Compare commits
1315 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 | ||
|
020afb8722 | ||
|
6a30a38415 | ||
|
312914d78c | ||
|
d4f979b1bc | ||
|
33d692194a | ||
|
e084035a71 | ||
|
313b6dcf93 | ||
|
4e6769d81c | ||
|
c53a288d0b | ||
|
235437be56 | ||
|
078d14861c | ||
|
c98ff08f56 | ||
|
e6b865130a | ||
|
d93cffaa30 | ||
|
619c4f8962 | ||
|
da29a87477 | ||
|
bba8931860 | ||
|
cda66f3ec4 | ||
|
9d8c6991e8 | ||
|
c7f919e22e | ||
|
a0409002b6 | ||
|
e20c098ab1 | ||
|
f211eef837 | ||
|
38274fb4f7 | ||
|
c674fc9a8b | ||
|
06ebf85d9d | ||
|
935a38607b | ||
|
d9106be820 | ||
|
0e6cb5557a | ||
|
64b3bfa30f | ||
|
532bf51718 | ||
|
eccb2787dc | ||
|
d94d52b852 | ||
|
2b51f20b1c | ||
|
c926456560 | ||
|
ab49281b0d | ||
|
1b50baf852 | ||
|
c1ecf1c281 | ||
|
3374544ced | ||
|
bd37877c8c | ||
|
4dd3cd967a | ||
|
ab273181f5 | ||
|
cb352fcc7c | ||
|
e9afd5e284 | ||
|
da9b8f2a42 | ||
|
fa19e466de | ||
|
7bf5ce7581 | ||
|
5b4e5b545d | ||
|
54296bdd71 | ||
|
4732f76bd5 | ||
|
07dc6dc4db | ||
|
6ff2409596 | ||
|
04b10bb04d | ||
|
bd3c7571c5 | ||
|
8dc37e9ab2 | ||
|
3a9cd85072 | ||
|
0440f0ef19 | ||
|
b7daafcac8 | ||
|
82dff88ba8 | ||
|
952d087a2b | ||
|
69b46c4b7b | ||
|
50cc2afb52 | ||
|
ae2fbb6256 | ||
|
80426d974c | ||
|
61f8b68c2f | ||
|
9d6691cf91 | ||
|
cb5451b9b9 | ||
|
5b7334bb17 | ||
|
fef6bc29bc | ||
|
07969d1fa6 | ||
|
b7630450f1 | ||
|
c46870ec10 | ||
|
0f31a4e8c6 | ||
|
0d95a74813 | ||
|
1407d9d948 | ||
|
8161ff88a8 | ||
|
1931f25475 | ||
|
58ab6818ed | ||
|
eac12e4559 | ||
|
f3eb6e19cf | ||
|
ec15336174 | ||
|
b1a42e5ecf | ||
|
19ab2b8d38 | ||
|
fa218d8dd7 | ||
|
34c0df228b | ||
|
8a283cc43b | ||
|
e013142cb1 | ||
|
0b1d42b7d5 | ||
|
ae21bbac09 | ||
|
3664645393 | ||
|
02e7f15810 | ||
|
f6f2b4c37e | ||
|
312265c395 | ||
|
4c5a9c3b70 | ||
|
2b9ae73795 | ||
|
551316fe59 | ||
|
d8f31b170d | ||
|
07323b12f9 | ||
|
adda4044ca | ||
|
df28d2f83f | ||
|
6cfa24b8ad | ||
|
b8a993aa34 | ||
|
893aa7effa | ||
|
33b7bee047 | ||
|
9b2d90ec58 | ||
|
fbde581475 | ||
|
bd6db60802 | ||
|
bbf2bd5b6a | ||
|
7b1b81aeb7 | ||
|
9cdfad7d34 | ||
|
18c21b3fda | ||
|
4115bdcb4f | ||
|
76b6039256 | ||
|
fa60c2e658 | ||
|
6178bb1f9d | ||
|
00ded29b35 | ||
|
66631c915b | ||
|
0bab98ccc6 | ||
|
a46cf3a0d3 | ||
|
ed9aa3503b | ||
|
0b6a9c3584 | ||
|
0b79d44345 | ||
|
e8587105c4 | ||
|
184f306eb2 | ||
|
da88dea271 | ||
|
1e9e426758 | ||
|
69480c8742 | ||
|
b91e76f216 | ||
|
6c7347310b | ||
|
ef0a79b8f0 | ||
|
7f6cf654f6 | ||
|
291ff890e6 | ||
|
7858c2135b | ||
|
08adc7f1bd | ||
|
c8fbc15c37 | ||
|
1b73df7e25 | ||
|
fa9aa9c2bb | ||
|
3d6b60c9f4 | ||
|
478f93922d | ||
|
a41c3d445b | ||
|
f99185e56d | ||
|
63ebf6aa7c | ||
|
228bf95329 | ||
|
8f39d736d5 | ||
|
6de38be207 | ||
|
0b1b4a7d9b | ||
|
0f67f7150f | ||
|
6b753c1418 | ||
|
56740b630d | ||
|
a854133f8e | ||
|
04eeedb0b9 | ||
|
9bcec5bf17 | ||
|
576d2a96cd | ||
|
daf412a47b | ||
|
e577791252 | ||
|
b008d39eae | ||
|
f72048383a | ||
|
9e92c2863a | ||
|
37416a61cb | ||
|
b8478348ed | ||
|
95afe011c8 | ||
|
c93cc8b680 | ||
|
7b40aa59a1 | ||
|
fd391690b9 | ||
|
433270f90f | ||
|
0f182d2d6d | ||
|
c300f6c364 | ||
|
8a886f0a60 | ||
|
c83804a76c | ||
|
72687b7581 | ||
|
ab9ae6bf0e | ||
|
404e9ad998 | ||
|
e593e2affb | ||
|
d054818aa3 | ||
|
373811f2bb | ||
|
962240f09d | ||
|
7c0db6161d | ||
|
5e699a8dc0 | ||
|
d80518871a | ||
|
9e985f7f3d | ||
|
9175257bbc | ||
|
d6faefb5fc | ||
|
a4faf204cb | ||
|
7d3dc493c0 | ||
|
5564b01d11 | ||
|
400017bc54 | ||
|
cdbb24b6b2 | ||
|
e6b46a3acf | ||
|
d58e74e19a | ||
|
2ac276458a | ||
|
f8d69f7945 | ||
|
d4caa6bb71 | ||
|
5b9f865a9d | ||
|
5b0fe1e050 | ||
|
8142ed3e72 | ||
|
28bdb2e395 | ||
|
0ca23344af | ||
|
1616b9335f | ||
|
45963102b8 | ||
|
30c602d468 | ||
|
556301366f | ||
|
1b931c4abd | ||
|
a9651a4f2e | ||
|
7b16d2c795 | ||
|
4aa6b1c47d | ||
|
0639fdc008 | ||
|
7d12fd4c02 | ||
|
df733d09a8 | ||
|
30b3ed610e | ||
|
d047152646 | ||
|
b1fc2e3736 | ||
|
ac7e1d5867 | ||
|
2d2d030145 | ||
|
8ede3abcab | ||
|
e5805716e2 | ||
|
bb00b5af12 | ||
|
6308f22f25 | ||
|
4c8d7a08d0 | ||
|
78e48c75fd | ||
|
e23ab50512 | ||
|
373ef6ca85 | ||
|
85df217c50 | ||
|
d5c347da9b | ||
|
6ff2038b0e | ||
|
97bb7981a3 | ||
|
7803e2ecc4 | ||
|
62c3c4ab90 | ||
|
32ea493c17 | ||
|
14ab294a47 | ||
|
4a2e417e31 | ||
|
0555f3d75d | ||
|
2f1172076a | ||
|
451eaca2b2 | ||
|
36a57c87d8 | ||
|
c2c0244990 | ||
|
55a2c25b44 | ||
|
3165f65377 | ||
|
6af03b34ad | ||
|
ba2a90030c | ||
|
f354e5bf88 | ||
|
a584f74788 | ||
|
9c5e018c5a | ||
|
9f28fdfcc0 | ||
|
2479ec5dd8 | ||
|
485282019b | ||
|
66d17d6df4 | ||
|
da29f1c0a5 | ||
|
7617029652 | ||
|
f590284ae2 | ||
|
11c624fb4a | ||
|
175520c885 | ||
|
83869ad3a0 | ||
|
718d3ad940 | ||
|
ecd0fbd364 | ||
|
7d6f637948 | ||
|
aed086bdb9 | ||
|
868564ff08 | ||
|
5bd4f4e9a5 | ||
|
efff725745 | ||
|
2959016496 | ||
|
30680777f3 | ||
|
dd6f1e0cb6 | ||
|
905afd6451 | ||
|
4f89ad7680 | ||
|
0f4f0ed297 | ||
|
be15913bd0 | ||
|
c3977627e9 | ||
|
9662f5e69f | ||
|
e1606ab6e7 | ||
|
9bd7b5cd48 | ||
|
6189e0cc49 | ||
|
f34aa2dcbe | ||
|
e09361295e | ||
|
df89082846 | ||
|
49bfd63033 | ||
|
096d9efcd9 | ||
|
1b31742d3b | ||
|
797e235056 | ||
|
4117c9a553 | ||
|
0bb470939f | ||
|
153c0ef4fa | ||
|
cddfa5c95f | ||
|
a91112c05c | ||
|
347c336b09 | ||
|
23091a0536 | ||
|
71a071fea4 | ||
|
acbd70a84f | ||
|
5852ca5aea | ||
|
115b34626e | ||
|
ff26dffada | ||
|
932a65be8c | ||
|
d15fd8a451 | ||
|
e624011415 | ||
|
dbd0fb6a56 | ||
|
946b1fe53d | ||
|
0fae7abd72 | ||
|
677de2508b | ||
|
16faec8627 | ||
|
862b8aaf06 | ||
|
29611ec3db | ||
|
0b30258f80 | ||
|
2f4b2790f6 | ||
|
02db5b5eb1 | ||
|
761206d009 | ||
|
fdb051bd2b | ||
|
7c11a5347c | ||
|
a9d3673f4e | ||
|
d6fcb5f9ca | ||
|
9a64bcc8b6 | ||
|
b04f05b575 | ||
|
50d3c843b4 | ||
|
10359224d4 | ||
|
ffe07a6a3c | ||
|
c105c3b778 | ||
|
59d77504c8 | ||
|
57449e3f4a | ||
|
425aae8f72 | ||
|
1a06102668 | ||
|
5696691a19 | ||
|
9daf4fa621 | ||
|
cdd7a15a42 | ||
|
e202f8e5b5 | ||
|
ac0f4d232e | ||
|
de3c7415b3 | ||
|
0055911491 | ||
|
0aa9ca0c70 | ||
|
5bb21b3b0a | ||
|
50ae45a533 | ||
|
3edd541750 | ||
|
f56fb9e505 | ||
|
8b631d564e | ||
|
9c6b745993 | ||
|
ec31b845b8 | ||
|
bfe6311ca4 | ||
|
02e4d4bd1b | ||
|
bc058a1c80 | ||
|
ebe9476bcc | ||
|
688fd92a6b | ||
|
a5a27c039e | ||
|
c6d0f44364 | ||
|
74f93ca4fb | ||
|
42b4f46356 | ||
|
6283f5f9e6 | ||
|
54955b6b5f | ||
|
93943f8f87 | ||
|
44bd9cf595 | ||
|
04624f208c | ||
|
0aee1ad452 | ||
|
7271106397 | ||
|
ef7b391da0 | ||
|
e52e554fec | ||
|
4ff762b711 | ||
|
8ee390a532 | ||
|
77010a0ab2 | ||
|
53e4019ecd | ||
|
634b7914ea | ||
|
4a49456a57 | ||
|
bd32b38027 | ||
|
571d60cbb7 | ||
|
4daecdc51a | ||
|
3e59f47748 | ||
|
27a227501a | ||
|
0c633d114c | ||
|
3907068014 | ||
|
121f0476e1 | ||
|
03be76f7f5 | ||
|
259abf4c4b | ||
|
c3e89d5d32 | ||
|
01365c38b7 | ||
|
d1c22573da | ||
|
5156055e53 | ||
|
0835b90219 | ||
|
bd2e198339 | ||
|
49a822afbf | ||
|
31dfc702ab | ||
|
03b5a0655a | ||
|
840175d218 | ||
|
38fab44cca | ||
|
76f463daff | ||
|
8c19b1f148 | ||
|
f0c36c6400 | ||
|
612e88456c | ||
|
e50f3f9814 | ||
|
8287f03f49 | ||
|
b6a02550f9 | ||
|
9f1205a6cd | ||
|
6014018f4e | ||
|
5435e1c930 | ||
|
da2c0b44ad | ||
|
7dd8f4dae3 | ||
|
4b4c8866dd | ||
|
49330ce101 | ||
|
eafe13e557 | ||
|
1805e311b8 | ||
|
65fc43c123 | ||
|
3d23e7f0b1 | ||
|
b9396542f0 | ||
|
4d274f46d7 | ||
|
f0deaab394 | ||
|
ff1377f7bb | ||
|
e1a30a25c7 | ||
|
ca37ebff0b | ||
|
f9f2516a65 | ||
|
67142bdb01 | ||
|
864c8ec9a5 | ||
|
0742be3204 | ||
|
460a1b9d84 | ||
|
67e3071920 | ||
|
4666e7a176 | ||
|
0bd2ab9e3c | ||
|
ae07b2cee6 | ||
|
9df036f4d4 | ||
|
f3197d641c | ||
|
5f8797b4be | ||
|
9424723536 | ||
|
5d51ea13c5 | ||
|
931f9e71b9 | ||
|
eb55b2f55d | ||
|
bcc59a9afb | ||
|
ba661759fb | ||
|
fdcaf54666 | ||
|
350403121d | ||
|
5dc63248d8 | ||
|
2eeef2d71c | ||
|
002c10ad13 | ||
|
3cdc9032b4 | ||
|
657b79cd3f | ||
|
ecfb206d1c | ||
|
5000d521a1 | ||
|
fc7bb2c377 | ||
|
e7332192c0 | ||
|
d37980e73c | ||
|
6e37060c24 | ||
|
078007c9fe | ||
|
a81f810a63 | ||
|
bf6fc7fd0b | ||
|
a480e5e922 | ||
|
beb8d8e6d7 | ||
|
05ecc267ef | ||
|
e73c40ba55 | ||
|
36a5eaae00 | ||
|
f9eb91e980 | ||
|
0ba2ddf195 | ||
|
1b8e1f4048 | ||
|
a86f5b877a | ||
|
d833ca6834 | ||
|
3dc35c5fff | ||
|
3351ee81cc | ||
|
b356f726a4 | ||
|
e0f87c676c | ||
|
b42c992a58 | ||
|
9d18aef634 | ||
|
46fe117f1f | ||
|
728e707024 | ||
|
3dd61dac4a | ||
|
e70162b2cc | ||
|
2feb8b9e6d | ||
|
b85b222fc0 | ||
|
d7b0e54494 | ||
|
75e5471dd1 | ||
|
c7de44b015 | ||
|
29bd0c8d2d | ||
|
fa223b90ad | ||
|
0cf2520df7 | ||
|
ea1fa189b2 | ||
|
62d08e139b | ||
|
7aec7f5c50 | ||
|
f619c5e0ab | ||
|
3a689cc7a1 | ||
|
4cdc501a34 | ||
|
253be26335 | ||
|
ecb9bbee8a | ||
|
41a4db4402 | ||
|
72d2fc1fac | ||
|
8f32b87b18 | ||
|
417574b4bb | ||
|
07afbc4714 | ||
|
1ee7845bb4 | ||
|
6331ec5707 | ||
|
e312dddb12 | ||
|
7ed7134b53 | ||
|
6a40fdc75d | ||
|
c635ae8136 | ||
|
546dbfc45a | ||
|
0be3114e7d | ||
|
72264109e9 | ||
|
27dee0223c | ||
|
c9e1775469 | ||
|
6b3c5249cf | ||
|
2435797bd1 | ||
|
8bdf48faba | ||
|
9e7139f344 | ||
|
aafb4adfa2 | ||
|
58c99a5dca | ||
|
358def836d | ||
|
48f97b6e60 | ||
|
cb4f60b2ff | ||
|
5a1ff68926 | ||
|
a60f5a783f | ||
|
7bd3622bbd | ||
|
c24cf916db | ||
|
d2503aaf1f | ||
|
0aacc14287 | ||
|
f50613704c | ||
|
68e048b945 | ||
|
fc5c9f137a | ||
|
5f0e0225e1 | ||
|
8c77a5d256 | ||
|
4538f0295d | ||
|
4dd31f6c69 | ||
|
13f3ea57a3 | ||
|
91cb2fda15 | ||
|
65f1349ce2 | ||
|
d37ecc44da | ||
|
b456086ee4 | ||
|
3d3618876f | ||
|
dc0951ee9f | ||
|
a4fa4cd482 | ||
|
a65c802485 | ||
|
ea09c2aa7b | ||
|
24a17c937b | ||
|
736298238e | ||
|
3cb4bd0fba | ||
|
6f52a7beed | ||
|
6fe9a4f167 | ||
|
b43edb2b4c | ||
|
c5fc186336 | ||
|
d1104e1eb3 | ||
|
7e458d1eda | ||
|
51d447618b | ||
|
9ec2b4fdef | ||
|
2a815a9709 | ||
|
fbdb513697 | ||
|
756245694f | ||
|
2719b1156b | ||
|
f4f9ae1a6a | ||
|
a2293a0ed1 | ||
|
2fd8d8673a | ||
|
ed609f124b | ||
|
8b63d5bb34 | ||
|
46e1caaa4a | ||
|
6ac606c91b | ||
|
6bd3ecb689 | ||
|
3aa142957c | ||
|
1221649a3d | ||
|
fdb112a037 | ||
|
a52fb469b6 | ||
|
de9e8cfe64 | ||
|
42f71e264e | ||
|
2f009f129e | ||
|
a5d5060048 | ||
|
3a7ea0837b | ||
|
d4352ef043 | ||
|
5147ec6bc9 | ||
|
4831950e61 | ||
|
49b5067619 | ||
|
05d6b3d223 | ||
|
34220b96e3 | ||
|
c6133ce7c0 | ||
|
ce6714006c | ||
|
90a1462ece | ||
|
3507b09207 | ||
|
25ba5ca789 | ||
|
5a9f82b147 | ||
|
995e39a57d | ||
|
e1f605b28c | ||
|
94efcaeca6 | ||
|
18be0dfc0b | ||
|
08d6358932 |
|
@ -343,4 +343,14 @@ make/oscar64
|
|||
*.int
|
||||
*.bcs
|
||||
*.crt
|
||||
*.crt
|
||||
**/*.d64
|
||||
*.tlog
|
||||
*.res
|
||||
*.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
|
||||
)
|
||||
|
291
README.md
291
README.md
|
@ -1,291 +1,40 @@
|
|||
# oscar64
|
||||
Optimizing small space C Compiler Assembler and Runtime for C64
|
||||
|
||||
## History and motivation
|
||||
Oscar64 is a C/C++ cross compiler running on a modern system (such as a Windows PC, Mac or Linux machine) and targets the classic 6502 family of processors. It is mainly focused on Commodore systems such as the C64, PET or VIC20. The compiler supports C99 and many C++ features up to variadic templates and lambda functions.
|
||||
|
||||
It is a sad fact that the 6502 used in the Commodore64 and other home computers of the 80s has a poor code density when it comes to 16 bit code. The C standard requires computations to be made with ints which work best if they have the same size as a pointer.
|
||||
The purpose of this compiler is to eliminate the need to write 6502 assembler code to achieve high code density and fast execution speed. It continues to improve with all the games, demos and tools written by it. It supports disk overlays and banked cartridges for larger projects.
|
||||
|
||||
The 6502 also has a very small stack of 256 bytes which cannot be easily addressed and thus cannot be used for local variables. Therefore a second stack for variables has to be maintained, resulting in costly indexing operations.
|
||||
The C64 executes 442 dhrystone V2.2 iteration per second, when compiled with Oscar64 and -O3 (which shows that the ancient dhrystone benchmark is no match to an optimizing compiler).
|
||||
|
||||
A C compiler for the 6502 thus generates large binaries if it translates to native machine code. The idea for the **oscar64** compiler is to translate the C source to an intermediate 16 bit byte code with the option to use native machine code for crucial functions. Using embedded assembly for runtime libraries or critical code should also be possible.
|
||||
[Full reference manual](oscar64.md)
|
||||
[Additional samples and tutorials](https://github.com/drmortalwombat/OscarTutorials)
|
||||
|
||||
The resulting compiler is a frankenstein constructed from a converted javascript parser a intermediate code optimizer based on a 15 year old compiler for 64bit x86 code and some new components for the backend.
|
||||
# References
|
||||
|
||||
The performance of interpreted code is clearly not as good as native machine code but the penalty for 16bit code is around 40-50% and less than 10% for floating point. Code that can use 8bit may suffer up to a factor of 10 to 20.
|
||||
This is a list of the games written with Oscar64, have a look if you are not convinced that fast paced action games can be written in C/C++ on a C64 (they are all free).
|
||||
|
||||
The goal is to implement the actual C standard and not some subset for performance reasons. So the compiler must support:
|
||||
[Ball and Chain](https://drmortalwombat.itch.io/ball-and-chain)
|
||||
|
||||
* Floating point
|
||||
* Recursion
|
||||
* Multi dimensional arrays
|
||||
* Pointer to structs
|
||||
[Balls like a Frog](https://drmortalwombat.itch.io/balls-like-a-frog)
|
||||
|
||||

|
||||
[Corescape](https://drmortalwombat.itch.io/corescape)
|
||||
|
||||
## Limits and Errors
|
||||
[MetalMayhem](https://drmortalwombat.itch.io/metal-mayhem)
|
||||
|
||||
There are still several open areas, but most targets have been reached. The current Dhrystone performance is 68 iterations per second with byte code (11266) and 295 iterations with native code (11784 Bytes).
|
||||
[Mineshaft Gap](https://drmortalwombat.itch.io/mineshaft-gap)
|
||||
|
||||
### Language
|
||||
[Minotrace](https://drmortalwombat.itch.io/minotrace)
|
||||
|
||||
* Missing const checks for structs and enums
|
||||
* Missing warnings for all kind of abuses
|
||||
[Missile Defence](https://drmortalwombat.itch.io/missile-defence)
|
||||
|
||||
### Linker
|
||||

|
||||
[Portal Buster](https://drmortalwombat.itch.io/portal-buster)
|
||||
|
||||
### Standard Libraries
|
||||
|
||||
* No standard file functions, but CBM based file ops
|
||||
|
||||
### Runtime
|
||||
|
||||
* No NaN support for floats
|
||||
* Basic zero page variables not restored on stop/restore
|
||||
|
||||
### Optimizing
|
||||
|
||||
* Auto variables placed on fixed stack for known call sequence
|
||||
|
||||
### Intermediate code generation
|
||||
|
||||
* No check for running out of temporary registers
|
||||
* Wasted 7 codes for far jumps
|
||||
|
||||
### Native code generation
|
||||
|
||||
## Compiler arguments
|
||||
|
||||
The compiler is command line driven, and creates an executable .prg file.
|
||||
|
||||
oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-e] [-n] [-dSYMBOL[=value]] {source.c}
|
||||
|
||||
* -v : verbose output for diagnostics
|
||||
* -i : additional include paths
|
||||
* -o : optional output file name
|
||||
* -rt : alternative runtime library, replaces the crt.c
|
||||
* -e : execute the result in the integrated emulator
|
||||
* -n : create pure native code for all functions
|
||||
* -d : define a symbol (e.g. NOFLOAT or NOLONG to avoid float/long code in printf)
|
||||
* -O1 or -O : default optimizations
|
||||
* -O0: disable optimizations
|
||||
* -O2: more aggressive speed optimizations including auto inline of small functions
|
||||
* -O3: aggressive optimization for speed
|
||||
* -Os: optimize for size
|
||||
|
||||
A list of source files can be provided.
|
||||
|
||||
## Console input and output
|
||||
|
||||
The C64 does not use ASCII it uses a derivative called PETSCII. There are two fonts, one with uppercase and one with uppercase and lowercase characters. It also used CR (13) as line terminator instead of LF (10). The stdio and conio libaries can perform translations.
|
||||
|
||||
The translation mode is selected in conio with the variable "giocharmap" and the function "iocharmap" which will also switch the font.
|
||||
|
||||
iocharmap(IOCHM_PETSCII_2);
|
||||
printf("Hello World\n");
|
||||
|
||||
Will switch to the lowercase PETSCII font and translate the strings while printing.
|
||||
|
||||
PETSCII string literals can also be generated using a "p" or "P" prefix such as:
|
||||
|
||||
printf(p"Hello World\n");
|
||||
|
||||
Screen codes can be generated similar using "s" or "S" prefix.
|
||||
|
||||
Input from the console will also be translated accordingly.
|
||||
|
||||
## Embedding binary data
|
||||
|
||||
The compiler supports the #embed preprocessor directive to import binary data. It converts a section of an external binary file into a sequence of numbers that can be placed into an initializer of an array.
|
||||
|
||||
byte data[] = {
|
||||
|
||||
#embed "data.bin"
|
||||
|
||||
};
|
||||
|
||||
A section of the file can be selected by providing a limit and or an offset into the file before the file name.
|
||||
|
||||
byte data[] = {
|
||||
|
||||
#embed 4096 126 "data.bin"
|
||||
|
||||
};
|
||||
|
||||
|
||||
## Language extensions for optimization
|
||||
|
||||
### Additional Optimizer information using __assume()
|
||||
|
||||
The compiler can be provided with additional information using the built in function __assume(cond). This can be useful to mark unreachable code using __assume(false) for e.g. the default of a switch statement. Another good option is to limit the value range of arguments to allow the compiler using byte operations without the need for integer promotion.
|
||||
|
||||
### Marking functions as native
|
||||
|
||||
Routines can be marked to be compiled to 6502 machine code with the native pragma:
|
||||
|
||||
void Plot(int x, int y)
|
||||
{
|
||||
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
|
||||
}
|
||||
|
||||
#pragma native(Plot)
|
||||
|
||||
Or alternatively with a __native storage class specifier
|
||||
|
||||
__native void Plot(int x, int y)
|
||||
{
|
||||
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
|
||||
}
|
||||
|
||||
### Linker control
|
||||
|
||||
The linker includes only objects that are referenced, starting by the startup code into main() and so on.
|
||||
|
||||
If you need to have a function or variable present regardless, you can specify it with the __export storage class specifier or use the #pragma reference(name) pragma.
|
||||
|
||||
|
||||
## Inline Assembler
|
||||
|
||||
Inline assembler can be embedded inside of any functions, regardles of their compilation target of byte code or native.
|
||||
|
||||
### Accessing variables in assembler
|
||||
|
||||
Access to local variables and parameters is done with zero page registers, global variables are accessed using absolute addressing.
|
||||
|
||||
void putchar(char c)
|
||||
{
|
||||
__asm {
|
||||
lda c
|
||||
bne w1
|
||||
lda #13
|
||||
w1:
|
||||
jsr 0xffd2
|
||||
}
|
||||
}
|
||||
|
||||
A function return value can be provided in the zero page addresses ACCU (+0..+3).
|
||||
|
||||
char getchar(void)
|
||||
{
|
||||
__asm {
|
||||
jsr 0xffcf
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
}
|
||||
|
||||
Labels are defined with a colon after the name. Pure assembler functions can be defined outside of the scope of a function and accessed using their name inside of other assembler function. One can e.g. set up an interrupt
|
||||
|
||||
### Interrupt routines
|
||||
|
||||
The C compiler will not generate good interrupt code, it is simply too greedy with the zero page registers. Interrupt code should therefore be written in assembler.
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// Next line for interrupt
|
||||
volatile char npos;
|
||||
|
||||
// Interrupt routine
|
||||
__asm irq
|
||||
{
|
||||
lda $d019 // Check if it is raster IRQ
|
||||
and #$01
|
||||
beq w1
|
||||
|
||||
inc $d020 // Start colored section
|
||||
inc $d021
|
||||
|
||||
ldx #20 // Wait for 2/3 lines
|
||||
l1: dex
|
||||
bne l1
|
||||
|
||||
dec $d020 // End colored section
|
||||
dec $d021
|
||||
|
||||
lda npos // Setup next interrupt
|
||||
sta $d012
|
||||
w1:
|
||||
asl $d019 // Ack interrupt
|
||||
|
||||
jmp $ea31 // System IRQ routine
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
__asm { sei } // Disable interrupt
|
||||
|
||||
|
||||
*(void **)0x0314 = irq; // Install interrupt routine
|
||||
*(char *)0xd01a = 1; // Enable raster interrupt
|
||||
*(char *)0xd011 &= 0x7f; // Set raster line for IRQ
|
||||
*(char *)0xd012 = 100;
|
||||
|
||||
npos = 100;
|
||||
|
||||
__asm { cli } // Re-enable interrupt
|
||||
|
||||
// Move the interrupt raster line up/down
|
||||
float f = 0;
|
||||
while (true)
|
||||
{
|
||||
npos = 130 + (int)(100 * sin(f));
|
||||
f += 0.1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
## Implementation Details
|
||||
|
||||
The compiler does a full program compile, the linker step is part of the compilation. It knows all functions during the compilation run and includes only reachable code in the output. Source files are added to the build with the help of a pragma:
|
||||
|
||||
#pragma compile("stdio.c")
|
||||
|
||||
The character map for string and char constants can be changed with a pragma to match a custon character set or PETSCII.
|
||||
|
||||
#pragma charmap(char, code [,count])
|
||||
|
||||
The byte code interpreter is compiled by the compiler itself and placed in the source file "crt.c". Functions implementing byte codes are marked with a pragma:
|
||||
|
||||
#pragma bytecode(BC_CONST_P8, inp_const_p8)
|
||||
|
||||
The functions are written in 6502 assembly with the __asm keyword
|
||||
|
||||
__asm inp_const_p8
|
||||
{
|
||||
lda (ip), y
|
||||
tax
|
||||
iny
|
||||
lda (ip), y
|
||||
sta $00, x
|
||||
lda #0
|
||||
sta $01, x
|
||||
iny
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
The current byte code program counter is (ip),y. The interpreter loop guarantees that y is always <= 128 and can thus be used to index the additional byte code arguments without the need to check the 16 bit pointer. The interpreter loop itself is quite compact and takes 21 cycles (including the final jump of the byte code function itself). Moving it to zero page would reduce this by another two cycles but is most likely not worth the waste of temporary space.
|
||||
|
||||
exec:
|
||||
lda (ip), y
|
||||
sta execjmp + 1
|
||||
iny
|
||||
bmi incip
|
||||
execjmp:
|
||||
jmp (0x0900)
|
||||
|
||||
The intermediate code generator assumes a large number of registers so the zero page is used for this purpose. The allocation is not yet final:
|
||||
|
||||
* **0x02-0x02** spilling of y register
|
||||
* **0x03-0x09** workspace for mul/div and floating point routines
|
||||
* **0x19-0x1a** instruction pointer
|
||||
* **0x1b-0x1e** integer and floating point accumulator
|
||||
* **0x1f-0x22** pointers for indirect addressing
|
||||
* **0x23-0x24** stack pointer
|
||||
* **0x25-0x26** frame pointer
|
||||
* **0x43-0x52** caller saved registers
|
||||
* **0x53-0x8f** callee saved registers
|
||||
[Roguebot](https://drmortalwombat.itch.io/roguebot)
|
||||
|
||||
[Shallow Domains](https://drmortalwombat.itch.io/shallow-domains)
|
||||
|
||||
[Veggies vs Undead](https://drmortalwombat.itch.io/veggies-vs-undead)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
#include <assert.h>
|
||||
|
||||
int t, n, m, k;
|
||||
|
||||
struct C1
|
||||
{
|
||||
int a;
|
||||
|
||||
C1(void);
|
||||
~C1(void);
|
||||
C1(const C1 & c);
|
||||
C1 & operator=(const C1 & c);
|
||||
};
|
||||
|
||||
struct C2
|
||||
{
|
||||
C1 nc[10], mc[20];
|
||||
};
|
||||
|
||||
C1::C1(void)
|
||||
{
|
||||
a = 1;
|
||||
n++;
|
||||
t++;
|
||||
}
|
||||
|
||||
C1::C1(const C1 & c)
|
||||
{
|
||||
a = c.a;
|
||||
k++;
|
||||
t++;
|
||||
}
|
||||
|
||||
C1 & C1::operator=(const C1 & c)
|
||||
{
|
||||
a = c.a;
|
||||
m++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
C1::~C1(void)
|
||||
{
|
||||
t--;
|
||||
}
|
||||
|
||||
void test_local_init(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C1 c[10];
|
||||
}
|
||||
|
||||
assert(n == 10 && t == 0);
|
||||
}
|
||||
|
||||
void test_member_init(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 d;
|
||||
}
|
||||
|
||||
assert(n == 30 && t == 0);
|
||||
}
|
||||
|
||||
void test_member_array_init(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 d[5];
|
||||
}
|
||||
|
||||
assert(n == 150 && t == 0);
|
||||
}
|
||||
|
||||
void test_local_copy(void)
|
||||
{
|
||||
n = 0;
|
||||
k = 0;
|
||||
|
||||
{
|
||||
C1 c[10];
|
||||
C1 d(c[4]);
|
||||
}
|
||||
|
||||
assert(n == 10 && k == 1 && t == 0);
|
||||
}
|
||||
|
||||
void test_member_copy(void)
|
||||
{
|
||||
n = 0;
|
||||
k = 0;
|
||||
|
||||
{
|
||||
C2 d;
|
||||
C2 e(d);
|
||||
}
|
||||
|
||||
assert(n == 30 && k == 30 && t == 0);
|
||||
}
|
||||
|
||||
void test_local_assign(void)
|
||||
{
|
||||
n = 0;
|
||||
k = 0;
|
||||
m = 0;
|
||||
|
||||
{
|
||||
C1 c[10];
|
||||
C1 d[5];
|
||||
|
||||
d[4] = c[2];
|
||||
}
|
||||
|
||||
assert(n == 15 && k == 0 && m == 1 && t == 0);
|
||||
}
|
||||
|
||||
void test_member_assign(void)
|
||||
{
|
||||
n = 0;
|
||||
k = 0;
|
||||
m = 0;
|
||||
|
||||
{
|
||||
C2 d;
|
||||
C2 e;
|
||||
e = d;
|
||||
}
|
||||
|
||||
assert(n == 60 && k == 0 && m == 30 && t == 0);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_local_init();
|
||||
test_member_init();
|
||||
|
||||
test_member_array_init();
|
||||
|
||||
test_local_copy();
|
||||
test_member_copy();
|
||||
|
||||
test_local_assign();
|
||||
test_member_assign();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
int a[10];
|
||||
|
||||
int get(int i)
|
||||
{
|
||||
return a[i];
|
||||
}
|
||||
|
||||
void put(int i, int x)
|
||||
{
|
||||
a[i] = x;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(int j=0; j<10; j++)
|
||||
put(j, j);
|
||||
int s = -45;
|
||||
for(int j=0; j<10; j++)
|
||||
s += get(j);
|
||||
return s;
|
||||
}
|
||||
|
|
@ -79,6 +79,7 @@ int main(void)
|
|||
}
|
||||
|
||||
assert(sum(a, 100) == 450);
|
||||
|
||||
copy(b, a, 100);
|
||||
assert(sum(b, 100) == 450);
|
||||
reverse(c, a, 100);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
int asum(int a, int b)
|
||||
{
|
||||
__asm
|
||||
return __asm
|
||||
{
|
||||
clc
|
||||
lda a
|
||||
|
@ -12,14 +12,14 @@ int asum(int a, int b)
|
|||
lda a + 1
|
||||
adc b + 1
|
||||
sta accu + 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int bsum(int a, int b)
|
||||
{
|
||||
puts("Hello\n");
|
||||
|
||||
__asm
|
||||
return __asm
|
||||
{
|
||||
clc
|
||||
lda a
|
||||
|
@ -28,7 +28,7 @@ int bsum(int a, int b)
|
|||
lda a + 1
|
||||
adc b + 1
|
||||
sta accu + 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int b, t[10];
|
||||
|
|
|
@ -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,6 +1,75 @@
|
|||
rem @echo off
|
||||
|
||||
@call :test stdlibtest.c
|
||||
@call :test rolrortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test bitfields.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testn autorefreturn.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_array.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_static_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_vector_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_string_init.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_streamtest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_pairtest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_parts.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_list.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testn opp_functional.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh operatoroverload.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh virtualdestruct.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh vcalltest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@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
|
||||
|
@ -12,18 +81,33 @@ rem @echo off
|
|||
@call :test testint16mul.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test testsigned16mul.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test testsigned16div.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test recursiontest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test copyinitmove.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@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
|
||||
|
||||
@call :test strcmptest2.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test memmovetest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test arraytest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -39,12 +123,18 @@ 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
|
||||
|
||||
@call :test arrayinittest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test arrayindexintrangecheck.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test array2stringinittest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -57,6 +147,9 @@ rem @echo off
|
|||
@call :test testint32cmp.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test mixsigncmptest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test testinterval.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -66,9 +159,15 @@ rem @echo off
|
|||
@call :test floatstringtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test sprintftest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@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
|
||||
|
||||
|
@ -96,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
|
||||
|
||||
|
@ -108,12 +213,18 @@ rem @echo off
|
|||
@call :test funcvartest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test funcarraycall.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test structassigntest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test structmembertest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test structarraycopy.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test randsumtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -126,50 +237,164 @@ rem @echo off
|
|||
@call :test charwintest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test linetest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test ptrinittest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test ptrarraycmptest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test cplxstructtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@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 %~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 %~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 %~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 -O3 %~1
|
||||
..\bin\oscar64 -e -Os -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O3 -n %~1
|
||||
..\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 -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 %~1
|
||||
..\bin\oscar64 -e -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O2 %~1
|
||||
..\bin\oscar64 -e -bc -O2 %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O0 %~1
|
||||
..\bin\oscar64 -e -bc -O0 %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O3 %~1
|
||||
..\bin\oscar64 -e -bc -Os %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -bc -O3 %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:testn
|
||||
..\bin\oscar64 -e -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O0 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -Os -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\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
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
#include <assert.h>
|
||||
|
||||
struct A
|
||||
{
|
||||
char x : 4;
|
||||
char y : 1;
|
||||
char z : 3;
|
||||
};
|
||||
|
||||
A a = {7, 1, 2};
|
||||
|
||||
void test_char_fit(void)
|
||||
{
|
||||
assert(a.x == 7);
|
||||
assert(a.y == 1);
|
||||
assert(a.z == 2);
|
||||
assert(sizeof(A) == 1);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
a.x = i;
|
||||
a.y = 0;
|
||||
a.z = 3;
|
||||
assert(a.x == i);
|
||||
assert(a.y == 0);
|
||||
assert(a.z == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct B
|
||||
{
|
||||
char x : 6;
|
||||
char y : 6;
|
||||
char z : 6;
|
||||
char w : 6;
|
||||
};
|
||||
|
||||
B b = {11, 22, 33, 44};
|
||||
|
||||
void test_char_cross(void)
|
||||
{
|
||||
assert(b.x == 11);
|
||||
assert(b.y == 22);
|
||||
assert(b.z == 33);
|
||||
assert(b.w == 44);
|
||||
assert(sizeof(B) == 3);
|
||||
|
||||
for(int i=0; i<64; i++)
|
||||
{
|
||||
b.x = i * 1;
|
||||
b.y = i * 3;
|
||||
b.z = i * 5;
|
||||
b.w = i * 7;
|
||||
assert(b.x == ((i * 1) & 0x3f));
|
||||
assert(b.y == ((i * 3) & 0x3f));
|
||||
assert(b.z == ((i * 5) & 0x3f));
|
||||
assert(b.w == ((i * 7) & 0x3f));
|
||||
}
|
||||
}
|
||||
|
||||
struct C
|
||||
{
|
||||
unsigned x : 4;
|
||||
unsigned y : 1;
|
||||
unsigned z : 3;
|
||||
};
|
||||
|
||||
C c = {7, 1, 2};
|
||||
|
||||
void test_word_fit(void)
|
||||
{
|
||||
assert(c.x == 7);
|
||||
assert(c.y == 1);
|
||||
assert(c.z == 2);
|
||||
assert(sizeof(C) == 1);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
c.x = i;
|
||||
c.y = 0;
|
||||
c.z = 3;
|
||||
assert(c.x == i);
|
||||
assert(c.y == 0);
|
||||
assert(c.z == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct D
|
||||
{
|
||||
unsigned x : 10;
|
||||
unsigned y : 10;
|
||||
unsigned z : 10;
|
||||
unsigned w : 10;
|
||||
};
|
||||
|
||||
D d = {111, 222, 333, 444};
|
||||
|
||||
void test_word_cross(void)
|
||||
{
|
||||
assert(d.x == 111);
|
||||
assert(d.y == 222);
|
||||
assert(d.z == 333);
|
||||
assert(d.w == 444);
|
||||
assert(sizeof(D) == 5);
|
||||
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
d.x = i * 1;
|
||||
d.y = i * 3;
|
||||
d.z = i * 5;
|
||||
d.w = i * 7;
|
||||
assert(d.x == ((i * 1) & 0x3ff));
|
||||
assert(d.y == ((i * 3) & 0x3ff));
|
||||
assert(d.z == ((i * 5) & 0x3ff));
|
||||
assert(d.w == ((i * 7) & 0x3ff));
|
||||
}
|
||||
}
|
||||
|
||||
struct E
|
||||
{
|
||||
unsigned long x : 4;
|
||||
unsigned long y : 1;
|
||||
unsigned long z : 3;
|
||||
};
|
||||
|
||||
E e = {7, 1, 2};
|
||||
|
||||
void test_dword_fit(void)
|
||||
{
|
||||
assert(e.x == 7);
|
||||
assert(e.y == 1);
|
||||
assert(e.z == 2);
|
||||
assert(sizeof(E) == 1);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
e.x = i;
|
||||
e.y = 0;
|
||||
e.z = 3;
|
||||
assert(e.x == i);
|
||||
assert(e.y == 0);
|
||||
assert(e.z == 3);
|
||||
}
|
||||
}
|
||||
|
||||
struct F
|
||||
{
|
||||
unsigned long x : 20;
|
||||
unsigned long y : 20;
|
||||
unsigned long z : 20;
|
||||
unsigned long w : 20;
|
||||
};
|
||||
|
||||
F f = {111111UL, 222222UL, 333333UL, 444444UL};
|
||||
|
||||
void test_dword_cross(void)
|
||||
{
|
||||
assert(f.x == 111111UL);
|
||||
assert(f.y == 222222UL);
|
||||
assert(f.z == 333333UL);
|
||||
assert(f.w == 444444UL);
|
||||
assert(sizeof(F) == 10);
|
||||
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
f.x = i * 11UL;
|
||||
f.y = i * 33UL;
|
||||
f.z = i * 55UL;
|
||||
f.w = i * 77UL;
|
||||
assert(f.x == ((i * 11UL) & 0xfffffUL));
|
||||
assert(f.y == ((i * 33UL) & 0xfffffUL));
|
||||
assert(f.z == ((i * 55UL) & 0xfffffUL));
|
||||
assert(f.w == ((i * 77UL) & 0xfffffUL));
|
||||
}
|
||||
}
|
||||
|
||||
struct G
|
||||
{
|
||||
signed char x : 1;
|
||||
signed char y : 5;
|
||||
signed char z : 2;
|
||||
};
|
||||
|
||||
G g = {0, -1, -2};
|
||||
|
||||
void test_char_signed(void)
|
||||
{
|
||||
assert(g.x == 0);
|
||||
assert(g.y == -1);
|
||||
assert(g.z == -2);
|
||||
assert(sizeof(G) == 1);
|
||||
|
||||
for(int i=-16; i<16; i++)
|
||||
{
|
||||
g.x = -1;
|
||||
g.y = i;
|
||||
g.z = 1;
|
||||
assert(g.x == -1);
|
||||
assert(g.y == i);
|
||||
assert(g.z == 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct H
|
||||
{
|
||||
int x : 10;
|
||||
int y : 10;
|
||||
int z : 10;
|
||||
int w : 10;
|
||||
};
|
||||
|
||||
H h = {111, -222, -333, 444};
|
||||
|
||||
void test_word_signed(void)
|
||||
{
|
||||
assert(h.x == 111);
|
||||
assert(h.y == -222);
|
||||
assert(h.z == -333);
|
||||
assert(h.w == 444);
|
||||
assert(sizeof(H) == 5);
|
||||
|
||||
for(int i=-32; i<32; i++)
|
||||
{
|
||||
h.x = i * 1;
|
||||
h.y = i * 3;
|
||||
h.z = i * 5;
|
||||
h.w = i * 7;
|
||||
assert(h.x == i * 1);
|
||||
assert(h.y == i * 3);
|
||||
assert(h.z == i * 5);
|
||||
assert(h.w == i * 7);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
test_char_cross();
|
||||
test_word_fit();
|
||||
test_word_cross();
|
||||
test_dword_fit();
|
||||
test_dword_cross();
|
||||
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)
|
||||
|
||||
|
@ -362,6 +374,7 @@ int main(void)
|
|||
shr16b(0xfedc, 0xfedc);
|
||||
|
||||
shl16n(0x0000, 0x0000);
|
||||
|
||||
shl16n(0xffff, 0xffff);
|
||||
shl16n(0x1234, 0x1234);
|
||||
shl16n(0xfedc, 0xfedc);
|
||||
|
@ -372,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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
#include <assert.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
struct C1
|
||||
{
|
||||
int a;
|
||||
|
||||
C1(int x);
|
||||
~C1(void);
|
||||
};
|
||||
|
||||
C1::C1(int x) : a(x)
|
||||
{
|
||||
t += a;
|
||||
n++;
|
||||
}
|
||||
|
||||
C1::~C1(void)
|
||||
{
|
||||
t -= a;
|
||||
}
|
||||
|
||||
void test_base(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C1 x(2);
|
||||
C1 y(1);
|
||||
}
|
||||
|
||||
assert(t == 0 && n == 2);
|
||||
}
|
||||
|
||||
void test_base_loop(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
C1 x(2);
|
||||
C1 y(1);
|
||||
}
|
||||
|
||||
assert(t == 0 && n == 20);
|
||||
}
|
||||
|
||||
struct C2
|
||||
{
|
||||
C1 c, d;
|
||||
|
||||
C2(void);
|
||||
};
|
||||
|
||||
C2::C2(void)
|
||||
: c(7), d(11)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void test_member(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 x();
|
||||
C2 y();
|
||||
}
|
||||
|
||||
assert(t == 0 && n == 4);
|
||||
}
|
||||
|
||||
void test_member_loop(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
C2 x();
|
||||
C2 y();
|
||||
}
|
||||
|
||||
assert(t == 0 && n == 40);
|
||||
}
|
||||
|
||||
struct C3
|
||||
{
|
||||
C2 x, y;
|
||||
};
|
||||
|
||||
void test_default(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C3 x();
|
||||
C3 y();
|
||||
}
|
||||
|
||||
assert(t == 0 && n == 8);
|
||||
}
|
||||
|
||||
void test_default_loop(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
C3 x();
|
||||
C3 y();
|
||||
}
|
||||
|
||||
assert(t == 0 && n == 80);
|
||||
}
|
||||
|
||||
inline void test_inline_x(void)
|
||||
{
|
||||
C1 x(1), y(2);
|
||||
}
|
||||
|
||||
void test_inline(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
test_inline_x();
|
||||
|
||||
assert(t == 0 && n == 2);
|
||||
}
|
||||
|
||||
inline void test_inline_xr(void)
|
||||
{
|
||||
C1 x(1), y(2);
|
||||
|
||||
{
|
||||
C1 x(3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void test_inline_return(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
test_inline_xr();
|
||||
|
||||
assert(t == 0 && n == 3);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_base();
|
||||
test_base_loop();
|
||||
|
||||
test_member();
|
||||
test_member_loop();
|
||||
|
||||
test_default();
|
||||
test_default_loop();
|
||||
|
||||
test_inline();
|
||||
test_inline_return();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
#include <assert.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
struct C0
|
||||
{
|
||||
int u;
|
||||
|
||||
C0(int a);
|
||||
~C0(void);
|
||||
};
|
||||
|
||||
C0::C0(int a) : u(a)
|
||||
{
|
||||
t += u;
|
||||
n++;
|
||||
}
|
||||
|
||||
C0::~C0(void)
|
||||
{
|
||||
t -= u;
|
||||
}
|
||||
|
||||
struct C1
|
||||
{
|
||||
int u;
|
||||
|
||||
C1(int a);
|
||||
~C1(void);
|
||||
C1(const C1 & c);
|
||||
C1 & operator=(const C1 & c);
|
||||
};
|
||||
|
||||
C1::C1(int a) : u(a)
|
||||
{
|
||||
t += u;
|
||||
n++;
|
||||
}
|
||||
|
||||
C1::~C1(void)
|
||||
{
|
||||
t -= u;
|
||||
}
|
||||
|
||||
C1::C1(const C1 & c) : u(c.u)
|
||||
{
|
||||
t += u;
|
||||
n++;
|
||||
}
|
||||
|
||||
C1 & C1::operator=(const C1 & c)
|
||||
{
|
||||
t -= u;
|
||||
u = c.u;
|
||||
t += u;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void test_assign(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C1 c(4);
|
||||
C1 d(5);
|
||||
c = d;
|
||||
}
|
||||
|
||||
assert(n == 2 && t == 0);
|
||||
}
|
||||
|
||||
struct C2
|
||||
{
|
||||
C1 a, b;
|
||||
|
||||
C2(int x, int y) : a(x), b(y)
|
||||
{}
|
||||
};
|
||||
|
||||
void test_assign_deflt(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 c(2, 3);
|
||||
C2 d(5, 10);
|
||||
c = d;
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
}
|
||||
|
||||
int k;
|
||||
|
||||
C2 test_ret_v(void)
|
||||
{
|
||||
C2 c(5, 10);
|
||||
return c;
|
||||
}
|
||||
|
||||
C2 & test_ret_r(C2 & r)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
void test_assign_return_value(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 c(2, 3);
|
||||
c = test_ret_v();
|
||||
}
|
||||
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_assign();
|
||||
test_assign_deflt();
|
||||
test_assign_return_value();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
struct C0
|
||||
{
|
||||
int u;
|
||||
|
||||
C0(int a);
|
||||
~C0(void);
|
||||
};
|
||||
|
||||
C0::C0(int a) : u(a)
|
||||
{
|
||||
t += u;
|
||||
n++;
|
||||
}
|
||||
|
||||
C0::~C0(void)
|
||||
{
|
||||
t -= u;
|
||||
}
|
||||
|
||||
struct C1
|
||||
{
|
||||
int u;
|
||||
|
||||
C1(int a);
|
||||
~C1(void);
|
||||
C1(const C1 & c);
|
||||
};
|
||||
|
||||
C1::C1(int a) : u(a)
|
||||
{
|
||||
t += u;
|
||||
n++;
|
||||
}
|
||||
|
||||
C1::~C1(void)
|
||||
{
|
||||
t -= u;
|
||||
}
|
||||
|
||||
C1::C1(const C1 & c) : u(c.u)
|
||||
{
|
||||
t += u;
|
||||
n++;
|
||||
}
|
||||
|
||||
void test_dcopy_init(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C0 x(4);
|
||||
C0 y(x);
|
||||
}
|
||||
|
||||
assert(n == 1 && t == -4);
|
||||
|
||||
t = 0;
|
||||
}
|
||||
|
||||
void test_copy_init(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C1 x(4);
|
||||
C1 y(x);
|
||||
}
|
||||
|
||||
assert(n == 2 && t == 0);
|
||||
}
|
||||
|
||||
struct C2
|
||||
{
|
||||
C1 a, b;
|
||||
|
||||
C2(void);
|
||||
};
|
||||
|
||||
C2::C2(void) : a(1), b(3)
|
||||
{}
|
||||
|
||||
void test_minit(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 x;
|
||||
}
|
||||
|
||||
assert(n == 2 && t == 0);
|
||||
}
|
||||
|
||||
void test_minit_copy(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 x;
|
||||
C2 y(x);
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
}
|
||||
|
||||
int k;
|
||||
|
||||
void test_param_fv(C2 c)
|
||||
{
|
||||
k += c.a.u;
|
||||
}
|
||||
|
||||
void test_param_fr(C2 & c)
|
||||
{
|
||||
k += c.a.u;
|
||||
}
|
||||
|
||||
void test_param_value(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 x;
|
||||
test_param_fv(x);
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
}
|
||||
|
||||
void test_param_ref(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 x;
|
||||
test_param_fr(x);
|
||||
}
|
||||
|
||||
assert(n == 2 && t == 0);
|
||||
}
|
||||
|
||||
C2 test_ret_v(void)
|
||||
{
|
||||
C2 c;
|
||||
return c;
|
||||
}
|
||||
|
||||
C2 & test_ret_r(C2 & r)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
void test_return_value(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 c(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_return_reference(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
C2 d;
|
||||
C2 c(test_ret_r(d));
|
||||
}
|
||||
|
||||
assert(n == 2 && t == 0);
|
||||
}
|
||||
|
||||
void test_retparam_value(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
test_param_fv(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_retparam_reference(void)
|
||||
{
|
||||
n = 0;
|
||||
|
||||
{
|
||||
test_param_fr(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_dcopy_init();
|
||||
test_copy_init();
|
||||
test_minit();
|
||||
test_minit_copy();
|
||||
test_param_value();
|
||||
test_param_ref();
|
||||
test_return_value();
|
||||
test_retparam_value();
|
||||
test_retparam_reference();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
int val(char * c)
|
||||
{
|
||||
return c[0];
|
||||
}
|
||||
|
||||
void set(char * c, int a)
|
||||
{
|
||||
c[0] = a;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
char t[10] = {1};
|
||||
sum0 += val(t);
|
||||
sum2 += t[0];
|
||||
set(t, i);
|
||||
sum1 += val(t);
|
||||
sum3 += t[0];
|
||||
}
|
||||
|
||||
return (sum1 - 45) | (sum0 - 10) | (sum3 - 45) | (sum2 - 10);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct cplx
|
||||
{
|
||||
float r, i;
|
||||
};
|
||||
|
||||
cplx cplx_add(cplx a, cplx b)
|
||||
{
|
||||
cplx c;
|
||||
c.r = a.r + b.r;
|
||||
c.i = a.i + b.i;
|
||||
return c;
|
||||
}
|
||||
|
||||
cplx cplx_sub(cplx a, cplx b)
|
||||
{
|
||||
cplx c;
|
||||
c.r = a.r - b.r;
|
||||
c.i = a.i - b.i;
|
||||
return c;
|
||||
}
|
||||
|
||||
cplx cplx_mul(cplx a, cplx b)
|
||||
{
|
||||
cplx c;
|
||||
c.r = a.r * b.r - a.i * b.i;
|
||||
c.i = a.i * b.r + a.r * b.i;
|
||||
return c;
|
||||
}
|
||||
|
||||
float cplx_abs(cplx a)
|
||||
{
|
||||
return sqrt(a.r * a.r + a.i * a.i);
|
||||
}
|
||||
|
||||
cplx cplx_sum(cplx p, const cplx * a, int n)
|
||||
{
|
||||
cplx s = {0.0, 0.0};
|
||||
cplx c = {1.0, 0.0};
|
||||
|
||||
for(int i=0; i<n; i++)
|
||||
{
|
||||
s = cplx_add(s, cplx_mul(a[i], c));
|
||||
c = cplx_mul(c, p);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cplx sig[100];
|
||||
|
||||
for(int i=0; i<100; i++)
|
||||
{
|
||||
sig[i].r = cos(i * 1.3);
|
||||
sig[i].i = sin(i * 1.3);
|
||||
}
|
||||
|
||||
cplx c = {1.0, 0.0};
|
||||
float phi = 0.1 * PI;
|
||||
cplx t;
|
||||
t.r = cos(phi); t.i = sin(phi);
|
||||
|
||||
float p[20], q[20];
|
||||
|
||||
for(int i=0; i<20; i++)
|
||||
{
|
||||
p[i] = cplx_abs(cplx_sum(c, sig, 100));
|
||||
c = cplx_mul(c, t);
|
||||
}
|
||||
|
||||
for(int i=0; i<20; i++)
|
||||
{
|
||||
float sumr = 0.0, sumi = 0.0;
|
||||
for(int j=0; j<100; j++)
|
||||
{
|
||||
float co = cos(i * j * 0.1 * PI), si = sin(i * j * 0.1 * PI);
|
||||
sumr += co * sig[j].r - si * sig[j].i;
|
||||
sumi += si * sig[j].r + co * sig[j].i;
|
||||
}
|
||||
q[i] = sqrt(sumr * sumr + sumi * sumi);
|
||||
}
|
||||
#if 1
|
||||
for(int i=0; i<20; i++)
|
||||
{
|
||||
printf("%d, %f - %f\n", i, p[i], q[i]);
|
||||
}
|
||||
#endif
|
||||
for(int i=0; i<20; i++)
|
||||
assert(fabs(p[i] - q[i]) < 1.0);
|
||||
|
||||
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;
|
||||
}
|
|
@ -12,16 +12,50 @@ bool flt(float a, float b)
|
|||
return a < b;
|
||||
}
|
||||
|
||||
bool fle(float a, float b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
bool fgt(float a, float b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
void cmpflt(float a, float b, bool eq, bool lt, bool gt)
|
||||
bool fge(float a, float b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
|
||||
volatile float f;
|
||||
|
||||
inline void cmpflt(float a, float b, bool eq, bool lt, bool gt)
|
||||
{
|
||||
bool le = eq || lt;
|
||||
bool ge = eq || gt;
|
||||
|
||||
assert(feq(a, b) == eq);
|
||||
assert(flt(a, b) == lt);
|
||||
assert(fgt(a, b) == gt);
|
||||
assert(fle(a, b) == le);
|
||||
assert(fge(a, b) == ge);
|
||||
|
||||
f = a;
|
||||
|
||||
assert(feq(f, b) == eq);
|
||||
assert(flt(f, b) == lt);
|
||||
assert(fgt(f, b) == gt);
|
||||
assert(fle(f, b) == le);
|
||||
assert(fge(f, b) == ge);
|
||||
|
||||
f = b;
|
||||
|
||||
assert(feq(a, f) == eq);
|
||||
assert(flt(a, f) == lt);
|
||||
assert(fgt(a, f) == gt);
|
||||
assert(fle(a, f) == le);
|
||||
assert(fge(a, f) == ge);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -15,7 +15,7 @@ int main(void)
|
|||
ftoa(x, xb); float xr = atof(xb);
|
||||
ftoa(y, yb); float yr = atof(yb);
|
||||
|
||||
printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y);
|
||||
printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, yr, fabs(x - xr) / x, fabs(y - yr) / y);
|
||||
|
||||
if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001)
|
||||
return -1;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
int (*funcs[10])(int);
|
||||
|
||||
#assign x 0
|
||||
#repeat
|
||||
int f##x(int i)
|
||||
{
|
||||
return i + x;
|
||||
}
|
||||
#assign x x + 1
|
||||
#until x == 10
|
||||
|
||||
int test(int k)
|
||||
{
|
||||
for(char i=0; i<10; i++)
|
||||
k = funcs[i](k);
|
||||
return k;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#assign x 0
|
||||
#repeat
|
||||
funcs[x] = f##x;
|
||||
#assign x x + 1
|
||||
#until x == 10
|
||||
|
||||
int k = test(-45);
|
||||
return k;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include <gfx/bitmap.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
char * const Hires = (char *)0x4000;
|
||||
Bitmap Screen;
|
||||
ClipRect cr = {0, 0, 320, 200};
|
||||
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bm_init(&Screen, Hires, 40, 25);
|
||||
|
||||
bmu_rect_clear(&Screen, 0, 0, 320, 200);
|
||||
|
||||
bm_line(&Screen, &cr, 0, 0, 199, 199, 0xff, LINOP_SET);
|
||||
|
||||
for(int i=0; i<200; i++)
|
||||
{
|
||||
assert(Hires[(i & 7) + 320 * (i >> 3) + (i & ~7)] == 0x80 >> (i & 7));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
SRCS=$(filter-out opp_part1.cpp opp_part2.cpp, $(wildcard *.c *.cpp))
|
||||
EXES=$(patsubst %.c,%,$(SRCS))
|
||||
EXES:=$(patsubst %.cpp,%,$(EXES))
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
%: %.c
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
|
@ -0,0 +1,49 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned b[4096];
|
||||
|
||||
void testfwd(unsigned sz)
|
||||
{
|
||||
for(unsigned i=0; i<4096; i++)
|
||||
b[i] = i;
|
||||
|
||||
memmove(b + 100, b + 101, 2 * sz);
|
||||
|
||||
for(unsigned i=0; i<100; i++)
|
||||
assert(b[i] == i);
|
||||
for(unsigned i=100; i<100 + sz; i++)
|
||||
assert(b[i] == i + 1);
|
||||
for(unsigned i=100 + sz; i<4096; i++)
|
||||
assert(b[i] == i);
|
||||
}
|
||||
|
||||
void testback(unsigned sz)
|
||||
{
|
||||
for(unsigned i=0; i<4096; i++)
|
||||
b[i] = i;
|
||||
|
||||
memmove(b + 101, b + 100, 2 * sz);
|
||||
|
||||
for(unsigned i=0; i<101; i++)
|
||||
assert(b[i] == i);
|
||||
for(unsigned i=101; i<101 + sz; i++)
|
||||
assert(b[i] == i - 1);
|
||||
for(unsigned i=101 + sz; i<4096; i++)
|
||||
assert(b[i] == i);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(unsigned i=1; i<2048; i *= 2)
|
||||
{
|
||||
testfwd(i - 1);
|
||||
testfwd(i);
|
||||
testback(i);
|
||||
testback(i - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
#include <assert.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned n1, n0;
|
||||
|
||||
n1 = 0; n0 = 0;
|
||||
for(int i=-1000; i<2000; i+=37)
|
||||
{
|
||||
for(char j=0; j<255; j++)
|
||||
{
|
||||
if (i < j)
|
||||
n1++;
|
||||
else
|
||||
n0++;
|
||||
}
|
||||
}
|
||||
|
||||
assert(n1 == 7893 && n0 == 13017);
|
||||
|
||||
n1 = 0; n0 = 0;
|
||||
for(int i=-1000; i<2000; i+=37)
|
||||
{
|
||||
for(char j=0; j<255; j++)
|
||||
{
|
||||
if (i <= j)
|
||||
n1++;
|
||||
else
|
||||
n0++;
|
||||
}
|
||||
}
|
||||
|
||||
assert(n1 == 7899 && n0 == 13011);
|
||||
|
||||
n1 = 0; n0 = 0;
|
||||
for(int i=-1000; i<2000; i+=37)
|
||||
{
|
||||
for(char j=0; j<255; j++)
|
||||
{
|
||||
if (i >= j)
|
||||
n1++;
|
||||
else
|
||||
n0++;
|
||||
}
|
||||
}
|
||||
|
||||
assert(n0 == 7893 && n1 == 13017);
|
||||
|
||||
n1 = 0; n0 = 0;
|
||||
for(int i=-1000; i<2000; i+=37)
|
||||
{
|
||||
for(char j=0; j<255; j++)
|
||||
{
|
||||
if (i > j)
|
||||
n1++;
|
||||
else
|
||||
n0++;
|
||||
}
|
||||
}
|
||||
|
||||
assert(n0 == 7899 && n1 == 13011);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -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,90 @@
|
|||
#include <assert.h>
|
||||
|
||||
struct A
|
||||
{
|
||||
int n;
|
||||
|
||||
A(int n_)
|
||||
: n(n_) {}
|
||||
|
||||
A(const A & a)
|
||||
: n(a.n) {}
|
||||
|
||||
A operator+(const A & a) const
|
||||
{
|
||||
return A(n + a.n);
|
||||
}
|
||||
|
||||
A operator-(const A & a) const
|
||||
{
|
||||
return A(n - a.n);
|
||||
}
|
||||
|
||||
A & operator+=(const A & a)
|
||||
{
|
||||
n += a.n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
A & operator-=(const A & a)
|
||||
{
|
||||
n -= a.n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
A operator-(void) const
|
||||
{
|
||||
return A(-n);
|
||||
}
|
||||
|
||||
A & operator++(void)
|
||||
{
|
||||
n++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
A & operator--(void)
|
||||
{
|
||||
n--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
A operator++(int);
|
||||
|
||||
A operator--(int);
|
||||
|
||||
};
|
||||
|
||||
A A::operator++(int)
|
||||
{
|
||||
A a(*this);
|
||||
n++;
|
||||
return a;
|
||||
}
|
||||
|
||||
A A::operator--(int)
|
||||
{
|
||||
A a(*this);
|
||||
n--;
|
||||
return a;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
A a(7), b(8), c(9);
|
||||
|
||||
assert((++a).n == 8);
|
||||
assert(a.n == 8);
|
||||
|
||||
assert((--a).n == 7);
|
||||
assert(a.n == 7);
|
||||
|
||||
assert((a++).n == 7);
|
||||
assert(a.n == 8);
|
||||
assert((a--).n == 8);
|
||||
assert(a.n == 7);
|
||||
|
||||
assert((a + b - c + -a + -b - -c).n == 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include <opp/array.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::array<int, 10> a10;
|
||||
opp::array<int, 20> a20;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
a10[i] = i;
|
||||
for(int i=0; i<20; i++)
|
||||
a20[i] = i;
|
||||
|
||||
int s = 0;
|
||||
for(int i=0; i<10; i++)
|
||||
s += a10[i];
|
||||
for(int i=10; i<20; i++)
|
||||
s -= a20[i];
|
||||
|
||||
assert(s == -100);
|
||||
|
||||
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,28 @@
|
|||
#include <assert.h>
|
||||
#include <opp/vector.h>
|
||||
#include <opp/utility.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
using namespace opp;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
vector<pair<int, int> > vii;
|
||||
|
||||
for(int i=0; i<100; i++)
|
||||
vii.push_back(make_pair(i, i * i));
|
||||
|
||||
int sum1 = 0;
|
||||
long sum2 = 0;
|
||||
for(const auto & v : vii)
|
||||
{
|
||||
sum1 += v.first;
|
||||
sum2 += v.second;
|
||||
}
|
||||
|
||||
|
||||
assert(sum1 == 4950);
|
||||
assert(sum2 == 328350l);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#include "opp_part1.h"
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <opp/vector.h>
|
||||
|
||||
class A
|
||||
{
|
||||
protected:
|
||||
int a, b;
|
||||
|
||||
public:
|
||||
A(int a_, int b_)
|
||||
: a(a_), b(b_)
|
||||
{}
|
||||
|
||||
int sum(void) const
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
};
|
||||
|
||||
class AS
|
||||
{
|
||||
protected:
|
||||
opp::vector<A> va;
|
||||
public:
|
||||
AS(const opp::vector<A> & v)
|
||||
: va(v)
|
||||
{}
|
||||
|
||||
int sum(void)
|
||||
{
|
||||
int s = 0;
|
||||
for(const auto & a : va)
|
||||
s += a.sum();
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
#pragma compile("opp_part1.cpp")
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include "opp_part2.h"
|
||||
|
||||
BS::BS(const opp::vector<A> & v)
|
||||
: va(v)
|
||||
{}
|
||||
|
||||
int BS::sum(void)
|
||||
{
|
||||
int s = 0;
|
||||
for(const auto & a : va)
|
||||
s += a.sum();
|
||||
return s;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "opp_part1.h"
|
||||
|
||||
class BS
|
||||
{
|
||||
protected:
|
||||
opp::vector<A> va;
|
||||
public:
|
||||
BS(const opp::vector<A> & v);
|
||||
int sum(void);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#pragma compile("opp_part2.cpp")
|
|
@ -0,0 +1,25 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "opp_part1.h"
|
||||
#include "opp_part2.h"
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::vector<A> va;
|
||||
va.push_back(A(1, 2));
|
||||
va.push_back(A(3, 4));
|
||||
va.push_back(A(6, 4));
|
||||
va.push_back(A(0, 9));
|
||||
|
||||
AS as(va);
|
||||
|
||||
va.push_back(A(7, 1));
|
||||
|
||||
BS bs(va);
|
||||
|
||||
assert(bs.sum() == 2 + 12 + 24 + 7);
|
||||
assert(as.sum() == 2 + 12 + 24);
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#include <opp/string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <opp/sstream.h>
|
||||
#include <math.h>
|
||||
|
||||
using opp::ostringstream;
|
||||
using opp::istringstream;
|
||||
using opp::endl;
|
||||
|
||||
float fdist(float a, float b)
|
||||
{
|
||||
float d = fabs(a - b);
|
||||
a = fabs(a);
|
||||
b = fabs(b);
|
||||
return d / (a > b ? a : b);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
for(int i=0; i<40; i++)
|
||||
{
|
||||
os << i << endl;
|
||||
}
|
||||
|
||||
istringstream is(os.str());
|
||||
|
||||
int j = 0, k = 47;
|
||||
#if 1
|
||||
|
||||
while (is >> k)
|
||||
{
|
||||
assert(k == j++);
|
||||
}
|
||||
|
||||
assert(j == 40);
|
||||
#endif
|
||||
os.str(opp::string());
|
||||
|
||||
#if 0
|
||||
cout << "[" << os.str() << "]" << endl;
|
||||
os << "HELLO";
|
||||
cout << "[" << os.str() << "]" << endl;
|
||||
#endif
|
||||
#if 1
|
||||
|
||||
float f = 1.0, g = 1.0;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
os << f << " " << g << endl;
|
||||
// cout << os.str();
|
||||
|
||||
f *= 5.1;
|
||||
g *= 0.12;
|
||||
}
|
||||
|
||||
|
||||
is.str(os.str());
|
||||
|
||||
f = 1.0, g = 1.0;
|
||||
|
||||
float fr, gr;
|
||||
|
||||
j = 0;
|
||||
while (is >> fr >> gr)
|
||||
{
|
||||
// cout << f << " " << fr << ", " << g << " " << gr << ", " << fdist(fr, f) << endl;
|
||||
|
||||
assert(fdist(fr, f) < 1.0e-5);
|
||||
assert(fdist(gr, g) < 1.0e-5);
|
||||
|
||||
f *= 5.1;
|
||||
g *= 0.12;
|
||||
j++;
|
||||
}
|
||||
|
||||
assert(j == 10);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
#include <opp/string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
using opp::string;
|
||||
|
||||
static const char HelloWorld[] = "Hello World";
|
||||
static const char AndBeyond[] = "And Beyond";
|
||||
static const char And[] = "And";
|
||||
static const char HelloWorldAndBeyond[] = "Hello World And Beyond";
|
||||
|
||||
__noinline void test_create(void)
|
||||
{
|
||||
string s1();
|
||||
string s2(HelloWorld);
|
||||
string s3(s2);
|
||||
string s4('a');
|
||||
|
||||
assert(!strcmp(s2.tocstr(), HelloWorld));
|
||||
assert(!strcmp(s3.tocstr(), HelloWorld));
|
||||
assert(s4.size() == 1 && s4[0] == 'a');
|
||||
}
|
||||
|
||||
__noinline void test_concat(void)
|
||||
{
|
||||
string s1();
|
||||
string s2(HelloWorld);
|
||||
string s3(AndBeyond);
|
||||
|
||||
string s4 = s1 + s2;
|
||||
string s5 = s2 + " " + s3;
|
||||
string s6 = s2 + " " + AndBeyond;
|
||||
|
||||
assert(!strcmp(s4.tocstr(), HelloWorld));
|
||||
assert(!strcmp(s5.tocstr(), HelloWorldAndBeyond));
|
||||
assert(!strcmp(s6.tocstr(), HelloWorldAndBeyond));
|
||||
}
|
||||
|
||||
__noinline void test_find(void)
|
||||
{
|
||||
string s1(HelloWorldAndBeyond);
|
||||
string s2(And);
|
||||
|
||||
assert(s1.find(HelloWorld) == 0);
|
||||
assert(s1.find(AndBeyond) == 12);
|
||||
assert(s1.find(And) == 12);
|
||||
assert(s1.find(s2) == 12);
|
||||
|
||||
assert(s1.find(' ') == 5);
|
||||
assert(s1.find(' ', 6) == 11);
|
||||
}
|
||||
|
||||
__noinline void test_assign(void)
|
||||
{
|
||||
string s1(HelloWorld);
|
||||
string s2(AndBeyond);
|
||||
string s3;
|
||||
s3 = s1;
|
||||
s3 = s2;
|
||||
s3 = s1;
|
||||
s3 += " ";
|
||||
s3 += s2;
|
||||
|
||||
assert(!strcmp(s3.tocstr(), HelloWorldAndBeyond));
|
||||
|
||||
s3 <<= 12;
|
||||
|
||||
assert(!strcmp(s3.tocstr(), AndBeyond));
|
||||
|
||||
s3 = HelloWorldAndBeyond;
|
||||
|
||||
assert(!strcmp(s3.tocstr(), HelloWorldAndBeyond));
|
||||
|
||||
s3 >>= 11;
|
||||
|
||||
assert(!strcmp(s3.tocstr(), HelloWorld));
|
||||
}
|
||||
|
||||
static char * test;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test = new char;
|
||||
|
||||
unsigned avail = heapfree();
|
||||
|
||||
test_create();
|
||||
assert(avail == heapfree());
|
||||
|
||||
test_concat();
|
||||
assert(avail == heapfree());
|
||||
|
||||
test_find();
|
||||
assert(avail == heapfree());
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
#include <opp/vector.h>
|
||||
#include <opp/algorithm.h>
|
||||
#include <assert.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::vector<int> 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::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,38 @@
|
|||
#include <opp/vector.h>
|
||||
#include <opp/string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
using opp::string;
|
||||
using opp::vector;
|
||||
|
||||
string join(const vector<string> & vs)
|
||||
{
|
||||
string sj;
|
||||
for(int i=0; i<vs.size(); i++)
|
||||
sj += vs[i];
|
||||
return sj;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
vector<string> vs;
|
||||
string a;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
vs.push_back(a);
|
||||
a += "x";
|
||||
}
|
||||
|
||||
int s = 0;
|
||||
for(int i=0; i<10; i++)
|
||||
s += vs[i].size();
|
||||
|
||||
assert(s == 45);
|
||||
|
||||
assert(join(vs).size() == 45);
|
||||
|
||||
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,39 @@
|
|||
#include <assert.h>
|
||||
|
||||
struct X
|
||||
{
|
||||
int a;
|
||||
};
|
||||
|
||||
X x[5] = {
|
||||
{1}, {2}, {3}, {4}, {5}
|
||||
};
|
||||
|
||||
X * y;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
y = x;
|
||||
assert(y == x);
|
||||
y = x + 1;
|
||||
assert(y == x + 1);
|
||||
y = &(x[2]);
|
||||
assert(y == x + 2);
|
||||
y = x + 3;
|
||||
assert(y == &(x[3]));
|
||||
y = x ;
|
||||
assert(y == (struct X*)x);
|
||||
|
||||
y = x;
|
||||
assert(x == y);
|
||||
y = x + 1;
|
||||
assert(x + 1 == y);
|
||||
y = &(x[2]);
|
||||
assert(x + 2 == y);
|
||||
y = x + 3;
|
||||
assert(&(x[3]) == y);
|
||||
y = x ;
|
||||
assert((struct X*)x == y);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#if 1
|
||||
|
||||
const struct A {
|
||||
char w;
|
||||
int b[5];
|
||||
struct {
|
||||
int c[5];
|
||||
} o;
|
||||
} a = {22,
|
||||
{4, 5, 6, 7, 8},
|
||||
{
|
||||
{4, 5, 6, 7, 8}
|
||||
}
|
||||
};
|
||||
|
||||
const int * t[4] = {
|
||||
a.b + 1 + 1
|
||||
};
|
||||
|
||||
const int * v[4] = {
|
||||
a.o.c + 1 + 1
|
||||
};
|
||||
|
||||
int q[5] = {4, 5, 6, 7, 8};
|
||||
|
||||
const int * u[4] = {
|
||||
q + 2
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return
|
||||
u[0][0] + (q + 2)[2] - 6 - 8 +
|
||||
v[0][0] + (a.o.c + 2)[2] - 6 - 8 +
|
||||
t[0][0] + (a.b + 2)[2] - 6 - 8;
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ void qsort(Node * n, int s)
|
|||
{
|
||||
n[pi] = n[i];
|
||||
pi++;
|
||||
n[i] = n[pi]
|
||||
n[i] = n[pi];
|
||||
}
|
||||
}
|
||||
n[pi] = pn;
|
||||
|
|
|
@ -11,6 +11,6 @@ int main(void)
|
|||
|
||||
assert(lsum == 32157742L);
|
||||
|
||||
return 0
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,321 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
void testi(const char * fmt, int val, const char * tst)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, fmt, val);
|
||||
printf("%s:%s\n", buffer, tst);
|
||||
assert(!strcmp(buffer, tst));
|
||||
}
|
||||
|
||||
void testu(const char * fmt, unsigned val, const char * tst)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, fmt, val);
|
||||
printf("%s:%s\n", buffer, tst);
|
||||
assert(!strcmp(buffer, tst));
|
||||
}
|
||||
|
||||
void testil(const char * fmt, long val, const char * tst)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, fmt, val);
|
||||
printf("%s:%s\n", buffer, tst);
|
||||
assert(!strcmp(buffer, tst));
|
||||
}
|
||||
|
||||
void testul(const char * fmt, unsigned long val, const char * tst)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, fmt, val);
|
||||
printf("%s:%s\n", buffer, tst);
|
||||
assert(!strcmp(buffer, tst));
|
||||
}
|
||||
|
||||
void testf(const char * fmt, float val, const char * tst)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, fmt, val);
|
||||
printf("%s:%s\n", buffer, tst);
|
||||
assert(!strcmp(buffer, tst));
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
testi("%d", 0, "0");
|
||||
testi("%d", 1, "1");
|
||||
testi("%d", -1, "-1");
|
||||
testi("%d", 12, "12");
|
||||
testi("%d", 123, "123");
|
||||
testi("%d", 1234, "1234");
|
||||
testi("%d", 12345, "12345");
|
||||
testi("%d", -12345, "-12345");
|
||||
testi("%d", 32767, "32767");
|
||||
testi("%d", -32768, "-32768");
|
||||
|
||||
testi("%3d", 0, " 0");
|
||||
testi("%3d", 1, " 1");
|
||||
testi("%3d", -1, " -1");
|
||||
testi("%3d", 12, " 12");
|
||||
testi("%3d", 123, "123");
|
||||
testi("%3d", 1234, "1234");
|
||||
testi("%3d", 12345, "12345");
|
||||
testi("%3d", -12345, "-12345");
|
||||
testi("%3d", 32767, "32767");
|
||||
testi("%3d", -32768, "-32768");
|
||||
|
||||
testi("%03d", 0, "000");
|
||||
testi("%03d", 1, "001");
|
||||
// testi("%03d", -1, "-01");
|
||||
testi("%03d", 12, "012");
|
||||
testi("%03d", 123, "123");
|
||||
testi("%03d", 1234, "1234");
|
||||
testi("%03d", 12345, "12345");
|
||||
testi("%03d", -12345, "-12345");
|
||||
testi("%03d", 32767, "32767");
|
||||
testi("%03d", -32768, "-32768");
|
||||
|
||||
testi("%-4d", 0, "0 ");
|
||||
testi("%-4d", 1, "1 ");
|
||||
testi("%-4d", -1, "-1 ");
|
||||
testi("%-4d", 12, "12 ");
|
||||
testi("%-4d", 123, "123 ");
|
||||
testi("%-4d", 1234, "1234");
|
||||
testi("%-4d", 12345, "12345");
|
||||
testi("%-4d", -12345, "-12345");
|
||||
testi("%-4d", 32767, "32767");
|
||||
testi("%-4d", -32768, "-32768");
|
||||
|
||||
testi("%+d", 0, "+0");
|
||||
testi("%+d", 1, "+1");
|
||||
testi("%+d", -1, "-1");
|
||||
testi("%+d", 12, "+12");
|
||||
testi("%+d", 123, "+123");
|
||||
testi("%+d", 1234, "+1234");
|
||||
testi("%+d", 12345, "+12345");
|
||||
testi("%+d", -12345, "-12345");
|
||||
testi("%+d", 32767, "+32767");
|
||||
testi("%+d", -32768, "-32768");
|
||||
|
||||
|
||||
|
||||
testil("%ld", 0l, "0");
|
||||
testil("%ld", 1l, "1");
|
||||
testil("%ld", -1l, "-1");
|
||||
testil("%ld", 12l, "12");
|
||||
testil("%ld", 123l, "123");
|
||||
testil("%ld", 1234l, "1234");
|
||||
testil("%ld", 12345l, "12345");
|
||||
testil("%ld", -12345l, "-12345");
|
||||
testil("%ld", 32767l, "32767");
|
||||
testil("%ld", -32768l, "-32768");
|
||||
testil("%ld", 2147483647l, "2147483647");
|
||||
testil("%ld", -2147483648l, "-2147483648");
|
||||
|
||||
testil("%3ld", 0l, " 0");
|
||||
testil("%3ld", 1l, " 1");
|
||||
testil("%3ld", -1l, " -1");
|
||||
testil("%3ld", 12l, " 12");
|
||||
testil("%3ld", 123l, "123");
|
||||
testil("%3ld", 1234l, "1234");
|
||||
testil("%3ld", 12345l, "12345");
|
||||
testil("%3ld", -12345l, "-12345");
|
||||
testil("%3ld", 32767l, "32767");
|
||||
testil("%3ld", -32768l, "-32768");
|
||||
testil("%3ld", 2147483647l, "2147483647");
|
||||
testil("%3ld", -2147483648l, "-2147483648");
|
||||
|
||||
testil("%03ld", 0l, "000");
|
||||
testil("%03ld", 1l, "001");
|
||||
// testil("%03ld", -1l, "-01");
|
||||
testil("%03ld", 12l, "012");
|
||||
testil("%03ld", 123l, "123");
|
||||
testil("%03ld", 1234l, "1234");
|
||||
testil("%03ld", 12345l, "12345");
|
||||
testil("%03ld", -12345l, "-12345");
|
||||
testil("%03ld", 32767l, "32767");
|
||||
testil("%03ld", -32768l, "-32768");
|
||||
testil("%03ld", 2147483647l, "2147483647");
|
||||
testil("%03ld", -2147483648l, "-2147483648");
|
||||
|
||||
testil("%-4ld", 0l, "0 ");
|
||||
testil("%-4ld", 1l, "1 ");
|
||||
testil("%-4ld", -1l, "-1 ");
|
||||
testil("%-4ld", 12l, "12 ");
|
||||
testil("%-4ld", 123l, "123 ");
|
||||
testil("%-4ld", 1234l, "1234");
|
||||
testil("%-4ld", 12345l, "12345");
|
||||
testil("%-4ld", -12345l, "-12345");
|
||||
testil("%-4ld", 32767l, "32767");
|
||||
testil("%-4ld", -32768l, "-32768");
|
||||
testil("%-4ld", 2147483647l, "2147483647");
|
||||
testil("%-4ld", -2147483648l, "-2147483648");
|
||||
|
||||
testil("%+ld", 0l, "+0");
|
||||
testil("%+ld", 1l, "+1");
|
||||
testil("%+ld", -1l, "-1");
|
||||
testil("%+ld", 12l, "+12");
|
||||
testil("%+ld", 123l, "+123");
|
||||
testil("%+ld", 1234l, "+1234");
|
||||
testil("%+ld", 12345l, "+12345");
|
||||
testil("%+ld", -12345l, "-12345");
|
||||
testil("%+ld", 32767l, "+32767");
|
||||
testil("%+ld", -32768l, "-32768");
|
||||
testil("%+ld", 2147483647l, "+2147483647");
|
||||
testil("%+ld", -2147483648l, "-2147483648");
|
||||
|
||||
testu("%u", 0, "0");
|
||||
testu("%u", 1, "1");
|
||||
testu("%u", 12, "12");
|
||||
testu("%u", 123, "123");
|
||||
testu("%u", 1234, "1234");
|
||||
testu("%u", 12345, "12345");
|
||||
testu("%u", 32767, "32767");
|
||||
testu("%u", 32768, "32768");
|
||||
testu("%u", 65535, "65535");
|
||||
testu("%x", 0, "0");
|
||||
testu("%x", 0x49bf, "49BF");
|
||||
testu("%x", 0xffff, "FFFF");
|
||||
|
||||
testu("%3u", 0, " 0");
|
||||
testu("%3u", 1, " 1");
|
||||
testu("%3u", 12, " 12");
|
||||
testu("%3u", 123, "123");
|
||||
testu("%3u", 1234, "1234");
|
||||
testu("%3u", 12345, "12345");
|
||||
testu("%3u", 32767, "32767");
|
||||
testu("%3u", 32768, "32768");
|
||||
testu("%3u", 65535, "65535");
|
||||
testu("%3x", 0, " 0");
|
||||
testu("%3x", 0x49bf, "49BF");
|
||||
testu("%3x", 0xffff, "FFFF");
|
||||
|
||||
testu("%03u", 0, "000");
|
||||
testu("%03u", 1, "001");
|
||||
testu("%03u", 12, "012");
|
||||
testu("%03u", 123, "123");
|
||||
testu("%03u", 1234, "1234");
|
||||
testu("%03u", 12345, "12345");
|
||||
testu("%03u", 32767, "32767");
|
||||
testu("%03u", 32768, "32768");
|
||||
testu("%03u", 65535, "65535");
|
||||
testu("%03x", 0, "000");
|
||||
testu("%03x", 0x49bf, "49BF");
|
||||
testu("%03x", 0xffff, "FFFF");
|
||||
|
||||
testu("%-4u", 0, "0 ");
|
||||
testu("%-4u", 1, "1 ");
|
||||
testu("%-4u", 12, "12 ");
|
||||
testu("%-4u", 123, "123 ");
|
||||
testu("%-4u", 1234, "1234");
|
||||
testu("%-4u", 12345, "12345");
|
||||
testu("%-4u", 32767, "32767");
|
||||
testu("%-4u", 32768, "32768");
|
||||
testu("%-4u", 65535, "65535");
|
||||
testu("%-4x", 0, "0 ");
|
||||
testu("%-4x", 0x49bf, "49BF");
|
||||
testu("%-4x", 0xffff, "FFFF");
|
||||
|
||||
testul("%3lu", 0l, " 0");
|
||||
testul("%3lu", 1l, " 1");
|
||||
testul("%3lu", 12l, " 12");
|
||||
testul("%3lu", 123l, "123");
|
||||
testul("%3lu", 1234l, "1234");
|
||||
testul("%3lu", 12345l, "12345");
|
||||
testul("%3lu", 32767l, "32767");
|
||||
testul("%3lu", 2147483647l, "2147483647");
|
||||
testul("%3lu", 4294967295l, "4294967295");
|
||||
testul("%3lx", 0, " 0");
|
||||
testul("%3lx", 0x3576fbcdl, "3576FBCD");
|
||||
testul("%3lx", 0xffffffffl, "FFFFFFFF");
|
||||
|
||||
testul("%03lu", 0l, "000");
|
||||
testul("%03lu", 1l, "001");
|
||||
testul("%03lu", 12l, "012");
|
||||
testul("%03lu", 123l, "123");
|
||||
testul("%03lu", 1234l, "1234");
|
||||
testul("%03lu", 12345l, "12345");
|
||||
testul("%03lu", 32767l, "32767");
|
||||
testul("%03lu", 2147483647l, "2147483647");
|
||||
testul("%03lu", 4294967295l, "4294967295");
|
||||
testul("%03lx", 0, "000");
|
||||
testul("%03lx", 0x3576fbcdl, "3576FBCD");
|
||||
testul("%03lx", 0xffffffffl, "FFFFFFFF");
|
||||
|
||||
testul("%-4lu", 0l, "0 ");
|
||||
testul("%-4lu", 1l, "1 ");
|
||||
testul("%-4lu", 12l, "12 ");
|
||||
testul("%-4lu", 123l, "123 ");
|
||||
testul("%-4lu", 1234l, "1234");
|
||||
testul("%-4lu", 12345l, "12345");
|
||||
testul("%-4lu", 32767l, "32767");
|
||||
testul("%-4lu", 2147483647l, "2147483647");
|
||||
testul("%-4lu", 4294967295l, "4294967295");
|
||||
testul("%-4lx", 0, "0 ");
|
||||
testul("%-4lx", 0x3576fbcdl, "3576FBCD");
|
||||
testul("%-4lx", 0xffffffffl, "FFFFFFFF");
|
||||
|
||||
testul("%+lu", 0l, "+0");
|
||||
testul("%+lu", 1l, "+1");
|
||||
testul("%+lu", 12l, "+12");
|
||||
testul("%+lu", 123l, "+123");
|
||||
testul("%+lu", 1234l, "+1234");
|
||||
testul("%+lu", 12345l, "+12345");
|
||||
testul("%+lu", 32767l, "+32767");
|
||||
testul("%+lu", 2147483647l, "+2147483647");
|
||||
testul("%+lu", 4294967295l, "+4294967295");
|
||||
|
||||
testf("%f", 0., "0.000000");
|
||||
testf("%f", 1., "1.000000");
|
||||
testf("%f", -1., "-1.000000");
|
||||
testf("%f", 12., "12.000000");
|
||||
testf("%f", 123., "123.000000");
|
||||
testf("%f", 1234., "1234.000000");
|
||||
testf("%f", 12345., "12345.000000");
|
||||
testf("%f", 123456., "123456.000000");
|
||||
testf("%f", 1234567., "1234567.000000");
|
||||
testf("%f", 0.1, "0.100000");
|
||||
testf("%f", 0.01, "0.010000");
|
||||
testf("%f", 0.001, "0.001000");
|
||||
testf("%f", 0.0001, "0.000100");
|
||||
testf("%f", 0.00001, "0.000010");
|
||||
testf("%f", 0.000001, "0.000001");
|
||||
|
||||
testf("%5.1f", 0, " 0.0");
|
||||
testf("%5.1f", 1, " 1.0");
|
||||
testf("%5.1f", -1, " -1.0");
|
||||
testf("%5.1f", 10, " 10.0");
|
||||
testf("%5.1f", -10, "-10.0");
|
||||
testf("%5.1f", 100, "100.0");
|
||||
testf("%5.1f", -100, "-100.0");
|
||||
testf("%5.1f", 0.1, " 0.1");
|
||||
testf("%5.1f", -0.1, " -0.1");
|
||||
testf("%5.1f", 0.04, " 0.0");
|
||||
testf("%5.1f", -0.04, " -0.0");
|
||||
testf("%5.1f", 0.051, " 0.1");
|
||||
testf("%5.1f", -0.051, " -0.1");
|
||||
|
||||
testf("%+5.1f", 0, " +0.0");
|
||||
testf("%+5.1f", 1, " +1.0");
|
||||
testf("%+5.1f", -1, " -1.0");
|
||||
testf("%+5.1f", 10, "+10.0");
|
||||
testf("%+5.1f", -10, "-10.0");
|
||||
testf("%+5.1f", 100, "+100.0");
|
||||
testf("%+5.1f", -100, "-100.0");
|
||||
testf("%+5.1f", 0.1, " +0.1");
|
||||
testf("%+5.1f", -0.1, " -0.1");
|
||||
testf("%+5.1f", 0.04, " +0.0");
|
||||
testf("%+5.1f", -0.04, " -0.0");
|
||||
testf("%+5.1f", 0.051, " +0.1");
|
||||
testf("%+5.1f", -0.051, " -0.1");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
// stdlibtest
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -50,16 +51,15 @@ void heapcheck(void)
|
|||
for(i=0; i<s; i++)
|
||||
{
|
||||
if (p[i] != n)
|
||||
{
|
||||
printf("MemError %d at %d:%d != %d\n", k, i, n, p[i]);
|
||||
exit(-2);
|
||||
}
|
||||
}
|
||||
free(memp[n]);
|
||||
|
||||
s = rand() % 100 + 3;
|
||||
mems[n] = s;
|
||||
memp[n] = malloc(s);
|
||||
if (!memp[n])
|
||||
exit(-3);
|
||||
memset(memp[n], n, s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,299 @@
|
|||
#include <assert.h>
|
||||
|
||||
|
||||
int a100[100];
|
||||
__striped int b100[100];
|
||||
__striped int c100[100];
|
||||
|
||||
unsigned a256[256];
|
||||
__striped unsigned b256[256];
|
||||
__striped unsigned c256[256];
|
||||
|
||||
#pragma align(c100, 256)
|
||||
#pragma align(c256, 256)
|
||||
|
||||
void test_ab100(void)
|
||||
{
|
||||
for(char i=0; i<100; i++)
|
||||
{
|
||||
a100[i] = i * i;
|
||||
b100[i] = i * i;
|
||||
c100[i] = i * i;
|
||||
}
|
||||
|
||||
a100[31] = 4711;
|
||||
b100[31] = 4711;
|
||||
c100[31] = 4711;
|
||||
|
||||
|
||||
for(char i=0; i<100; i++)
|
||||
{
|
||||
a100[i] += i; a100[i] -= 5; a100[i] = a100[i] + a100[99 - i];
|
||||
b100[i] += i; b100[i] -= 5; b100[i] = b100[i] + b100[99 - i];
|
||||
c100[i] += i; c100[i] -= 5; c100[i] = c100[i] + c100[99 - i];
|
||||
}
|
||||
|
||||
for(char i=0; i<100; i++)
|
||||
{
|
||||
assert(a100[i] == b100[i]);
|
||||
assert(a100[i] == c100[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_ab256(void)
|
||||
{
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
a256[i] = i * i;
|
||||
b256[i] = i * i;
|
||||
c256[i] = i * i;
|
||||
}
|
||||
|
||||
a256[31] = 4711;
|
||||
b256[31] = 4711;
|
||||
c256[31] = 4711;
|
||||
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
a256[i] += i; a256[i] -= 5; a256[i] = a256[i] + a256[255 - i];
|
||||
b256[i] += i; b256[i] -= 5; b256[i] = b256[i] + b256[255 - i];
|
||||
c256[i] += i; c256[i] -= 5; c256[i] = c256[i] + c256[255 - i];
|
||||
}
|
||||
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
assert(a256[i] == b256[i]);
|
||||
assert(a256[i] == c256[i]);
|
||||
}
|
||||
}
|
||||
|
||||
long la50[50];
|
||||
__striped long lb50[50];
|
||||
__striped long lc50[50];
|
||||
|
||||
unsigned long la256[256];
|
||||
__striped unsigned long lb256[256];
|
||||
__striped unsigned long lc256[256];
|
||||
|
||||
#pragma align(lc50, 256)
|
||||
#pragma align(lc256, 256)
|
||||
|
||||
void test_lab50(void)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
long j = i * i;
|
||||
la50[i] = j * j;
|
||||
lb50[i] = j * j;
|
||||
lc50[i] = j * j;
|
||||
}
|
||||
|
||||
la50[31] = 47110815l;
|
||||
lb50[31] = 47110815l;
|
||||
lc50[31] = 47110815l;
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
la50[i] += i; la50[i] -= 12345678l; la50[i] = la50[i] + la50[49 - i];
|
||||
lb50[i] += i; lb50[i] -= 12345678l; lb50[i] = lb50[i] + lb50[49 - i];
|
||||
lc50[i] += i; lc50[i] -= 12345678l; lc50[i] = lc50[i] + lc50[49 - i];
|
||||
}
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
assert(la50[i] == lb50[i]);
|
||||
assert(la50[i] == lc50[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_lab256(void)
|
||||
{
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
unsigned long j = i * i;
|
||||
la256[i] = j * j;
|
||||
lb256[i] = j * j;
|
||||
lc256[i] = j * j;
|
||||
}
|
||||
|
||||
la256[31] = 47110815ul;
|
||||
lb256[31] = 47110815ul;
|
||||
lc256[31] = 47110815ul;
|
||||
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
la256[i] += i; la256[i] -= 12345678ul; la256[i] = la256[i] + la256[255 - i];
|
||||
lb256[i] += i; lb256[i] -= 12345678ul; lb256[i] = lb256[i] + lb256[255 - i];
|
||||
lc256[i] += i; lc256[i] -= 12345678ul; lc256[i] = lc256[i] + lc256[255 - i];
|
||||
}
|
||||
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
assert(la256[i] == lb256[i]);
|
||||
assert(la256[i] == lc256[i]);
|
||||
}
|
||||
}
|
||||
|
||||
float fa50[50];
|
||||
__striped float fb50[50];
|
||||
__striped float fc50[50];
|
||||
|
||||
float fa256[256];
|
||||
__striped float fb256[256];
|
||||
__striped float fc256[256];
|
||||
|
||||
#pragma align(fc50, 256)
|
||||
#pragma align(fc256, 256)
|
||||
|
||||
void test_fab50(void)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
fa50[i] = i * i;
|
||||
fb50[i] = i * i;
|
||||
fc50[i] = i * i;
|
||||
}
|
||||
|
||||
fa50[31] = 4711.0815;
|
||||
fb50[31] = 4711.0815;
|
||||
fc50[31] = 4711.0815;
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
fa50[i] += i; fa50[i] -= 1234.5678; fa50[i] = fa50[i] + fa50[49 - i];
|
||||
fb50[i] += i; fb50[i] -= 1234.5678; fb50[i] = fb50[i] + fb50[49 - i];
|
||||
fc50[i] += i; fc50[i] -= 1234.5678; fc50[i] = fc50[i] + fc50[49 - i];
|
||||
}
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
assert(fa50[i] == fb50[i]);
|
||||
assert(fa50[i] == fc50[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_fab256(void)
|
||||
{
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
fa256[i] = i * i;
|
||||
fb256[i] = i * i;
|
||||
fc256[i] = i * i;
|
||||
}
|
||||
|
||||
fa256[31] = 4711.0815;
|
||||
fb256[31] = 4711.0815;
|
||||
fc256[31] = 4711.0815;
|
||||
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
fa256[i] += i; fa256[i] -= 1234.5678; fa256[i] = fa256[i] + fa256[255 - i];
|
||||
fb256[i] += i; fb256[i] -= 1234.5678; fb256[i] = fb256[i] + fb256[255 - i];
|
||||
fc256[i] += i; fc256[i] -= 1234.5678; fc256[i] = fc256[i] + fc256[255 - i];
|
||||
}
|
||||
|
||||
for(unsigned i=0; i<256; i++)
|
||||
{
|
||||
assert(fa256[i] == fb256[i]);
|
||||
assert(fa256[i] == fc256[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned da50[50], db50[50], dc50[50];
|
||||
|
||||
unsigned * pa50[50];
|
||||
__striped unsigned * pb50[50];
|
||||
__striped unsigned * pc50[50];
|
||||
|
||||
#pragma align(pc50, 256)
|
||||
|
||||
void test_pab50(void)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
pa50[i] = da50 + (i * 17) % 50;
|
||||
pb50[i] = db50 + (i * 17) % 50;
|
||||
pc50[i] = dc50 + (i * 17) % 50;
|
||||
}
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
*pa50[i] = i * i;
|
||||
*pb50[i] = i * i;
|
||||
*pc50[i] = i * i;
|
||||
}
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
*pa50[i] += i; *pa50[i] -= 5; *pa50[i] = *pa50[i] + *pa50[49 - i];
|
||||
*pb50[i] += i; *pb50[i] -= 5; *pb50[i] = *pb50[i] + *pb50[49 - i];
|
||||
*pc50[i] += i; *pc50[i] -= 5; *pc50[i] = *pc50[i] + *pc50[49 - i];
|
||||
}
|
||||
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
assert(*pa50[i] == *pb50[i]);
|
||||
assert(*pa50[i] == *pc50[i]);
|
||||
assert(da50[i] == db50[i]);
|
||||
assert(da50[i] == dc50[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned da50_4[50][4], db50_4[50][4], dc50_4[50][4];
|
||||
|
||||
void test_pab50_4(void)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
pa50[i] = da50_4[(i * 17) % 50];
|
||||
pb50[i] = db50_4[(i * 17) % 50];
|
||||
pc50[i] = dc50_4[(i * 17) % 50];
|
||||
}
|
||||
|
||||
for(char k=0; k<4; k++)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
pa50[i][k] = i * i;
|
||||
pb50[i][k] = i * i;
|
||||
pc50[i][k] = i * i;
|
||||
}
|
||||
}
|
||||
|
||||
for(char k=0; k<4; k++)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
pa50[i][k] += i; pa50[i][k] -= 5; pa50[i][k] = pa50[i][k] + pa50[49 - i][k];
|
||||
pb50[i][k] += i; pb50[i][k] -= 5; pb50[i][k] = pb50[i][k] + pb50[49 - i][k];
|
||||
pc50[i][k] += i; pc50[i][k] -= 5; pc50[i][k] = pc50[i][k] + pc50[49 - i][k];
|
||||
}
|
||||
}
|
||||
|
||||
for(char k=0; k<4; k++)
|
||||
{
|
||||
for(char i=0; i<50; i++)
|
||||
{
|
||||
assert(pa50[i][k] == pb50[i][k]);
|
||||
assert(pa50[i][k] == pc50[i][k]);
|
||||
assert(da50_4[i][k] == db50_4[i][k]);
|
||||
assert(da50_4[i][k] == dc50_4[i][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_ab100();
|
||||
test_ab256();
|
||||
test_lab50();
|
||||
test_lab256();
|
||||
test_fab50();
|
||||
test_fab256();
|
||||
test_pab50();
|
||||
test_pab50_4();
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
|
||||
struct Point
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
|
||||
Point tcorners[8], pcorners[8];
|
||||
|
||||
int bm_line(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drawCube(void)
|
||||
{
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
bm_line();
|
||||
if (!(i & 2))
|
||||
bm_line();
|
||||
if (!(i & 4))
|
||||
bm_line();
|
||||
|
||||
pcorners[i] = tcorners[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
tcorners[i].x = (i + 1) * 3;
|
||||
tcorners[i].y = (i + 1) * 7;
|
||||
}
|
||||
|
||||
drawCube();
|
||||
|
||||
int sum = 0;
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
sum += pcorners[i].x;
|
||||
sum -= tcorners[i].y;
|
||||
}
|
||||
|
||||
return sum + 144;
|
||||
}
|
|
@ -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);
|
||||
|
@ -54,7 +59,6 @@ long sieve(long size)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
testmuli(0, 0, 0);
|
||||
testmuli(1, 0, 0);
|
||||
testmuli(0, 1, 0);
|
||||
|
@ -65,11 +69,42 @@ int main(void)
|
|||
testmuli( 1, -1, -1);
|
||||
|
||||
testmuli(5, 5, 25);
|
||||
|
||||
testmuli( 127, 255, 32385);
|
||||
testmuli(-127, 255, -32385);
|
||||
testmuli( 127, -255, -32385);
|
||||
testmuli(-127, -255, 32385);
|
||||
|
||||
testmuli( 1237, 1024, 1266688l);
|
||||
testmuli(-1237, 1024, -1266688l);
|
||||
testmuli( 1237, -1024, -1266688l);
|
||||
testmuli(-1237, -1024, 1266688l);
|
||||
|
||||
testmuli( 1024, 1237, 1266688l);
|
||||
testmuli( 1024,-1237, -1266688l);
|
||||
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);
|
||||
|
@ -100,7 +135,6 @@ int main(void)
|
|||
|
||||
assert(sieve(200) == 47);
|
||||
assert(sieve(1000) == 169);
|
||||
|
||||
long a = 0, b = 0;
|
||||
for(long i=0; i<10000; i++)
|
||||
{
|
||||
|
@ -119,5 +153,14 @@ int main(void)
|
|||
d -= 10000;
|
||||
}
|
||||
|
||||
long e = 0, f = 0;
|
||||
for(long i=0; i<177000l; i += 1000)
|
||||
{
|
||||
assert( 1024 * i == e);
|
||||
assert(-1024 * i == f);
|
||||
e += 1024000l;
|
||||
f -= 1024000l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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,29 @@
|
|||
#include <assert.h>
|
||||
|
||||
int multab[32];
|
||||
|
||||
void fill_mulli(int m)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(int i=-16; i<16; i++)
|
||||
if (i != 0)
|
||||
multab[i + 16] = m / i;
|
||||
}
|
||||
|
||||
void check_mulli(int m)
|
||||
{
|
||||
for(int i=-16; i<16; i++)
|
||||
if (i != 0)
|
||||
assert(multab[i + 16] == m / i);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(int i=-1024; i<=1024; i++)
|
||||
{
|
||||
fill_mulli(i);
|
||||
check_mulli(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#include <assert.h>
|
||||
|
||||
int multab[32];
|
||||
|
||||
void fill_mulli(int m)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(int i=-16; i<16; i++)
|
||||
multab[i + 16] = m * i;
|
||||
}
|
||||
|
||||
void check_mulli(int m)
|
||||
{
|
||||
for(int i=-16; i<16; i++)
|
||||
assert(multab[i + 16] == m * i);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(int i=-1024; i<=1024; i++)
|
||||
{
|
||||
fill_mulli(i);
|
||||
check_mulli(i);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
#include <assert.h>
|
||||
|
||||
struct A
|
||||
{
|
||||
virtual int f(int x);
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
virtual int f(int x);
|
||||
};
|
||||
|
||||
struct C : A
|
||||
{
|
||||
virtual int f(int x);
|
||||
virtual int g(int y, int z);
|
||||
};
|
||||
|
||||
struct D : B
|
||||
{
|
||||
virtual int f(int x);
|
||||
};
|
||||
|
||||
struct E : C
|
||||
{
|
||||
virtual int f(int x);
|
||||
virtual int g(int y, int z);
|
||||
};
|
||||
|
||||
struct F : C
|
||||
{
|
||||
virtual int g(int y, int z);
|
||||
};
|
||||
|
||||
int A::f(int x)
|
||||
{
|
||||
return x * 1;
|
||||
}
|
||||
|
||||
int B::f(int x)
|
||||
{
|
||||
return x * 2;
|
||||
}
|
||||
|
||||
int C::f(int x)
|
||||
{
|
||||
return x * 3;
|
||||
}
|
||||
|
||||
int C::g(int y, int z)
|
||||
{
|
||||
return (y + z) * 3;
|
||||
}
|
||||
|
||||
int D::f(int x)
|
||||
{
|
||||
return x * 4;
|
||||
}
|
||||
|
||||
int E::f(int x)
|
||||
{
|
||||
return x * 5;
|
||||
}
|
||||
|
||||
int E::g(int y, int z)
|
||||
{
|
||||
return (y + z) * 5;
|
||||
}
|
||||
|
||||
int F::g(int y, int z)
|
||||
{
|
||||
return (y + z) * 6;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
A a;
|
||||
B b;
|
||||
C c;
|
||||
D d;
|
||||
E e;
|
||||
F f;
|
||||
|
||||
assert(a.f(3) == c.f(1));
|
||||
assert(b.f(4) == d.f(2));
|
||||
assert(e.f(2) == b.f(5));
|
||||
assert(f.f(5) == e.f(3));
|
||||
|
||||
assert(c.g(3, 2) == e.g(1, 2));
|
||||
assert(c.g(1, 5) == f.g(0, 3));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#include <assert.h>
|
||||
|
||||
struct Node
|
||||
{
|
||||
virtual float eval(void)
|
||||
{
|
||||
return 1.0e6;
|
||||
}
|
||||
};
|
||||
|
||||
struct ConstNode : Node
|
||||
{
|
||||
float c;
|
||||
|
||||
ConstNode(float c_)
|
||||
: c(c_) {}
|
||||
|
||||
virtual float eval(void)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
struct BinopNode : Node
|
||||
{
|
||||
Node * left, * right;
|
||||
|
||||
BinopNode(Node * left_, Node * right_)
|
||||
: left(left_), right(right_)
|
||||
{}
|
||||
};
|
||||
|
||||
struct AddNode : BinopNode
|
||||
{
|
||||
AddNode(Node * left_, Node * right_)
|
||||
: BinopNode(left_, right_)
|
||||
{}
|
||||
|
||||
virtual float eval(void)
|
||||
{
|
||||
return left->eval() + right->eval();
|
||||
}
|
||||
};
|
||||
|
||||
struct SubNode : BinopNode
|
||||
{
|
||||
SubNode(Node * left_, Node * right_)
|
||||
: BinopNode(left_, right_)
|
||||
{}
|
||||
|
||||
virtual float eval(void)
|
||||
{
|
||||
return left->eval() - right->eval();
|
||||
}
|
||||
};
|
||||
|
||||
struct MulNode : BinopNode
|
||||
{
|
||||
MulNode(Node * left_, Node * right_)
|
||||
: BinopNode(left_, right_)
|
||||
{}
|
||||
|
||||
virtual float eval(void)
|
||||
{
|
||||
return left->eval() * right->eval();
|
||||
}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Node * n =
|
||||
new SubNode(
|
||||
new MulNode(new ConstNode(4), new ConstNode(5)),
|
||||
new AddNode(new ConstNode(12), new ConstNode(7)));
|
||||
|
||||
assert(n->eval() == 1.0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#include <assert.h>
|
||||
|
||||
int a, b, c;
|
||||
|
||||
struct A
|
||||
{
|
||||
A(void)
|
||||
{
|
||||
a++;
|
||||
}
|
||||
|
||||
virtual ~A(void)
|
||||
{
|
||||
a--;
|
||||
}
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
B(void)
|
||||
{
|
||||
b++;
|
||||
}
|
||||
|
||||
virtual ~B(void)
|
||||
{
|
||||
b--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct C : B
|
||||
{
|
||||
C(void)
|
||||
{
|
||||
c++;
|
||||
}
|
||||
|
||||
virtual ~C(void)
|
||||
{
|
||||
c--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
A * t[3];
|
||||
|
||||
t[0] = new A();
|
||||
t[1] = new B();
|
||||
t[2] = new C();
|
||||
|
||||
assert(a == 3 && b == 2 && c == 1);
|
||||
|
||||
delete t[0];
|
||||
delete t[1];
|
||||
delete t[2];
|
||||
|
||||
assert(a == 0 && b == 0 && c == 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
#include "sidfx.h"
|
||||
|
||||
enum SIDFXState
|
||||
{
|
||||
SIDFX_IDLE,
|
||||
SIDFX_RESET_0,
|
||||
SIDFX_RESET_1,
|
||||
SIDFX_READY,
|
||||
SIDFX_PLAY,
|
||||
SIDFX_WAIT
|
||||
};
|
||||
|
||||
__striped static struct SIDFXChannel
|
||||
{
|
||||
const SIDFX * volatile com;
|
||||
byte delay, priority;
|
||||
volatile byte cnt;
|
||||
volatile SIDFXState state;
|
||||
unsigned freq, pwm;
|
||||
|
||||
} channels[3];
|
||||
|
||||
void sidfx_init(void)
|
||||
{
|
||||
for(char i=0; i<3; i++)
|
||||
{
|
||||
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;
|
||||
|
||||
if (ns == SIDFX_IDLE)
|
||||
ns = SIDFX_READY;
|
||||
else if (channels[chn].priority <= fx->priority)
|
||||
ns = SIDFX_RESET_0;
|
||||
else
|
||||
return;
|
||||
|
||||
channels[chn].state = SIDFX_IDLE;
|
||||
channels[chn].delay = 1;
|
||||
|
||||
channels[chn].com = fx;
|
||||
channels[chn].cnt = cnt - 1;
|
||||
channels[chn].priority = fx->priority;
|
||||
|
||||
channels[chn].state = ns;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (channels[ch].state)
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
|
||||
channels[ch].delay--;
|
||||
if (channels[ch].delay)
|
||||
{
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
}
|
||||
|
||||
while (!channels[ch].delay)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
{
|
||||
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;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sidfx_loop_2(void)
|
||||
{
|
||||
sidfx_loop_ch(2);
|
||||
}
|
||||
|
||||
void sidfx_loop(void)
|
||||
{
|
||||
for(byte ch=0; ch<3; ch++)
|
||||
sidfx_loop_ch(ch);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef SIDFX_H
|
||||
#define SIDFX_H
|
||||
|
||||
#include <c64/sid.h>
|
||||
|
||||
struct SIDFX
|
||||
{
|
||||
unsigned freq, pwm;
|
||||
byte ctrl, attdec, susrel;
|
||||
int dfreq, dpwm;
|
||||
byte time1, time0;
|
||||
byte priority;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
#pragma compile("sidfx.c")
|
||||
|
||||
#endif
|
|
@ -0,0 +1,84 @@
|
|||
#include "bank1.h"
|
||||
#include "mmu.h"
|
||||
#include <string.h>
|
||||
|
||||
void bnk1_init(void)
|
||||
{
|
||||
mmu.cr = 0x3e;
|
||||
memcpy((char *)0xfc00, (char *)0xf000, 0x0300);
|
||||
xmmu.rcr |= 0x0c;
|
||||
mmu.cr = 0x3f;
|
||||
}
|
||||
|
||||
#pragma code(bnk1code)
|
||||
|
||||
char bnk1_readb(volatile char * p)
|
||||
{
|
||||
mmu.bank1 = 0;
|
||||
char c = *p;
|
||||
mmu.bank0 = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
unsigned bnk1_readw(volatile unsigned * p)
|
||||
{
|
||||
mmu.bank1 = 0;
|
||||
unsigned w = *p;
|
||||
mmu.bank0 = 1;
|
||||
return w;
|
||||
}
|
||||
|
||||
unsigned long bnk1_readl(volatile unsigned long * p)
|
||||
{
|
||||
mmu.bank1 = 0;
|
||||
unsigned long l = *p;
|
||||
mmu.bank0 = 3;
|
||||
return l;
|
||||
}
|
||||
|
||||
void bnk1_readm(char * dp, volatile char * sp, unsigned size)
|
||||
{
|
||||
while (size > 0)
|
||||
{
|
||||
mmu.bank1 = 0;
|
||||
char c = * sp++;
|
||||
mmu.bank0 = c;
|
||||
*dp++ = c;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
|
||||
void bnk1_writeb(volatile char * p, char b)
|
||||
{
|
||||
mmu.bank1 = b;
|
||||
*p = b;
|
||||
mmu.bank0 = b;
|
||||
}
|
||||
|
||||
void bnk1_writew(volatile unsigned * p, unsigned w)
|
||||
{
|
||||
mmu.bank1 = w;
|
||||
*p = w;
|
||||
mmu.bank0 = w;
|
||||
}
|
||||
|
||||
void bnk1_writel(volatile unsigned long * p, unsigned long l)
|
||||
{
|
||||
mmu.bank1 = l;
|
||||
*p = l;
|
||||
mmu.bank0 = l;
|
||||
}
|
||||
|
||||
void bnk1_writem(volatile char * dp, const char * sp, unsigned size)
|
||||
{
|
||||
while (size > 0)
|
||||
{
|
||||
char c = * sp++;
|
||||
mmu.bank1 = c;
|
||||
*dp++ = c;
|
||||
mmu.bank0 = c;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma code(code)
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef C128_BANK1_H
|
||||
#define C128_BANK1_H
|
||||
|
||||
|
||||
#pragma section( bnk1code, 0)
|
||||
|
||||
#pragma region( bnk1code, 0xf000, 0xf300, , , {bnk1code}, 0xfc00 )
|
||||
|
||||
void bnk1_init(void);
|
||||
|
||||
#pragma code(bnk1code)
|
||||
|
||||
__noinline char bnk1_readb(volatile char * p);
|
||||
|
||||
__noinline unsigned bnk1_readw(volatile unsigned * p);
|
||||
|
||||
__noinline unsigned long bnk1_readl(volatile unsigned long * p);
|
||||
|
||||
__noinline void bnk1_readm(char * dp, volatile char * sp, unsigned size);
|
||||
|
||||
|
||||
__noinline void bnk1_writeb(volatile char * p, char b);
|
||||
|
||||
__noinline void bnk1_writew(volatile unsigned * p, unsigned w);
|
||||
|
||||
__noinline void bnk1_writel(volatile unsigned long * p, unsigned long l);
|
||||
|
||||
__noinline void bnk1_writem(volatile char * dp, const char * sp, unsigned size);
|
||||
|
||||
#pragma code(code)
|
||||
|
||||
#pragma compile("bank1.c")
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
#include "mmu.h"
|
||||
|
||||
inline char mmu_set(char cr)
|
||||
{
|
||||
char pcr = mmu.cr;
|
||||
mmu.cr = cr;
|
||||
return pcr;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef C128_MMU_H
|
||||
#define C128_MMU_H
|
||||
|
||||
#include <c64/types.h>
|
||||
|
||||
struct MMU
|
||||
{
|
||||
volatile byte cr;
|
||||
volatile byte bank0;
|
||||
volatile byte bank1;
|
||||
volatile byte bank14;
|
||||
volatile byte bankx;
|
||||
};
|
||||
|
||||
struct XMMU
|
||||
{
|
||||
volatile byte cr;
|
||||
volatile byte pcr[4];
|
||||
volatile byte mcr;
|
||||
volatile byte rcr;
|
||||
volatile word page0;
|
||||
volatile word page1;
|
||||
volatile byte vr;
|
||||
};
|
||||
|
||||
#define mmu (*((struct MMU *)0xff00))
|
||||
|
||||
#define xmmu (*((struct XMMU *)0xd500))
|
||||
|
||||
inline char mmu_set(char cr);
|
||||
|
||||
#pragma compile("mmu.c")
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#include "vdc.h"
|
||||
|
||||
|
||||
inline void vdc_reg(VDCRegister reg)
|
||||
{
|
||||
vdc.addr = reg;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void vdc_reg_write(VDCRegister reg, byte data)
|
||||
{
|
||||
vdc_reg(reg);
|
||||
vdc_write(data);
|
||||
}
|
||||
|
||||
byte vdc_reg_read(VDCRegister reg)
|
||||
{
|
||||
vdc_reg(reg);
|
||||
return vdc_read();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
inline void vdc_mem_write(char data)
|
||||
{
|
||||
vdc_write(data);
|
||||
}
|
||||
|
||||
inline char vdc_mem_read(void)
|
||||
{
|
||||
return vdc_read();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void vdc_mem_write_buffer(unsigned addr, const char * data, char size)
|
||||
{
|
||||
vdc_mem_addr(addr);
|
||||
for(char i=0; i<size; i++)
|
||||
vdc_write(data[i]);
|
||||
}
|
||||
|
||||
void vdc_mem_read_buffer(unsigned addr, char * data, char size)
|
||||
{
|
||||
vdc_mem_addr(addr);
|
||||
for(char i=0; i<size; i++)
|
||||
data[i] = vdc_read();
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
#ifndef C128_VDC_H
|
||||
#define C128_VDC_H
|
||||
|
||||
#include <c64/types.h>
|
||||
|
||||
enum VDCRegister
|
||||
{
|
||||
VDCR_HTOTAL,
|
||||
VDCR_HDISPLAY,
|
||||
VDCR_HSYNC,
|
||||
VDCR_SYNCSIZE,
|
||||
|
||||
VDCR_VTOTAL,
|
||||
VDCR_VADJUST,
|
||||
VDCR_VDISPLAY,
|
||||
VDCR_VSYNC,
|
||||
|
||||
VDCR_LACE,
|
||||
VDCR_CSIZE,
|
||||
VDCR_CURSOR_START,
|
||||
VDCR_CURSOR_END,
|
||||
|
||||
VDCR_DISP_ADDRH,
|
||||
VDCR_DISP_ADDRL,
|
||||
VDCR_CURSOR_ADDRH,
|
||||
VDCR_CURSOR_ADDRL,
|
||||
|
||||
VDCR_LPEN_Y,
|
||||
VDCR_LPEN_X,
|
||||
VDCR_ADDRH,
|
||||
VDCR_ADDRL,
|
||||
|
||||
VDCR_ATTR_ADDRH,
|
||||
VDCR_ATTR_ADDRL,
|
||||
VDCR_CWIDTH,
|
||||
VDCR_CHEIGHT,
|
||||
|
||||
VDCR_VSCROLL,
|
||||
VDCR_HSCROLL,
|
||||
VDCR_COLOR,
|
||||
VDCR_ROWINC,
|
||||
|
||||
VDCR_CHAR_ADDRH,
|
||||
VDCR_UNDERLINE,
|
||||
VDCR_DSIZE,
|
||||
VDCR_DATA,
|
||||
|
||||
VDCR_BLOCK_ADDRH,
|
||||
VDCR_BLOCK_ADDRL,
|
||||
VDCR_HSTART,
|
||||
VDCR_HEND,
|
||||
|
||||
VDCR_REFRESH
|
||||
};
|
||||
|
||||
struct VDC
|
||||
{
|
||||
volatile char addr;
|
||||
volatile char data;
|
||||
};
|
||||
|
||||
#define vdc (*((struct VDC *)0xd600))
|
||||
|
||||
inline void vdc_reg(VDCRegister reg);
|
||||
|
||||
inline void vdc_write(byte data);
|
||||
|
||||
inline byte vdc_read(void);
|
||||
|
||||
|
||||
void vdc_reg_write(VDCRegister reg, byte data);
|
||||
|
||||
byte vdc_reg_read(VDCRegister reg);
|
||||
|
||||
|
||||
void vdc_mem_addr(unsigned addr);
|
||||
|
||||
inline void vdc_mem_write(char data);
|
||||
|
||||
inline char vdc_mem_read(void);
|
||||
|
||||
|
||||
void vdc_mem_write_at(unsigned addr, char data);
|
||||
|
||||
char vdc_mem_read_at(unsigned addr);
|
||||
|
||||
|
||||
void vdc_mem_write_buffer(unsigned addr, const char * data, char size);
|
||||
|
||||
void vdc_mem_read_buffer(unsigned addr, char * data, char size);
|
||||
|
||||
|
||||
#pragma compile("vdc.c")
|
||||
|
||||
#endif
|
|
@ -19,10 +19,10 @@ inline byte asm_zp(byte * ip, AsmIns ins, byte addr)
|
|||
return 2;
|
||||
}
|
||||
|
||||
inline byte asm_rl(byte * ip, AsmIns ins, byte addr)
|
||||
inline byte asm_rl(byte * ip, AsmIns ins, sbyte addr)
|
||||
{
|
||||
ip[0] = ins & 0xff;
|
||||
ip[1] = addr;
|
||||
ip[1] = (byte)addr;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ inline byte asm_ac(byte * ip, AsmIns ins);
|
|||
inline byte asm_zp(byte * ip, AsmIns ins, byte addr);
|
||||
|
||||
// relative branch
|
||||
inline byte asm_rl(byte * ip, AsmIns ins, byte addr);
|
||||
inline byte asm_rl(byte * ip, AsmIns ins, sbyte addr);
|
||||
|
||||
// immediate
|
||||
inline byte asm_im(byte * ip, AsmIns ins, byte value);
|
||||
|
|
|
@ -9,7 +9,7 @@ static const unsigned mul40[25] = {
|
|||
800, 840, 880, 920, 960
|
||||
};
|
||||
|
||||
static void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
||||
static __native inline void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
||||
{
|
||||
for(char i=0; i<n; i++)
|
||||
{
|
||||
|
@ -18,9 +18,7 @@ static void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp,
|
|||
}
|
||||
}
|
||||
|
||||
#pragma native(copy_fwd)
|
||||
|
||||
static void fill_fwd(char * sdp, char * cdp, char ch, char color, char n)
|
||||
static __native inline void fill_fwd(char * sdp, char * cdp, char ch, char color, char n)
|
||||
{
|
||||
for(char i=0; i<n; i++)
|
||||
{
|
||||
|
@ -29,9 +27,7 @@ static void fill_fwd(char * sdp, char * cdp, char ch, char color, char n)
|
|||
}
|
||||
}
|
||||
|
||||
#pragma native(fill_fwd)
|
||||
|
||||
static void copy_bwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
||||
static __native inline void copy_bwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
||||
{
|
||||
while (n)
|
||||
{
|
||||
|
@ -41,9 +37,6 @@ static void copy_bwd(char * sdp, const char * ssp, char * cdp, const char * csp,
|
|||
}
|
||||
}
|
||||
|
||||
#pragma native(copy_bwd)
|
||||
|
||||
|
||||
|
||||
void cwin_init(CharWin * win, char * screen, char sx, char sy, char wx, char wy)
|
||||
{
|
||||
|
@ -181,17 +174,19 @@ bool cwin_cursor_backward(CharWin * win)
|
|||
return false;
|
||||
}
|
||||
|
||||
static char p2smap[] = {0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x40, 0x60};
|
||||
static char s2pmap[] = {0x40, 0x20, 0x60, 0xb0, 0x40, 0x20, 0x60, 0xb0};
|
||||
//static char p2smap[] = {0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x40, 0x60};
|
||||
static char p2smap[] = {0x00, 0x00, 0x40, 0x20, 0x80, 0xc0, 0x80, 0x80};
|
||||
//static char s2pmap[] = {0x40, 0x20, 0x60, 0xa0, 0x40, 0x20, 0x60, 0xa0};
|
||||
static char s2pmap[] = {0x40, 0x00, 0x20, 0xc0, 0xc0, 0x80, 0xa0, 0x40};
|
||||
|
||||
static inline char p2s(char ch)
|
||||
{
|
||||
return (ch & 0x1f) | p2smap[ch >> 5];
|
||||
return ch ^ p2smap[ch >> 5];
|
||||
}
|
||||
|
||||
static inline char s2p(char ch)
|
||||
{
|
||||
return (ch & 0x1f) | s2pmap[ch >> 5];
|
||||
return ch ^ s2pmap[ch >> 5];
|
||||
}
|
||||
|
||||
void cwin_read_string(CharWin * win, char * buffer)
|
||||
|
@ -289,6 +284,17 @@ void cwin_put_chars_raw(CharWin * win, const char * chars, char num, char color)
|
|||
}
|
||||
}
|
||||
|
||||
char cwin_put_string_raw(CharWin * win, const char * str, char color)
|
||||
{
|
||||
char n = cwin_putat_string_raw(win, win->cx, win->cy, str, color);
|
||||
win->cx += n;
|
||||
if (win->cx >= win->wx)
|
||||
{
|
||||
win->cx = 0;
|
||||
win->cy++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -340,7 +346,6 @@ char cwin_putat_string(CharWin * win, char x, char y, const char * str, char col
|
|||
|
||||
#pragma native(cwin_putat_string)
|
||||
|
||||
|
||||
void cwin_putat_char_raw(CharWin * win, char x, char y, char ch, char color)
|
||||
{
|
||||
int offset = mul40[y] + x;
|
||||
|
@ -369,6 +374,25 @@ void cwin_putat_chars_raw(CharWin * win, char x, char y, const char * chars, cha
|
|||
|
||||
#pragma native(cwin_putat_chars_raw)
|
||||
|
||||
char cwin_putat_string_raw(CharWin * win, char x, char y, const char * str, char color)
|
||||
{
|
||||
int offset = mul40[y] + x;
|
||||
|
||||
char * sp = win->sp + offset;
|
||||
char * cp = win->cp + offset;
|
||||
|
||||
char i = 0;
|
||||
while (char ch = str[i])
|
||||
{
|
||||
sp[i] = ch;
|
||||
cp[i] = color;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#pragma native(cwin_putat_string_raw)
|
||||
|
||||
char cwin_getat_char(CharWin * win, char x, char y)
|
||||
{
|
||||
|
@ -398,7 +422,7 @@ char cwin_getat_char_raw(CharWin * win, char x, char y)
|
|||
return *sp;
|
||||
}
|
||||
|
||||
#pragma native(cwin_getat_char_raw)
|
||||
#pragma native(cwin_getat_chars_raw)
|
||||
|
||||
void cwin_getat_chars_raw(CharWin * win, char x, char y, char * chars, char num)
|
||||
{
|
||||
|
@ -410,6 +434,98 @@ void cwin_getat_chars_raw(CharWin * win, char x, char y, char * chars, char num)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma native(cwin_put_rect_raw)
|
||||
|
||||
void cwin_put_rect_raw(CharWin * win, char x, char y, char w, char h, const char * chars, char color)
|
||||
{
|
||||
int offset = mul40[y] + x;
|
||||
|
||||
char * sp = win->sp + offset;
|
||||
char * cp = win->cp + offset;
|
||||
|
||||
for(char i=0; i<h; i++)
|
||||
{
|
||||
|
||||
for(char j=0; j<w; j++)
|
||||
{
|
||||
sp[j] = chars[j];
|
||||
cp[j] = color;
|
||||
}
|
||||
|
||||
chars += w;
|
||||
sp += 40;
|
||||
cp += 40;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(cwin_put_rect)
|
||||
|
||||
void cwin_put_rect(CharWin * win, char x, char y, char w, char h, const char * chars, char color)
|
||||
{
|
||||
int offset = mul40[y] + x;
|
||||
|
||||
char * sp = win->sp + offset;
|
||||
char * cp = win->cp + offset;
|
||||
|
||||
for(char i=0; i<h; i++)
|
||||
{
|
||||
|
||||
for(char j=0; j<w; j++)
|
||||
{
|
||||
sp[j] = p2s(chars[j]);
|
||||
cp[j] = color;
|
||||
}
|
||||
|
||||
chars += w;
|
||||
sp += 40;
|
||||
cp += 40;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(cwin_get_rect_raw)
|
||||
|
||||
void cwin_get_rect_raw(CharWin * win, char x, char y, char w, char h, char * chars)
|
||||
{
|
||||
int offset = mul40[y] + x;
|
||||
|
||||
char * sp = win->sp + offset;
|
||||
|
||||
for(char i=0; i<h; i++)
|
||||
{
|
||||
|
||||
for(char j=0; j<w; j++)
|
||||
{
|
||||
chars[j] = sp[j];
|
||||
}
|
||||
|
||||
chars += w;
|
||||
sp += 40;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(cwin_get_rect)
|
||||
|
||||
void cwin_get_rect(CharWin * win, char x, char y, char w, char h, char * chars)
|
||||
{
|
||||
int offset = mul40[y] + x;
|
||||
|
||||
char * sp = win->sp + offset;
|
||||
|
||||
for(char i=0; i<h; i++)
|
||||
{
|
||||
|
||||
for(char j=0; j<w; j++)
|
||||
{
|
||||
chars[j] = s2p(sp[j]);
|
||||
}
|
||||
|
||||
chars += w;
|
||||
sp += 40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma native(cwin_getat_chars_raw)
|
||||
|
||||
void cwin_insert_char(CharWin * win)
|
||||
|
@ -479,6 +595,18 @@ int cwin_getch(void)
|
|||
}
|
||||
}
|
||||
|
||||
int cwin_checkch(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
L1:
|
||||
jsr 0xffe4
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
}
|
||||
|
||||
bool cwin_edit_char(CharWin * win, char ch)
|
||||
{
|
||||
switch (ch)
|
||||
|
|
|
@ -71,6 +71,10 @@ void cwin_put_char_raw(CharWin * win, char ch, char color);
|
|||
//
|
||||
void cwin_put_chars_raw(CharWin * win, const char * chars, char num, char color);
|
||||
|
||||
// Put a zero terminated raw string at the cursor location and advance the cursor
|
||||
//
|
||||
char cwin_put_string_raw(CharWin * win, const char * str, char color);
|
||||
|
||||
|
||||
|
||||
// Put a single char at the given window location
|
||||
|
@ -94,6 +98,10 @@ void cwin_putat_char_raw(CharWin * win, char x, char y, char ch, char color);
|
|||
//
|
||||
void cwin_putat_chars_raw(CharWin * win, char x, char y, const char * chars, char num, char color);
|
||||
|
||||
// Put a zero terminated string at the given window location
|
||||
//
|
||||
char cwin_putat_string_raw(CharWin * win, char x, char y, const char * str, char color);
|
||||
|
||||
|
||||
// Get a single char at the given window location
|
||||
//
|
||||
|
@ -114,6 +122,17 @@ char cwin_getat_char_raw(CharWin * win, char x, char y);
|
|||
void cwin_getat_chars_raw(CharWin * win, char x, char y, char * chars, char num);
|
||||
|
||||
|
||||
// Put an array of characters into a rectangle in the char win
|
||||
void cwin_put_rect_raw(CharWin * win, char x, char y, char w, char h, const char * chars, char color);
|
||||
|
||||
void cwin_put_rect(CharWin * win, char x, char y, char w, char h, const char * chars, char color);
|
||||
|
||||
// Get an array of characters from a rectangle of a char win
|
||||
void cwin_get_rect_raw(CharWin * win, char x, char y, char w, char h, char * chars);
|
||||
|
||||
void cwin_get_rect(CharWin * win, char x, char y, char w, char h, char * chars);
|
||||
|
||||
|
||||
|
||||
// Insert one space character at the cursor position
|
||||
//
|
||||
|
@ -125,6 +144,8 @@ void cwin_delete_char(CharWin * win);
|
|||
|
||||
int cwin_getch(void);
|
||||
|
||||
int cwin_checkch(void);
|
||||
|
||||
// Edit the window position using the char as the input
|
||||
//
|
||||
bool cwin_edit_char(CharWin * win, char ch);
|
||||
|
@ -150,6 +171,8 @@ inline void cwin_fill_rect(CharWin * win, char x, char y, char w, char h, char c
|
|||
//
|
||||
void cwin_fill_rect_raw(CharWin * win, char x, char y, char w, char h, char ch, char color);
|
||||
|
||||
|
||||
#pragma compile("charwin.c")
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "cia.h"
|
||||
|
||||
byte ciaa_pra_def;
|
||||
|
||||
void cia_init(void)
|
||||
{
|
||||
cia1.icr = 0x7f;
|
||||
|
@ -14,6 +16,11 @@ void cia_init(void)
|
|||
cia2.ddrb = 0x00;
|
||||
cia1.ddra = 0xff;
|
||||
|
||||
cia2.prb = 0x07;
|
||||
cia2.pra = 0x07;
|
||||
cia2.ddra = 0x3f;
|
||||
|
||||
char i0 = cia1.icr;
|
||||
char i1 = cia2.icr;
|
||||
|
||||
ciaa_pra_def = 0x7f;
|
||||
}
|
||||
|
|
|
@ -6,17 +6,19 @@
|
|||
struct CIA
|
||||
{
|
||||
volatile byte pra, prb;
|
||||
byte ddra, ddrb;
|
||||
word ta, tb;
|
||||
byte todt, tods, todm, todh;
|
||||
byte sdr;
|
||||
byte icr;
|
||||
byte cra, crb;
|
||||
volatile byte ddra, ddrb;
|
||||
volatile word ta, tb;
|
||||
volatile byte todt, tods, todm, todh;
|
||||
volatile byte sdr;
|
||||
volatile byte icr;
|
||||
volatile byte cra, crb;
|
||||
};
|
||||
|
||||
#define cia1 (*((struct CIA *)0xdc00))
|
||||
#define cia2 (*((struct CIA *)0xdd00))
|
||||
|
||||
extern byte ciaa_pra_def;
|
||||
|
||||
void cia_init(void);
|
||||
|
||||
#pragma compile("cia.c")
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
struct EasyFlash
|
||||
{
|
||||
byte bank;
|
||||
byte pad1;
|
||||
byte control;
|
||||
volatile byte bank;
|
||||
byte pad1;
|
||||
volatile byte control;
|
||||
};
|
||||
|
||||
#define EFCTRL_GAME 0x01
|
||||
|
@ -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
|
|
@ -0,0 +1,353 @@
|
|||
#include "iecbus.h"
|
||||
#include <c64/cia.h>
|
||||
#include <c64/vic.h>
|
||||
|
||||
IEC_STATUS iec_status;
|
||||
char iec_queue;
|
||||
|
||||
#define CIA2B_ATNOUT 0x08
|
||||
#define CIA2B_CLKOUT 0x10
|
||||
#define CIA2B_DATAOUT 0x20
|
||||
|
||||
#define CIA2B_CLKIN 0x40
|
||||
#define CIA2B_DATAIN 0x80
|
||||
|
||||
#pragma optimize(push)
|
||||
#pragma optimize(1)
|
||||
|
||||
// multiples of 5us
|
||||
static void delay(char n)
|
||||
{
|
||||
__asm {
|
||||
ldx n
|
||||
l1:
|
||||
dex
|
||||
bne l1
|
||||
}
|
||||
}
|
||||
|
||||
static inline void data_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_DATAOUT;
|
||||
}
|
||||
|
||||
static inline void data_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
}
|
||||
|
||||
static inline void clock_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_CLKOUT;
|
||||
}
|
||||
|
||||
static inline void cdata_true(void)
|
||||
{
|
||||
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
|
||||
}
|
||||
|
||||
static inline void clock_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_CLKOUT;
|
||||
}
|
||||
|
||||
static inline void atn_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_ATNOUT;
|
||||
}
|
||||
|
||||
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 = 200;
|
||||
while (cnt > 0 && data_in())
|
||||
{
|
||||
delay(5);
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (cnt)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
iec_status = IEC_DATA_CHECK;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool iec_eoib(void)
|
||||
{
|
||||
clock_true();
|
||||
|
||||
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)
|
||||
{
|
||||
if (iec_status == IEC_QUEUED)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
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 (!clock_in());
|
||||
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
data_true();
|
||||
|
||||
char cnt = 100;
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
iec_status = IEC_EOF;
|
||||
data_false();
|
||||
delay(10);
|
||||
data_true();
|
||||
|
||||
cnt = 200;
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
iec_status = IEC_TIMEOUT;
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
char b = 0;
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
char c;
|
||||
while (!((c = cia2.pra) & CIA2B_CLKIN))
|
||||
;
|
||||
|
||||
b >>= 1;
|
||||
b |= c & 0x80;
|
||||
|
||||
while (cia2.pra & CIA2B_CLKIN)
|
||||
;
|
||||
}
|
||||
|
||||
data_false();
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void iec_atn(char dev, char sec)
|
||||
{
|
||||
clock_true();
|
||||
data_true();
|
||||
atn_false();
|
||||
clock_false();
|
||||
|
||||
delay(200);
|
||||
|
||||
while (data_in());
|
||||
|
||||
iec_writeb(dev);
|
||||
data_check();
|
||||
if (sec != 0xff)
|
||||
{
|
||||
iec_writeb(sec);
|
||||
data_check();
|
||||
}
|
||||
|
||||
atn_true();
|
||||
}
|
||||
|
||||
|
||||
void iec_talk(char dev, char sec)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
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)
|
||||
{
|
||||
iec_atn(0x5f, 0xff);
|
||||
}
|
||||
|
||||
void iec_listen(char dev, char sec)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
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)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x20, sec | 0xf0);
|
||||
|
||||
char i = 0;
|
||||
while (fname[i])
|
||||
{
|
||||
iec_write(fname[i]);
|
||||
i++;
|
||||
}
|
||||
iec_unlisten();
|
||||
}
|
||||
|
||||
void iec_close(char dev, char sec)
|
||||
{
|
||||
iec_atn(dev | 0x20, sec | 0xe0);
|
||||
iec_unlisten();
|
||||
}
|
||||
|
||||
int iec_write_bytes(const char * data, int num)
|
||||
{
|
||||
for(int i=0; i<num; i++)
|
||||
{
|
||||
if (!iec_write(data[i]))
|
||||
return i;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
int iec_read_bytes(char * data, int num)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
#pragma optimize(pop)
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef C64_IECBUS_H
|
||||
#define C64_IECBUS_H
|
||||
|
||||
enum IEC_STATUS
|
||||
{
|
||||
IEC_OK = 0x00,
|
||||
IEC_EOF = 0x01,
|
||||
IEC_QUEUED = 0x02,
|
||||
|
||||
IEC_ERROR = 0x80,
|
||||
IEC_TIMEOUT,
|
||||
IEC_DATA_CHECK,
|
||||
};
|
||||
|
||||
extern IEC_STATUS iec_status;
|
||||
|
||||
bool iec_write(char b);
|
||||
|
||||
char iec_read(void);
|
||||
|
||||
void iec_atn(char dev, char sec);
|
||||
|
||||
void iec_talk(char dev, char sec);
|
||||
|
||||
void iec_untalk(void);
|
||||
|
||||
void iec_listen(char dev, char sec);
|
||||
|
||||
void iec_unlisten(void);
|
||||
|
||||
void iec_open(char dev, char sec, const char * fname);
|
||||
|
||||
void iec_close(char dev, char sec);
|
||||
|
||||
int iec_write_bytes(const char * data, int num);
|
||||
|
||||
int iec_read_bytes(char * data, int num);
|
||||
|
||||
|
||||
#pragma compile("iecbus.c")
|
||||
|
||||
#endif
|
||||
|
|
@ -5,7 +5,7 @@ bool joyb[2];
|
|||
|
||||
void joy_poll(char n)
|
||||
{
|
||||
char b = ((char *)0xdc00)[n];
|
||||
char b = ((volatile char *)0xdc00)[n];
|
||||
|
||||
if (!(b & 1))
|
||||
joyy[n] = -1;
|
||||
|
|
|
@ -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)
|
||||
|
@ -274,6 +354,66 @@ int krnio_read(char fnum, char * data, int num)
|
|||
|
||||
#pragma native(krnio_read)
|
||||
|
||||
int krnio_read_lzo(char fnum, char * data)
|
||||
{
|
||||
if (krnio_pstatus[fnum] == KRNIO_EOF)
|
||||
return 0;
|
||||
|
||||
if (krnio_chkin(fnum))
|
||||
{
|
||||
int i = 0;
|
||||
char ch;
|
||||
char cmd = 0;
|
||||
krnioerr err;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ch = krnio_chrin();
|
||||
err = krnio_status();
|
||||
if (err && err != KRNIO_EOF)
|
||||
break;
|
||||
|
||||
if (cmd & 0x80)
|
||||
{
|
||||
|
||||
char * dp = data + i, * cp = dp - ch;
|
||||
|
||||
cmd &= 0x7f;
|
||||
i += cmd;
|
||||
|
||||
char n = 0x00;
|
||||
do {
|
||||
dp[n] = cp[n];
|
||||
n++;
|
||||
} while (n != cmd);
|
||||
cmd = 0;
|
||||
}
|
||||
else if (cmd)
|
||||
{
|
||||
data[i++] = (char)ch;
|
||||
cmd--;
|
||||
}
|
||||
else if (ch)
|
||||
cmd = ch;
|
||||
else
|
||||
break;
|
||||
|
||||
if (err)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
krnio_pstatus[fnum] = err;
|
||||
|
||||
krnio_clrchn();
|
||||
return i;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#pragma native(krnio_read_lzo)
|
||||
|
||||
int krnio_gets(char fnum, char * data, int num)
|
||||
{
|
||||
if (krnio_pstatus[fnum] == KRNIO_EOF)
|
||||
|
@ -281,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
|
||||
|
@ -81,6 +90,8 @@ int krnio_puts(char fnum, const char * data);
|
|||
|
||||
int krnio_read(char fnum, char * data, int num);
|
||||
|
||||
int krnio_read_lzo(char fnum, char * data);
|
||||
|
||||
// read a line from the given file, terminated by a CR or LF character
|
||||
// and appends a zero byte.
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ const char keyb_codes[128] = {
|
|||
'7', 'y', 'g', '8', 'b', 'h', 'u', 'v',
|
||||
'9', 'i', 'j', '0', 'm', 'k', 'o', 'n',
|
||||
'+', 'p', 'l', '-', '.', ':', '@', ',',
|
||||
0 , '*', ';', 0, 0, '=', '^', '/',
|
||||
'1', 0, 0, '2', ' ', 0, 'q', KEY_ESC,
|
||||
0 , '*', ';', KEY_HOME, 0, '=', '^', '/',
|
||||
'1', KEY_ARROW_LEFT, 0, '2', ' ', 0, 'q', KEY_ESC,
|
||||
|
||||
KEY_INST, KEY_RETURN, KEY_CSR_LEFT, KEY_F8, KEY_F2, KEY_F4, KEY_F6, KEY_CSR_UP,
|
||||
'#', 'W', 'A', '$', 'Z', 'S', 'E', 0,
|
||||
|
@ -17,16 +17,18 @@ const char keyb_codes[128] = {
|
|||
'\'', 'Y', 'G', '(', 'B', 'H', 'U', 'V',
|
||||
')', 'I', 'J', '0', 'M', 'K', 'O', 'N',
|
||||
0, 'P', 'L', 0, '>', '[', '@', '<',
|
||||
0, 0, ']', 0, 0, 0, '^', '?',
|
||||
0, 0, ']', KEY_CLR, 0, 0, '^', '?',
|
||||
'!', 0, 0, '"', ' ', 0, 'Q', KEY_ESC,
|
||||
|
||||
};
|
||||
|
||||
|
||||
byte keyb_matrix[8], keyb_key;
|
||||
byte keyb_matrix[8];
|
||||
|
||||
KeyScanCode keyb_key;
|
||||
static byte keyb_pmatrix[8];
|
||||
|
||||
bool key_pressed(char code)
|
||||
bool key_pressed(KeyScanCode code)
|
||||
{
|
||||
return !(keyb_matrix[code >> 3] & (1 << (code & 7)));
|
||||
}
|
||||
|
@ -41,6 +43,7 @@ bool key_shift(void)
|
|||
void keyb_poll(void)
|
||||
{
|
||||
cia1.ddra = 0xff;
|
||||
cia1.pra = 0xff;
|
||||
keyb_key = 0x00;
|
||||
|
||||
if (cia1.prb == 0xff)
|
||||
|
@ -93,5 +96,5 @@ void keyb_poll(void)
|
|||
}
|
||||
}
|
||||
|
||||
cia1.pra = 0xff;
|
||||
cia1.pra = ciaa_pra_def;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,16 @@
|
|||
#define KEY_CSR_UP (17 + 128)
|
||||
#define KEY_CSR_LEFT (29 + 128)
|
||||
|
||||
#define KEY_ARROW_LEFT (95)
|
||||
|
||||
#define KEY_ESC (27)
|
||||
#define KEY_DEL (20)
|
||||
#define KEY_INST (148)
|
||||
#define KEY_RETURN (13)
|
||||
|
||||
#define KEY_HOME (19)
|
||||
#define KEY_CLR (147)
|
||||
|
||||
#define KEY_F1 (133)
|
||||
#define KEY_F3 (134)
|
||||
#define KEY_F5 (135)
|
||||
|
@ -23,10 +28,86 @@
|
|||
#define KEY_F6 (139)
|
||||
#define KEY_F8 (140)
|
||||
|
||||
#define KEY_CODE_CSR_RIGHT (2)
|
||||
#define KEY_CODE_CSR_DOWN (7)
|
||||
#define KEY_CODE_LSHIFT (15)
|
||||
#define KEY_CODE_RSHIFT (48)
|
||||
enum KeyScanCode
|
||||
{
|
||||
KSCAN_DEL,
|
||||
KSCAN_RETURN,
|
||||
KSCAN_CSR_RIGHT,
|
||||
KSCAN_F7,
|
||||
KSCAN_F1,
|
||||
KSCAN_F3,
|
||||
KSCAN_F5,
|
||||
KSCAN_CSR_DOWN,
|
||||
|
||||
KSCAN_3,
|
||||
KSCAN_W,
|
||||
KSCAN_A,
|
||||
KSCAN_4,
|
||||
KSCAN_Z,
|
||||
KSCAN_S,
|
||||
KSCAN_E,
|
||||
KSCAN_SHIFT_LOCK,
|
||||
|
||||
KSCAN_5,
|
||||
KSCAN_R,
|
||||
KSCAN_D,
|
||||
KSCAN_6,
|
||||
KSCAN_C,
|
||||
KSCAN_F,
|
||||
KSCAN_T,
|
||||
KSCAN_X,
|
||||
|
||||
KSCAN_7,
|
||||
KSCAN_Y,
|
||||
KSCAN_G,
|
||||
KSCAN_8,
|
||||
KSCAN_B,
|
||||
KSCAN_H,
|
||||
KSCAN_U,
|
||||
KSCAN_V,
|
||||
|
||||
KSCAN_9,
|
||||
KSCAN_I,
|
||||
KSCAN_J,
|
||||
KSCAN_0,
|
||||
KSCAN_M,
|
||||
KSCAN_K,
|
||||
KSCAN_O,
|
||||
KSCAN_N,
|
||||
|
||||
KSCAN_PLUS,
|
||||
KSCAN_P,
|
||||
KSCAN_L,
|
||||
KSCAN_MINUS,
|
||||
KSCAN_DOT,
|
||||
KSCAN_COLON,
|
||||
KSCAN_AT,
|
||||
KSCAN_COMMA,
|
||||
|
||||
KSCAN_POUND,
|
||||
KSCAN_STAR,
|
||||
KSCAN_SEMICOLON,
|
||||
KSCAN_HOME,
|
||||
KSCAN_RSHIFT,
|
||||
KSCAN_EQUAL,
|
||||
KSCAN_ARROW_UP,
|
||||
KSCAN_SLASH,
|
||||
|
||||
KSCAN_1,
|
||||
KSCAN_ARROW_LEFT,
|
||||
KSCAN_CONTROL,
|
||||
KSCAN_2,
|
||||
KSCAN_SPACE,
|
||||
KSCAN_COMMODORE,
|
||||
KSCAN_Q,
|
||||
KSCAN_STOP,
|
||||
|
||||
KSCAN_QUAL_SHIFT = 0x40,
|
||||
KSCAN_QUAL_MASK = 0x7f,
|
||||
KSCAN_QUAL_DOWN = 0x80,
|
||||
|
||||
KSCAN_MAX = 0xff
|
||||
};
|
||||
|
||||
// map of keyboard codes to PETSCII, first 64 without shift
|
||||
// second 64 with shift
|
||||
|
@ -36,14 +117,15 @@ extern const char keyb_codes[128];
|
|||
// current status of key matrix
|
||||
extern byte keyb_matrix[8];
|
||||
|
||||
// current key
|
||||
extern byte keyb_key;
|
||||
// current key in scan code - the top level bit KSCAN_QUAL_DOWN is
|
||||
// used to indicate a key is pressed, so 0 is no key
|
||||
extern KeyScanCode keyb_key;
|
||||
|
||||
// poll keyboard matrix
|
||||
|
||||
void keyb_poll(void);
|
||||
|
||||
inline bool key_pressed(char code);
|
||||
inline bool key_pressed(KeyScanCode code);
|
||||
|
||||
inline bool key_shift(void);
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#include "memmap.h"
|
||||
|
||||
volatile char PLAShadow;
|
||||
|
||||
__asm DoneTrampoline
|
||||
{
|
||||
lda PLAShadow
|
||||
sta $01
|
||||
stx $01
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
|
@ -17,8 +14,6 @@ __asm IRQTrampoline
|
|||
pha
|
||||
txa
|
||||
pha
|
||||
lda #$36
|
||||
sta $01
|
||||
|
||||
lda #>DoneTrampoline
|
||||
pha
|
||||
|
@ -27,7 +22,10 @@ __asm IRQTrampoline
|
|||
tsx
|
||||
lda $0105, x
|
||||
pha
|
||||
jmp ($fffa)
|
||||
ldx $01
|
||||
lda #$36
|
||||
sta $01
|
||||
jmp ($fffe)
|
||||
}
|
||||
|
||||
__asm NMITrampoline
|
||||
|
@ -35,8 +33,6 @@ __asm NMITrampoline
|
|||
pha
|
||||
txa
|
||||
pha
|
||||
lda #$36
|
||||
sta $01
|
||||
|
||||
lda #>DoneTrampoline
|
||||
pha
|
||||
|
@ -45,19 +41,23 @@ __asm NMITrampoline
|
|||
tsx
|
||||
lda $0105, x
|
||||
pha
|
||||
jmp ($fffe)
|
||||
ldx $01
|
||||
lda #$36
|
||||
sta $01
|
||||
jmp ($fffa)
|
||||
}
|
||||
|
||||
void mmap_trampoline(void)
|
||||
{
|
||||
*((void **)0xfffa) = IRQTrampoline;
|
||||
*((void **)0xfffe) = NMITrampoline;
|
||||
*((void **)0xfffa) = NMITrampoline;
|
||||
*((void **)0xfffe) = IRQTrampoline;
|
||||
}
|
||||
|
||||
#pragma native(mmap_trampoline)
|
||||
|
||||
void mmap_set(char pla)
|
||||
char mmap_set(char pla)
|
||||
{
|
||||
PLAShadow = pla;
|
||||
*((char *)0x01) = pla;
|
||||
char ppla = *((char *)0x01);
|
||||
*((volatile char *)0x01) = pla;
|
||||
return ppla;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define MMAP_NO_ROM 0x35
|
||||
#define MMAP_RAM 0x30
|
||||
#define MMAP_CHAR_ROM 0x31
|
||||
#define MMAP_ALL_ROM 0x33
|
||||
|
||||
// Install an IRQ an NMI trampoline, that routes the kernal interrupts
|
||||
// through an intermediate trampoline when the kernal ROM is not paged
|
||||
|
@ -17,9 +18,9 @@
|
|||
void mmap_trampoline(void);
|
||||
|
||||
// Set the memory map in a way that is compatible with the IRQ
|
||||
// trampoline
|
||||
// trampoline, returns the previous state
|
||||
|
||||
inline void mmap_set(char pla);
|
||||
inline char mmap_set(char pla);
|
||||
|
||||
#pragma compile("memmap.c")
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#include "mouse.h"
|
||||
#include "sid.h"
|
||||
#include "cia.h"
|
||||
|
||||
sbyte mouse_dx, mouse_dy;
|
||||
bool mouse_lb, mouse_rb;
|
||||
static char mouse_px, mouse_py;
|
||||
static char mouse_port;
|
||||
|
||||
inline signed char dpos(char * old, char mnew)
|
||||
{
|
||||
mnew = (mnew & 0x7f) >> 1;
|
||||
|
||||
char diff = (mnew - *old) & 0x3f;
|
||||
|
||||
if (diff >= 0x20)
|
||||
{
|
||||
*old = mnew;
|
||||
return diff | 0xe0;
|
||||
}
|
||||
else if (diff)
|
||||
{
|
||||
*old = mnew;
|
||||
return diff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mouse_poll(void)
|
||||
{
|
||||
char b = ((volatile char *)0xdc00)[mouse_port];
|
||||
mouse_rb = (b & 0x01) == 0;
|
||||
mouse_lb = (b & 0x10) == 0;
|
||||
|
||||
char x = sid.potx, y = sid.poty;
|
||||
|
||||
mouse_dx = dpos(&mouse_px, x);
|
||||
mouse_dy = dpos(&mouse_py, y);
|
||||
}
|
||||
|
||||
void mouse_arm(char n)
|
||||
{
|
||||
mouse_port = n;
|
||||
cia1.pra = ciaa_pra_def = n ? 0x7f : 0xbf;
|
||||
}
|
||||
|
||||
void mouse_init(void)
|
||||
{
|
||||
mouse_arm(1);
|
||||
mouse_poll();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef C64_MOUSE_H
|
||||
#define C64_MOUSE_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern sbyte mouse_dx, mouse_dy;
|
||||
extern bool mouse_lb, mouse_rb;
|
||||
|
||||
|
||||
void mouse_init(void);
|
||||
|
||||
// arm the potentiometer input for the selected mouse input
|
||||
// needs ~4ms to stabilize
|
||||
|
||||
void mouse_arm(char n);
|
||||
|
||||
// poll mouse input for selected mouse, but the relative
|
||||
// movement into mouse_dx/dy and the button state into
|
||||
// mouse_lb/mouse_rb
|
||||
|
||||
void mouse_poll(void);
|
||||
|
||||
#pragma compile("mouse.c")
|
||||
|
||||
#endif
|
||||
|
|
@ -5,83 +5,194 @@
|
|||
#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];
|
||||
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
|
||||
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
|
||||
|
||||
__asm rirq_isr_ram_io
|
||||
{
|
||||
stx plrx + 1
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
|
||||
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
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
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
|
||||
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
|
||||
jx:
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
asl $d019
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm rirq_isr_noio
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
kentry:
|
||||
lda $01
|
||||
pha
|
||||
|
||||
lda #$35
|
||||
sta $01
|
||||
|
||||
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
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
|
@ -89,25 +200,35 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
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
|
||||
|
@ -116,43 +237,36 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp $ea81
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
jmp $ea81
|
||||
|
||||
ex2:
|
||||
|
@ -161,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
|
||||
|
@ -176,21 +360,27 @@ ex2:
|
|||
|
||||
void rirq_build(RIRQCode * ic, byte size)
|
||||
{
|
||||
__assume(size < 26);
|
||||
|
||||
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);
|
||||
|
||||
if (size == 1)
|
||||
if (size == 0)
|
||||
{
|
||||
asm_np(ic->code + 0, ASM_RTS);
|
||||
}
|
||||
else if (size == 1)
|
||||
{
|
||||
asm_np(ic->code + 12, ASM_RTS);
|
||||
}
|
||||
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++)
|
||||
|
@ -219,14 +409,18 @@ void rirq_set(byte n, byte row, RIRQCode * write)
|
|||
rasterIRQRows[n] = row;
|
||||
}
|
||||
|
||||
static const byte irqai[16] = {
|
||||
static const byte irqai[26] = {
|
||||
RIRQ_ADDR_0, RIRQ_ADDR_1, RIRQ_ADDR_2, RIRQ_ADDR_3, RIRQ_ADDR_4, RIRQ_ADDR_5, RIRQ_ADDR_6, RIRQ_ADDR_7,
|
||||
RIRQ_ADDR_8, RIRQ_ADDR_9, RIRQ_ADDR_10, RIRQ_ADDR_11, RIRQ_ADDR_12, RIRQ_ADDR_13, RIRQ_ADDR_14, RIRQ_ADDR_15
|
||||
RIRQ_ADDR_8, RIRQ_ADDR_9, RIRQ_ADDR_10, RIRQ_ADDR_11, RIRQ_ADDR_12, RIRQ_ADDR_13, RIRQ_ADDR_14, RIRQ_ADDR_15,
|
||||
RIRQ_ADDR_16, RIRQ_ADDR_17, RIRQ_ADDR_18, RIRQ_ADDR_19, RIRQ_ADDR_20, RIRQ_ADDR_21, RIRQ_ADDR_22, RIRQ_ADDR_23,
|
||||
RIRQ_ADDR_24, RIRQ_ADDR_25
|
||||
};
|
||||
|
||||
static const byte irqdi[16] = {
|
||||
static const byte irqdi[26] = {
|
||||
RIRQ_DATA_0, RIRQ_DATA_1, RIRQ_DATA_2, RIRQ_DATA_3, RIRQ_DATA_4, RIRQ_DATA_5, RIRQ_DATA_6, RIRQ_DATA_7,
|
||||
RIRQ_DATA_8, RIRQ_DATA_9, RIRQ_DATA_10, RIRQ_DATA_11, RIRQ_DATA_12, RIRQ_DATA_13, RIRQ_DATA_14, RIRQ_DATA_15
|
||||
RIRQ_DATA_8, RIRQ_DATA_9, RIRQ_DATA_10, RIRQ_DATA_11, RIRQ_DATA_12, RIRQ_DATA_13, RIRQ_DATA_14, RIRQ_DATA_15,
|
||||
RIRQ_DATA_16, RIRQ_DATA_17, RIRQ_DATA_18, RIRQ_DATA_19, RIRQ_DATA_20, RIRQ_DATA_21, RIRQ_DATA_22, RIRQ_DATA_23,
|
||||
RIRQ_DATA_24, RIRQ_DATA_25
|
||||
};
|
||||
|
||||
void rirq_addr(RIRQCode * ic, byte n, void * addr)
|
||||
|
@ -236,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)
|
||||
|
@ -278,45 +479,165 @@ void rirq_clear(byte n)
|
|||
rasterIRQRows[n] = 255;
|
||||
}
|
||||
|
||||
void rirq_init(bool kernalIRQ)
|
||||
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
|
||||
|
||||
#if 0
|
||||
// disable CIA interrupts
|
||||
|
||||
lda #$7f
|
||||
sta $dc0d
|
||||
sta $dd0d
|
||||
#endif
|
||||
}
|
||||
|
||||
if (kernalIRQ)
|
||||
*(void **)0x0314 = irq1;
|
||||
else
|
||||
*(void **)0xfffe = irq0;
|
||||
*(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;
|
||||
vic.raster = 255;
|
||||
|
||||
}
|
||||
|
||||
void rirq_init_io(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = rirq_isr_ram_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
vic.raster = 255;
|
||||
|
||||
}
|
||||
|
||||
void rirq_init_memmap(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
vic.raster = 255;
|
||||
|
||||
}
|
||||
|
||||
void rirq_init(bool kernalIRQ)
|
||||
{
|
||||
if (kernalIRQ)
|
||||
rirq_init_kernal();
|
||||
else
|
||||
rirq_init_io();
|
||||
}
|
||||
|
||||
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];
|
||||
|
@ -329,12 +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++;
|
||||
vic.raster = rasterIRQNext[nextIRQ] - 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)
|
||||
|
@ -348,6 +689,7 @@ void rirq_start(void)
|
|||
lda #100
|
||||
sta $d012
|
||||
|
||||
asl $d019
|
||||
cli
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
#ifndef NUM_IRQS
|
||||
#define NUM_IRQS 16
|
||||
#endif
|
||||
|
||||
extern volatile byte rirq_count;
|
||||
|
||||
enum RIRQCodeIndex
|
||||
{
|
||||
|
@ -56,7 +59,39 @@ enum RIRQCodeIndex
|
|||
RIRQ_ADDR_14 = 78,
|
||||
|
||||
RIRQ_DATA_15 = 81,
|
||||
RIRQ_ADDR_15 = 88,
|
||||
RIRQ_ADDR_15 = 83,
|
||||
|
||||
RIRQ_DATA_16 = 86,
|
||||
RIRQ_ADDR_16 = 88,
|
||||
|
||||
RIRQ_DATA_17 = 91,
|
||||
RIRQ_ADDR_17 = 93,
|
||||
|
||||
RIRQ_DATA_18 = 96,
|
||||
RIRQ_ADDR_18 = 98,
|
||||
|
||||
RIRQ_DATA_19 = 101,
|
||||
RIRQ_ADDR_19 = 103,
|
||||
|
||||
RIRQ_SIZE_20 = 106,
|
||||
|
||||
RIRQ_DATA_20 = 106,
|
||||
RIRQ_ADDR_20 = 108,
|
||||
|
||||
RIRQ_DATA_21 = 111,
|
||||
RIRQ_ADDR_21 = 113,
|
||||
|
||||
RIRQ_DATA_22 = 116,
|
||||
RIRQ_ADDR_22 = 118,
|
||||
|
||||
RIRQ_DATA_23 = 121,
|
||||
RIRQ_ADDR_23 = 123,
|
||||
|
||||
RIRQ_DATA_24 = 126,
|
||||
RIRQ_ADDR_24 = 128,
|
||||
|
||||
RIRQ_DATA_25 = 131,
|
||||
RIRQ_ADDR_25 = 133
|
||||
};
|
||||
|
||||
// One raster interrupt operation, handles up to five writes
|
||||
|
@ -67,6 +102,12 @@ typedef struct RIRQCode
|
|||
byte code[RIRQ_SIZE];
|
||||
} RIRQCode;
|
||||
|
||||
typedef struct RQIRCode20
|
||||
{
|
||||
RIRQCode c;
|
||||
byte code[RIRQ_SIZE_20 - RIRQ_SIZE];
|
||||
} RIRQCode20;
|
||||
|
||||
// Build one raster IRQ operation of the given size (wait + #ops) for up to 5 instructions
|
||||
void rirq_build(RIRQCode * ic, byte size);
|
||||
|
||||
|
@ -82,17 +123,21 @@ 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
|
||||
inline void rirq_clear(byte n)
|
||||
inline void rirq_clear(byte n);
|
||||
|
||||
// Change the vertical position of the raster IRQ of one of the slots
|
||||
inline void rirq_move(byte n, byte row);
|
||||
|
@ -101,7 +146,31 @@ inline void rirq_move(byte n, byte row);
|
|||
// Initialize the raster IRQ system with either the kernal IRQ vector
|
||||
// or the hardware IRQ vector if the kernal ROM is turned off (which is
|
||||
// the less resource hungry option)
|
||||
void rirq_init(bool kernalIRQ);
|
||||
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
|
||||
void rirq_start(void);
|
||||
|
@ -110,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
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#include "reu.h"
|
||||
|
||||
int reu_count_pages(void)
|
||||
{
|
||||
volatile char c, d;
|
||||
|
||||
c = 0;
|
||||
reu_store(0, &c, 1);
|
||||
reu_load(0, &d, 1);
|
||||
|
||||
if (d == 0)
|
||||
{
|
||||
c = 0x47;
|
||||
reu_store(0, &c, 1);
|
||||
reu_load(0, &d, 1);
|
||||
|
||||
if (d == 0x47)
|
||||
{
|
||||
for(int i=1; i<256; i++)
|
||||
{
|
||||
long l = (long)i << 16;
|
||||
c = 0x47;
|
||||
reu_store(l, &c, 1);
|
||||
c = 0x00;
|
||||
reu_store(0, &c, 1);
|
||||
|
||||
reu_load(l, &d, 1);
|
||||
if (d != 0x47)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 256;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void reu_store(unsigned long raddr, const volatile char * sp, unsigned length)
|
||||
{
|
||||
reu.laddr = (word)sp;
|
||||
reu.raddr = raddr;
|
||||
reu.rbank = raddr >> 16;
|
||||
reu.length = length;
|
||||
reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR;
|
||||
reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_STORE;
|
||||
|
||||
}
|
||||
|
||||
inline void reu_load(unsigned long raddr, volatile char * dp, unsigned length)
|
||||
{
|
||||
reu.laddr = (word)dp;
|
||||
reu.raddr = raddr;
|
||||
reu.rbank = raddr >> 16;
|
||||
reu.length = length;
|
||||
reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR;
|
||||
reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_LOAD;
|
||||
}
|
||||
|
||||
inline void reu_fill(unsigned long raddr, char c, unsigned length)
|
||||
{
|
||||
reu.laddr = (word)&c;
|
||||
reu.raddr = raddr;
|
||||
reu.rbank = raddr >> 16;
|
||||
reu.length = length;
|
||||
reu.ctrl = REU_CTRL_FIXL | REU_CTRL_INCR;
|
||||
reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_STORE;
|
||||
}
|
||||
|
||||
inline void reu_load2d(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride)
|
||||
{
|
||||
reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR;
|
||||
reu.laddr = (word)dp;
|
||||
for(char i=0; i<height; i++)
|
||||
{
|
||||
reu.length = width;
|
||||
reu.raddr = raddr;
|
||||
reu.rbank = raddr >> 16;
|
||||
reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_LOAD;
|
||||
raddr += stride;
|
||||
}
|
||||
}
|
||||
|
||||
inline void reu_load2dpage(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride)
|
||||
{
|
||||
reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR;
|
||||
reu.laddr = (word)dp;
|
||||
reu.rbank = raddr >> 16;
|
||||
for(char i=0; i<height; i++)
|
||||
{
|
||||
reu.length = width;
|
||||
reu.raddr = raddr;
|
||||
reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_LOAD;
|
||||
raddr += stride;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef C64_REU_H
|
||||
#define C64_REU_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define REU_STAT_IRQ 0x80
|
||||
#define REU_STAT_EOB 0x40
|
||||
#define REU_STAT_FAULT 0x20
|
||||
#define REU_STAT_SIZE 0x10
|
||||
#define REU_STAT_VERSION 0x0f
|
||||
|
||||
#define REU_CTRL_FIXL 0x80
|
||||
#define REU_CTRL_FIXR 0x40
|
||||
#define REU_CTRL_INCL 0x00
|
||||
#define REU_CTRL_INCR 0x00
|
||||
|
||||
#define REU_IRQ_ENABLE 0x80
|
||||
#define REU_IRQ_EOB 0x40
|
||||
#define REU_IRQ_FAULT 0x20
|
||||
|
||||
#define REU_CMD_EXEC 0x80
|
||||
#define REU_CMD_AUTO 0x20
|
||||
#define REU_CMD_FF00 0x10
|
||||
#define REU_CMD_STORE 0x00
|
||||
#define REU_CMD_LOAD 0x01
|
||||
#define REU_CMD_SWAP 0x02
|
||||
#define REU_CMD_VERIFY 0x03
|
||||
|
||||
struct REU
|
||||
{
|
||||
volatile byte status;
|
||||
volatile byte cmd;
|
||||
|
||||
volatile word laddr;
|
||||
volatile word raddr;
|
||||
volatile byte rbank;
|
||||
|
||||
volatile word length;
|
||||
|
||||
volatile byte irqmask;
|
||||
volatile byte ctrl;
|
||||
};
|
||||
|
||||
|
||||
#define reu (*((struct REU *)0xdf00))
|
||||
|
||||
// Count the number of 64k pages in the REU, the test is destructive
|
||||
int reu_count_pages(void);
|
||||
|
||||
// Copy an array of data from C64 memory to the REU memory
|
||||
inline void reu_store(unsigned long raddr, const volatile char * sp, unsigned length);
|
||||
|
||||
// Copy an array of data from REU memory to the C64 memory
|
||||
inline void reu_load(unsigned long raddr, volatile char * dp, unsigned length);
|
||||
|
||||
// Fill an array of data in the REU with a single value
|
||||
inline void reu_fill(unsigned long raddr, char c, unsigned length);
|
||||
|
||||
// Copy a 2D array from REU memory to the C64 memory. The stride parameter
|
||||
// is the distance of two rows in REU memory
|
||||
inline void reu_load2d(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride);
|
||||
|
||||
|
||||
inline void reu_load2dpage(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride);
|
||||
|
||||
#pragma compile("reu.c")
|
||||
|
||||
#endif
|
|
@ -1,8 +1,11 @@
|
|||
#include "sprites.h"
|
||||
#include "rasterirq.h"
|
||||
|
||||
static char * vspriteScreen;
|
||||
static volatile char * vspriteScreen;
|
||||
|
||||
#ifdef VSPRITE_BSS
|
||||
#pragma bss(VSPRITE_BSS)
|
||||
#endif
|
||||
|
||||
void spr_init(char * screen)
|
||||
{
|
||||
|
@ -69,6 +72,31 @@ void spr_move(char sp, int xpos, int ypos)
|
|||
vic.spr_msbx &= ~(1 << sp);
|
||||
}
|
||||
|
||||
void spr_move16(char sp, int xpos, int ypos)
|
||||
{
|
||||
__assume (sp < 8);
|
||||
|
||||
if (ypos < 0 || ypos >= 256 || xpos < 0 || xpos >= 384)
|
||||
xpos = 384;
|
||||
|
||||
vic.spr_pos[sp].y = ypos;
|
||||
vic.spr_pos[sp].x = xpos & 0xff;
|
||||
if (xpos & 0x100)
|
||||
vic.spr_msbx |= 1 << sp;
|
||||
else
|
||||
vic.spr_msbx &= ~(1 << sp);
|
||||
}
|
||||
|
||||
int spr_posx(char sp)
|
||||
{
|
||||
return vic.spr_pos[sp].x | ((vic.spr_msbx & (1 << sp)) ? 256 : 0);
|
||||
}
|
||||
|
||||
int spr_posy(char sp)
|
||||
{
|
||||
return vic.spr_pos[sp].y;
|
||||
}
|
||||
|
||||
void spr_image(char sp, char image)
|
||||
{
|
||||
__assume (sp < 8);
|
||||
|
@ -83,15 +111,29 @@ void spr_color(char sp, char color)
|
|||
vic.spr_color[sp] = color;
|
||||
}
|
||||
|
||||
void spr_expand(char sp, bool xexpand, bool yexpand)
|
||||
{
|
||||
__assume (sp < 8);
|
||||
|
||||
#define NUM_SPRITES 16
|
||||
char m = 1 << sp;
|
||||
|
||||
static char vspriteYLow[NUM_SPRITES], vspriteXLow[NUM_SPRITES], vspriteXHigh[NUM_SPRITES];
|
||||
static char vspriteImage[NUM_SPRITES], vspriteColor[NUM_SPRITES];
|
||||
if (xexpand)
|
||||
vic.spr_expand_x |= m;
|
||||
else
|
||||
vic.spr_expand_x &= ~m;
|
||||
|
||||
static char spriteOrder[16], spriteYPos[17];
|
||||
if (yexpand)
|
||||
vic.spr_expand_y |= m;
|
||||
else
|
||||
vic.spr_expand_y &= ~m;
|
||||
}
|
||||
|
||||
static RIRQCode spirq[8], synch;
|
||||
static char vspriteYLow[VSPRITES_MAX], vspriteXLow[VSPRITES_MAX], vspriteXHigh[VSPRITES_MAX];
|
||||
static char vspriteImage[VSPRITES_MAX], vspriteColor[VSPRITES_MAX];
|
||||
|
||||
static char spriteOrder[VSPRITES_MAX], spriteYPos[VSPRITES_MAX + 1];
|
||||
|
||||
static RIRQCode spirq[VSPRITES_MAX - 8], synch;
|
||||
|
||||
|
||||
void vspr_init(char * screen)
|
||||
|
@ -102,27 +144,48 @@ void vspr_init(char * screen)
|
|||
vic.spr_expand_y = 0;
|
||||
vic.spr_enable = 0xff;
|
||||
|
||||
for(int i=0; i<8; i++)
|
||||
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[i], 0);
|
||||
rirq_write(spirq + i, 1, &vic.spr_pos[i].x, 0);
|
||||
rirq_write(spirq + i, 2, &vic.spr_pos[i].y, 0);
|
||||
rirq_write(spirq + i, 3, &vspriteScreen[i], 0);
|
||||
rirq_write(spirq + i, 0, &vic.spr_color[j], 0);
|
||||
rirq_write(spirq + i, 1, &vic.spr_pos[j].x, 0);
|
||||
rirq_write(spirq + i, 2, &vic.spr_pos[j].y, 0);
|
||||
rirq_write(spirq + i, 3, &vspriteScreen[j], 0);
|
||||
rirq_write(spirq + i, 4, &vic.spr_msbx, 0);
|
||||
rirq_set(i, 80 + 8 * i, spirq + i);
|
||||
rirq_set(i, 80 + 4 * i, spirq + i);
|
||||
}
|
||||
|
||||
rirq_build(&synch, 0);
|
||||
rirq_set(8, 250, &synch);
|
||||
rirq_set(VSPRITES_MAX - 8, 250, &synch);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
for(int i=0; i<VSPRITES_MAX; i++)
|
||||
{
|
||||
spriteOrder[i] = i;
|
||||
vspriteYLow[i] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -151,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;
|
||||
|
@ -168,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<16; i++)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,48 +278,68 @@ void vspr_sort(void)
|
|||
void vspr_update(void)
|
||||
{
|
||||
char xymask = 0;
|
||||
char * vsprs = vspriteScreen;
|
||||
volatile char * vsprs = vspriteScreen;
|
||||
// char sypos[VSPRITES_MAX];
|
||||
|
||||
#pragma unroll(full)
|
||||
|
||||
for(char ui=0; ui<8; 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;
|
||||
|
||||
if (spriteYPos[8] < 230)
|
||||
{
|
||||
char m = 1;
|
||||
for(char ti=0; ti<8; ti++)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
bool done = false;
|
||||
|
||||
for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
|
||||
{
|
||||
if (!done && spriteYPos[ti + 9] < 250)
|
||||
{
|
||||
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] + 21);
|
||||
|
||||
m <<= 1;
|
||||
// spriteYPos[ti + 9] = vspriteYLow[ri];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(char ti=0; ti<8; ti++)
|
||||
else
|
||||
{
|
||||
rirq_clear(ti);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,22 @@ void spr_set(char sp, bool show, int xpos, int ypos, char image, char color, boo
|
|||
|
||||
inline void spr_show(char sp, bool show);
|
||||
|
||||
// move a sprite the
|
||||
// move a sprite to the given position, only uses 8 bit y and 9 bit x
|
||||
|
||||
inline void spr_move(char sp, int xpos, int ypos);
|
||||
|
||||
// get current x position of sprite
|
||||
|
||||
inline int spr_posx(char sp);
|
||||
|
||||
// get current y position of sprite
|
||||
|
||||
inline int spr_posy(char sp);
|
||||
|
||||
// move a sprite to the given position, only uses 16 bit y and 16 bit x,
|
||||
// moves the sprite to a zero y position if offscreen
|
||||
void spr_move16(char sp, int xpos, int ypos);
|
||||
|
||||
// change the image of a sprite
|
||||
|
||||
inline void spr_image(char sp, char image);
|
||||
|
@ -27,6 +39,10 @@ inline void spr_image(char sp, char image);
|
|||
|
||||
inline void spr_color(char sp, char color);
|
||||
|
||||
// change the image of a sprite
|
||||
|
||||
inline void spr_expand(char sp, bool xexpand, bool yexpand);
|
||||
|
||||
// The virtual sprite system works with the rasterirq library to multiplex
|
||||
// 16 virtual sprites onto the actual eight hardware sprites. It uses the slots
|
||||
// 0 to 8 of the rasterirq library to switch the sprites mid screen. The
|
||||
|
@ -44,10 +60,18 @@ inline void spr_color(char sp, char color);
|
|||
// rirq_sort();
|
||||
//
|
||||
|
||||
#ifndef VSPRITES_MAX
|
||||
#define VSPRITES_MAX 16
|
||||
#endif
|
||||
|
||||
// initialize the virtual (multiplexed) sprite system, offering 16 sprites
|
||||
|
||||
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);
|
||||
|
@ -56,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);
|
||||
|
|
|
@ -16,7 +16,12 @@ void vic_sprxy(byte s, int x, int y)
|
|||
vic.spr_msbx &= ~(1 << s);
|
||||
}
|
||||
|
||||
void vic_setmode(VicMode mode, char * text, char * font)
|
||||
int vic_sprgetx(byte s)
|
||||
{
|
||||
return vic.spr_pos[s].x | ((vic.spr_msbx & (1 << s)) ? 256 : 0);
|
||||
}
|
||||
|
||||
void vic_setmode(VicMode mode, const char * text, const char * font)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
|
@ -40,6 +45,8 @@ void vic_setmode(VicMode mode, char * text, char * font)
|
|||
vic.ctrl1 = VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3;
|
||||
vic.ctrl2 = VIC_CTRL2_CSEL | VIC_CTRL2_MCM;
|
||||
break;
|
||||
default:
|
||||
__assume(false);
|
||||
}
|
||||
|
||||
cia2.pra = (cia2.pra & 0xfc) | (((unsigned)text >> 14) ^ 0x03);
|
||||
|
@ -66,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;
|
||||
|
@ -78,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)
|
||||
|
|
|
@ -91,12 +91,15 @@ enum VicMode
|
|||
|
||||
// set the display mode and base address. This will also
|
||||
// adapt the bank.
|
||||
void vic_setmode(VicMode mode, char * text, char * font);
|
||||
void vic_setmode(VicMode mode, const char * text, const char * font);
|
||||
|
||||
// put a sprite at the given x/y location, taking care of the
|
||||
// x MSB
|
||||
inline void vic_sprxy(byte s, int x, int y);
|
||||
|
||||
// Read the sprite x position from the LSB and MSB register
|
||||
inline int vic_sprgetx(byte s);
|
||||
|
||||
// wait for the beam to reach the bottom of the visual area
|
||||
inline void vic_waitBottom(void);
|
||||
|
||||
|
@ -106,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))
|
||||
|
||||
|
|
487
include/conio.c
487
include/conio.c
|
@ -2,176 +2,425 @@
|
|||
|
||||
static IOCharMap giocharmap = IOCHM_ASCII;
|
||||
|
||||
#if defined(__C128__)
|
||||
#pragma code(lowcode)
|
||||
__asm bsout
|
||||
{
|
||||
ldx #0
|
||||
stx 0xff00
|
||||
jsr 0xffd2
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsin
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xffe4
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsget
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xffcf
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xfff0
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsinit
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xff81
|
||||
sta 0xff01
|
||||
}
|
||||
__asm dswap
|
||||
{
|
||||
sta 0xff00
|
||||
jsr 0xff5f
|
||||
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
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffd2
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsin
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffe4
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsget
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffcf
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xfff0
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsinit
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xff81
|
||||
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 bsget
|
||||
{
|
||||
lda 0xe405
|
||||
pha
|
||||
lda 0xe404
|
||||
pha
|
||||
}
|
||||
|
||||
__asm bsplot
|
||||
{
|
||||
|
||||
}
|
||||
__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__) || defined(__C128B__) || defined(__C128E__)
|
||||
void dispmode40col(void)
|
||||
{
|
||||
if (*(volatile char *)0xd7 >= 128)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr dswap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dispmode80col(void)
|
||||
{
|
||||
if (*(volatile char *)0xd7 < 128)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr dswap
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
cpx #IOCHM_PETSCII_2
|
||||
beq w3
|
||||
and #$df
|
||||
w3:
|
||||
jmp 0xffd2
|
||||
__asm {
|
||||
lda c
|
||||
jsr bsout
|
||||
}
|
||||
}
|
||||
|
||||
__asm getpch
|
||||
void putpch(char c)
|
||||
{
|
||||
jsr 0xffe4
|
||||
#if defined(__ATARI__)
|
||||
if (c == 10)
|
||||
c = 0x9b;
|
||||
#else
|
||||
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
|
||||
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
if (giocharmap == IOCHM_PETSCII_1)
|
||||
c &= 0xdf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmp #13
|
||||
bne w1
|
||||
lda #10
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
#endif
|
||||
|
||||
cmp #65
|
||||
bcc w3
|
||||
cmp #123
|
||||
bcs w3
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
w3:
|
||||
putrch(c);
|
||||
}
|
||||
|
||||
static char convch(char ch)
|
||||
{
|
||||
#if !defined(__ATARI__)
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
||||
char getrch(void)
|
||||
{
|
||||
return __asm {
|
||||
jsr bsget
|
||||
sta accu
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
void putch(int c)
|
||||
{
|
||||
__asm {
|
||||
lda c
|
||||
jsr 0xffd2
|
||||
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 $ff5b
|
||||
}
|
||||
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 $fff0
|
||||
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,28 +18,95 @@ extern IOCharMap giocharmap;
|
|||
|
||||
void iocharmap(IOCharMap chmap);
|
||||
|
||||
#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,
|
||||
|
||||
void putch(int c);
|
||||
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
|
||||
char getchx(void);
|
||||
|
||||
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")
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue