Compare commits

...

818 Commits

Author SHA1 Message Date
drmortalwombat 6ed4adb0ed OPtimize signed+unsigned char arithmetic 2025-06-19 21:54:23 +02:00
drmortalwombat f16c24363c Improve pointer compare constant folding 2025-06-19 12:58:40 +02:00
drmortalwombat fd7e68573c Fold CLC into prev block for dual pointer increment 2025-06-19 09:37:03 +02:00
drmortalwombat f1873f0794 Optimize carry flag analysis with indexed tables 2025-06-17 21:51:19 +02:00
drmortalwombat a01d98e584 Propagate closed bool variables to use sign bit instead of zero/one 2025-06-15 18:10:50 +02:00
drmortalwombat c7a53a5be6 Bump version number 2025-06-15 14:27:49 +02:00
drmortalwombat 4633631d7e Fix double condition propagation 2025-06-15 13:56:11 +02:00
drmortalwombat 100608e0ac Fix loop head split for infinite loops 2025-06-14 12:53:55 +02:00
drmortalwombat 35a0b36a0d Make rasterirq handler more resilient for timing glitches 2025-06-11 09:34:21 +02:00
drmortalwombat 5470db3a5f Fix sidfx state machine sequence end 2025-06-10 21:06:28 +02:00
drmortalwombat d6802f3cb9 Make loop head extraction explicit 2025-06-10 17:41:16 +02:00
drmortalwombat 5b4e0c2b55 Sidfx extend gate sprike condition 2025-06-08 18:19:37 +02:00
drmortalwombat 8175fae67a Add complex loop value forwarding, tweak sidfx state machine 2025-06-07 19:35:40 +02:00
drmortalwombat 13c90eb542 Change SIDFX state machine reset 2025-06-06 20:00:38 +02:00
drmortalwombat f98665c577 Fix bool artihmetic assign combos 2025-06-01 18:40:19 +02:00
drmortalwombat 8843f3feba Fix pointer loop reversal counting from one 2025-06-01 11:51:24 +02:00
drmortalwombat 514cf59398 More short loop reversal 2025-05-31 19:44:33 +02:00
drmortalwombat 03c133cd48 Swap shift/add if add fits in byte before but not after 2025-05-30 17:39:40 +02:00
drmortalwombat 880abea32e Shortcut tiny jump detours after placement 2025-05-29 13:38:00 +02:00
drmortalwombat fc9a8f2a89 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-05-28 20:49:00 +02:00
drmortalwombat 40c467d958 Improve copy elision 2025-05-28 20:48:37 +02:00
drmortalwombat 4bde6385b8
Merge pull request #250 from ilmich/fix-compiler-build
prepare output directory also to build only the compiler
2025-05-28 12:55:39 +02:00
drmortalwombat 688ef958e3 Add default move constructor and assignment operators 2025-05-27 20:47:03 +02:00
ilmich 6da7223472 prepare output directory also to build only the compiler 2025-05-27 16:33:36 +02:00
drmortalwombat a1d4bc8375 Improve const initialized simple type usage for local variables 2025-05-27 14:03:04 +02:00
drmortalwombat 197e2a91be Optimize carry propagation 2025-05-25 17:37:52 +02:00
drmortalwombat 4d9d628b67 Add static_assert 2025-05-25 12:31:15 +02:00
drmortalwombat f720feebbf Fix global register forward mixing up x and y in one case 2025-05-25 10:15:47 +02:00
drmortalwombat 6076808f5e Relax interrupt complexity limits for local variables on stack 2025-05-24 20:48:04 +02:00
drmortalwombat 0af17f0f40 Fix constness of reference parameter of standard copy assignment operator 2025-05-24 17:49:51 +02:00
drmortalwombat 81e5321bfc Return short simple structs in accu 2025-05-23 12:02:12 +02:00
drmortalwombat 27d3666285 Fix pass struct rvalue return to rvalue parameter conflicting zero page registers 2025-05-22 15:28:39 +02:00
drmortalwombat c6b794db3a Fix kernal io return values 2025-05-22 08:11:49 +02:00
drmortalwombat 1fa4c39a20 Add more math intrinsics 2025-05-21 16:59:52 +02:00
drmortalwombat 0ba148b6bb Make raster interrupt start more deterministic 2025-05-20 18:26:42 +02:00
drmortalwombat 65540da3f7 Optimize signed long compare 2025-05-20 16:05:09 +02:00
drmortalwombat e660757824 Some low level shift optimizations 2025-05-20 11:09:20 +02:00
drmortalwombat 05a6d16dde Some cascading store optimization 2025-05-19 17:23:28 +02:00
drmortalwombat 79ec9af3f2 Fix signed unsigned char compare to promote to int 2025-05-19 15:31:30 +02:00
drmortalwombat 8f37df448f Optimize constant array parameters 2025-05-19 10:03:45 +02:00
drmortalwombat d710a71ba0 Fix static const member qualification with dot 2025-05-19 08:16:58 +02:00
drmortalwombat 8dd211b662 Fix crash in peephole optimizer on potential oob static const array access 2025-05-18 19:25:47 +02:00
drmortalwombat 398ed22b09 Fix array member packing strategy 2025-05-18 18:41:37 +02:00
drmortalwombat 6f1da4335b Fix continue/break for unrolled loops 2025-05-18 14:04:14 +02:00
drmortalwombat c86dc364b1 Fixed array size template parameter 2025-05-18 11:35:13 +02:00
drmortalwombat 70eb7a5eab Fix assert with negative array offset in local variable of a recursive function 2025-05-18 11:03:04 +02:00
drmortalwombat c1cd2ba57e Fix crash with partial reference of ternary conditional operator 2025-05-18 09:42:37 +02:00
drmortalwombat 00da0ef87d Add CAPACITYCHECK to static_vector 2025-05-17 09:07:33 +02:00
drmortalwombat be9abbf510 Optimize vector copy 2025-05-16 18:20:23 +02:00
drmortalwombat 0b72e6b2f2 Force nop for breakpoint() to avoid elimination if alone in basic block 2025-05-16 17:25:58 +02:00
drmortalwombat 6ea39d7bfa CTT file import 2025-05-15 17:50:59 +02:00
drmortalwombat c0abe031ee Fix enum base type selection with trailing comma 2025-05-15 08:46:57 +02:00
drmortalwombat fe667863b2 Constant folding of absolute pointer difference 2025-05-15 07:58:58 +02:00
drmortalwombat e514e05dc8 Fix crash constant folding uninitialized constants 2025-05-14 20:22:25 +02:00
drmortalwombat d978d0a483 Fix error message location for integer const truncation 2025-05-14 18:25:20 +02:00
drmortalwombat 37cacdafa7 Improve cross compilation unit template matching 2025-05-14 18:18:13 +02:00
drmortalwombat 78e3696663 Improve nullptr check for addresses of placed linker objects 2025-05-14 17:09:12 +02:00
drmortalwombat a0215a4f21 Add fix for template overload with multiple includes 2025-05-14 15:15:24 +02:00
drmortalwombat 2310416c46 Propagate non aliasing initializers to compile time constants 2025-05-13 20:48:12 +02:00
drmortalwombat 52db653ec1 Optimize shift code generation 2025-05-12 20:09:57 +02:00
drmortalwombat 6fe76e478f Add -ii option to change default include path 2025-05-11 18:29:57 +02:00
drmortalwombat ba05ec743d Fix high byte address forwarding 2025-05-11 17:31:01 +02:00
drmortalwombat 05ef25a61e Add optimization -Ox to simplify pointer arithmetic by non page crossing 2025-05-11 12:41:40 +02:00
drmortalwombat b26cc4ede7 Remove assembly debug output 2025-05-10 20:24:30 +02:00
drmortalwombat 8dc5f703e8 Fix copy indirect lea elimination 2025-05-10 20:23:45 +02:00
drmortalwombat c05d7e47f4 Add assign to vector and static_vector 2025-05-10 18:50:13 +02:00
drmortalwombat 9dc8489693 Fix copy struct to value struct param, add vsprintf 2025-05-10 17:49:34 +02:00
drmortalwombat f443c97f70 Fix for default copy constructor on init calls 2025-05-10 13:40:36 +02:00
drmortalwombat 4837ceb73f Fix inline assembler optimzier for JSR returning result in X and Y 2025-05-10 13:13:27 +02:00
drmortalwombat 42299c9406 Improve const to immediate propagation 2025-05-10 10:50:42 +02:00
drmortalwombat 850bbfc31a Fix alignment increment problem 2025-05-10 09:53:31 +02:00
drmortalwombat 1e95f51469 Fix building object directly on call stack 2025-05-10 08:33:02 +02:00
drmortalwombat e525e5d62e Optimize copy of arrays of ints 2025-05-09 16:52:04 +02:00
drmortalwombat 18deb8846d Add full() to static_vector 2025-05-08 17:31:16 +02:00
drmortalwombat 34ce9afeae Fix memory use after free error in vector 2025-05-08 17:26:10 +02:00
drmortalwombat d0411b7d52 Fix more function overloads with const 2025-05-08 15:21:59 +02:00
drmortalwombat 34fda8c9b5 Fix const struct parameter overload matching 2025-05-08 13:50:51 +02:00
drmortalwombat b4a357e44f Add clear to vector and static_vector 2025-05-08 12:30:50 +02:00
drmortalwombat 2b224f262b Fix use of hash character in preprocessor defines 2025-05-08 08:18:57 +02:00
drmortalwombat 3c306e0899 Fix loss of register dependency chain when splitting 16bit adds into basic blocks 2025-05-07 13:13:33 +02:00
drmortalwombat e82ab0c7ca Improve shift carry combine 2025-05-06 18:38:44 +02:00
drmortalwombat 983064c694 Fix removal of reference returns when struct member used 2025-05-06 17:00:36 +02:00
drmortalwombat 9230d95bad Fix copy constructor selection in placement new 2025-05-06 08:53:57 +02:00
drmortalwombat 8b0790588b Fix integer range when combining same instruction on alternate paths 2025-05-05 16:52:17 +02:00
drmortalwombat 0a9c43757a Fix reference to value cast 2025-05-05 11:44:10 +02:00
drmortalwombat fccfe35c4f Fix 16bit const add propagation 2025-05-05 11:17:00 +02:00
drmortalwombat 064fed63f5 Fix operator() call on reference parameter 2025-05-04 16:18:07 +02:00
drmortalwombat f43f471124 Fix internal const cast 2025-05-04 16:00:08 +02:00
drmortalwombat f99abb32e2 Fix cost method selection for pointers to incomplete types 2025-05-04 15:27:28 +02:00
drmortalwombat 18f044e90c Fix crash in profile generation 2025-05-04 13:12:14 +02:00
drmortalwombat 5b961c031c Fix reference return from inlined function into inline parameter 2025-05-04 11:05:15 +02:00
drmortalwombat 500cce511f Fix removal of function reference result if only used as target 2025-05-03 17:22:18 +02:00
drmortalwombat 885d6ff706 Fix crash in complex select statement 2025-05-03 09:41:15 +02:00
drmortalwombat efc182ce27
Merge pull request #238 from polluks/patch-4
Fixed minor typo
2025-05-02 17:43:29 +02:00
drmortalwombat 06ef87fe63
Merge pull request #237 from polluks/patch-5
Fixed minor typo
2025-05-02 17:43:05 +02:00
drmortalwombat f3d8251072
Merge pull request #236 from polluks/patch-6
Fixed minor typo
2025-05-02 17:42:37 +02:00
drmortalwombat 0d5efc90ed
Merge pull request #235 from polluks/patch-7
Fixed minor typo
2025-05-02 17:42:18 +02:00
drmortalwombat 30b8e4e970
Merge pull request #234 from polluks/patch-8
Fixed minor typo
2025-05-02 17:41:52 +02:00
drmortalwombat 3da1ddf5da
Merge pull request #233 from polluks/patch-9
Fixed typo
2025-05-02 17:41:29 +02:00
drmortalwombat bfdd1b85fb
Merge pull request #239 from polluks/patch-3
Fixed minor typo
2025-05-02 17:40:59 +02:00
drmortalwombat 686d468d32
Merge pull request #240 from polluks/patch-2
Fixed minor typo
2025-05-02 17:40:39 +02:00
drmortalwombat 23b15678cd
Merge pull request #232 from polluks/patch-10
Fixed minor typo
2025-05-02 17:40:13 +02:00
Stefan d1054abd90
Fixed minor typo 2025-05-02 16:50:57 +02:00
Stefan d358c8359b
Fixed typo 2025-05-02 16:48:56 +02:00
Stefan 9e9494ebf9
Fixed minor typo 2025-05-02 16:46:27 +02:00
Stefan 015ada7a33
Fixed minor typo 2025-05-02 16:44:44 +02:00
drmortalwombat 12e832ebd3 Fix static constexpr in class context 2025-05-02 16:44:24 +02:00
Stefan e327d2a148
Fixed minor typo 2025-05-02 16:41:42 +02:00
Stefan 366f9686dd
Fixed minor typo 2025-05-02 16:39:17 +02:00
Stefan a2927401bc
Fixed minor typo 2025-05-02 16:36:01 +02:00
Stefan bbb339d641
Fixed minor typo 2025-05-02 16:33:35 +02:00
Stefan 8e76334c20
Fixed minor typo 2025-05-02 16:30:49 +02:00
drmortalwombat 739f1e2161 Improve conditional branch integer range propagation 2025-05-01 20:23:13 +02:00
drmortalwombat 4ee6ca5b94 Improve function automatic template matching 2025-05-01 16:04:10 +02:00
drmortalwombat 347898ea53 fix mixup of stack and fast call in virtual function parameter offsets 2025-05-01 10:21:35 +02:00
drmortalwombat 6caed58be4 Fix new operator broken with placement new fix 2025-04-30 22:38:43 +02:00
drmortalwombat c4185832ba Fix method invocation on rvalue reference 2025-04-30 17:06:28 +02:00
drmortalwombat 2b0994b086 Fix placement new for vector constructor 2025-04-29 20:12:48 +02:00
drmortalwombat f9acbc152d Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-04-29 14:26:58 +02:00
drmortalwombat 3eed21567e Fix disabled warning bitset size 2025-04-29 14:26:55 +02:00
drmortalwombat f3370cb149
Merge pull request #226 from CTalkobt/main
Update to reflect mega65 in .md
2025-04-27 14:23:54 +02:00
ctalkobt@ctalkobt.net 494fb97e49 Update to reflect mega65 in .md 2025-04-27 07:38:14 -04:00
drmortalwombat bd8786af0b Improve carry propagation to eliminate sec and clc 2025-04-26 21:25:43 +02:00
drmortalwombat f0a7499814 Ignore nullptr access for volatile data 2025-04-24 15:31:39 +02:00
drmortalwombat da4a90b724 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-04-24 09:05:59 +02:00
drmortalwombat 96a9109915 Add warning pragma, improved token concatenation in preprocessing 2025-04-24 09:05:57 +02:00
drmortalwombat f5a33edcf4
Merge pull request #224 from polluks/patch-1
Changed make target everywhere
2025-04-23 16:58:45 +02:00
Stefan 1bd98bdeb2
Changed make target everywhere
oops
2025-04-23 15:32:26 +02:00
drmortalwombat e4696a6539
Merge pull request #223 from polluks/wildcard
More POSIX, fixed #190
2025-04-23 11:23:21 +02:00
polluks 74350d6133 oops 2025-04-23 10:40:28 +02:00
drmortalwombat cbf86b2e8f
Merge pull request #219 from polluks/patch-3
Changed make target
2025-04-22 08:21:40 +02:00
Stefan cb757dfaf9
Changed make target
https://www.gnu.org/software/make/manual/html_node/Standard-Targets.html
2025-04-21 22:22:40 +02:00
drmortalwombat 5ad94d01d4
Merge pull request #218 from CTalkobt/main
Correct end address for Mega 65
2025-04-21 20:13:40 +02:00
ctalkobt@ctalkobt.net cdba71b353 Correct end address for M65 2025-04-21 13:46:53 -04:00
drmortalwombat 01d187cf83
Merge pull request #217 from CTalkobt/main
Initial patch to add -tm=mega65 support
2025-04-21 18:48:38 +02:00
drmortalwombat ab06ce74c5 More global namespace fixes 2025-04-21 18:29:01 +02:00
Craig Taylor 1e2b227113
Merge branch 'drmortalwombat:main' into main 2025-04-21 11:53:36 -04:00
ctalkobt@ctalkobt.net 9d5dbe67fe Adjust M65 top of memory to $e000 2025-04-21 11:48:12 -04:00
ctalkobt@ctalkobt.net 9a409ca347 Initial patch to add -tm=mega65 support 2025-04-21 11:12:02 -04:00
drmortalwombat 449acece05 Fix global namespace access 2025-04-21 15:58:49 +02:00
drmortalwombat ee3f6fc4a5 Struct value forwarding 2025-04-21 08:18:55 +02:00
drmortalwombat e95b51609c Optimize loop unrolling 2025-04-18 17:16:56 +02:00
drmortalwombat 323589a484 Optimize compilation time 2025-04-18 12:55:10 +02:00
drmortalwombat 33f4b25f28 Fix C64 ascii to petscii output in conio 2025-04-17 22:38:54 +02:00
drmortalwombat 538d965636 Fix 16bit forward for middle 32bit registers 2025-04-17 18:55:53 +02:00
drmortalwombat 4b99110533 Bump version number 2025-04-10 08:47:24 +02:00
drmortalwombat 94f2489083 Fix TAXA range bypass with trailing multi store 2025-04-08 18:22:45 +02:00
drmortalwombat 6de1b1fd96 Code size optimizations 2025-03-31 17:30:57 +02:00
drmortalwombat 80abcdfe95 Optimize local struct variable usage 2025-03-30 20:22:50 +02:00
drmortalwombat 0dc6588a66 Improve double index register single block loops 2025-03-29 13:30:03 +01:00
drmortalwombat 65ad05c608 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-03-24 08:56:07 +01:00
drmortalwombat 2db8890453 Fix temp spilling in recursive functions 2025-03-24 08:56:03 +01:00
drmortalwombat 3f4268328e
Merge pull request #198 from root42/detect-basic-and-gotoxy-for-pet
Implement gotoxy for PET
2025-03-23 14:54:10 +01:00
Arne Schmitz 33cabb487b pure C implementation 2025-03-23 13:15:09 +01:00
Arne Schmitz ab2ca897ce pure asm implementation of bsplot 2025-03-22 12:31:05 +01:00
Arne Schmitz 2c37e150a9 comment 2025-03-22 12:31:05 +01:00
Arne Schmitz ee68f2575a better implementation, inspired by cc65 2025-03-22 12:31:05 +01:00
Arne Schmitz 4f100266c3 fix ldy 2025-03-22 12:31:05 +01:00
Arne Schmitz c22a67f95f basic version detection and and implement bsplot for PET 2025-03-22 12:31:05 +01:00
drmortalwombat e6bc6371c9 Fix PET target zero page variable range 2025-03-19 17:16:20 +01:00
drmortalwombat 2acca6d7b1 Fix register load/store bypass when register result still needed 2025-03-19 09:38:40 +01:00
drmortalwombat fc2095301d Fix aliasing problem when auto inlining non early embedded assembly stubs 2025-03-16 20:29:03 +01:00
drmortalwombat 32f0b8c6f3 Fix warnings in unreachable code 2025-03-16 15:53:27 +01:00
drmortalwombat 10c9b735e9 Fix short infinite loop code split 2025-03-15 21:17:21 +01:00
drmortalwombat fefb511404 Fix integer range loss in loop index reduction 2025-03-15 17:59:45 +01:00
drmortalwombat bedafe7b6f Fix loss of type reduction in loop causing overflow error 2025-03-15 12:05:34 +01:00
drmortalwombat 242d7f1700 Fix optimizer crash with volatile long ops 2025-03-14 08:10:36 +01:00
drmortalwombat 90e892dfa5
Merge pull request #199 from polluks/patch-2
Fixed install
2025-03-12 08:12:34 +01:00
drmortalwombat c98e0751b0 Fix carry usage check in inline assembler, add optional volatile to __asm 2025-03-12 08:11:23 +01:00
Stefan f3b4a4e5fc
Fixed install
Long options are not POSIX.
2025-03-11 23:01:49 +01:00
drmortalwombat 1c7d71cadb Fix loop unrolling changing boundary constant 2025-03-11 08:19:49 +01:00
drmortalwombat 840050738f Fix compare of enum in striped bitfield 2025-03-09 10:49:23 +01:00
drmortalwombat 2ee5cc7bf4 Fix loss of memory live status when reversing compare 2025-03-07 17:23:50 +01:00
drmortalwombat 490180f9dc Fix compare reversal and reuse if z flag used 2025-03-07 08:17:51 +01:00
drmortalwombat 2582f3076d Fix passing rvalue to non const reference 2025-03-02 15:02:01 +01:00
drmortalwombat 0032d42b2c Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-02-28 16:20:10 +01:00
drmortalwombat 5c70c20c6e Reverse cross block accu to index propagation 2025-02-28 16:20:07 +01:00
drmortalwombat 71236aa405
Merge pull request #193 from polluks/patch-1
Fixed minor typos
2025-02-25 15:50:15 +01:00
Stefan 31a38e2a62
Fixed minor typos 2025-02-25 13:44:32 +01:00
drmortalwombat ee0e4d5428 Fix void pointer arithmetic 2025-02-23 11:04:29 +01:00
drmortalwombat f6296e83e5 Improve outliner for short loops 2025-02-18 14:51:42 +01:00
drmortalwombat 39840b5fb1 Convert add to compare if only flags needed 2025-02-18 11:35:06 +01:00
drmortalwombat fe0bfccfaa Reduce eagerness to join stores with short leas 2025-02-18 09:22:28 +01:00
drmortalwombat 25ee4e9b2b Shortcut known branch cascades 2025-02-17 13:12:28 +01:00
drmortalwombat 9f7d4c0ab0 Improved index register use in short loops 2025-02-16 17:16:27 +01:00
drmortalwombat 038928232c Propagate conditional stores behind blocks 2025-02-15 10:51:55 +01:00
drmortalwombat 100affa083 Reverse zp register alias move across single block loops 2025-02-14 10:40:00 +01:00
drmortalwombat e27075955d Optimize enums in bitfield usage 2025-02-12 15:12:06 +01:00
drmortalwombat 0959a15b10 Fixed striped structs with bitfields 2025-02-09 22:10:39 +01:00
drmortalwombat 4a87e4d97b Fix no inline for overloaded operators 2025-02-08 11:04:19 +01:00
drmortalwombat 9de7caa68d Fix enums in bitfields 2025-02-05 10:57:58 +01:00
drmortalwombat e23d78eb86 Fix move of store abs cross function call 2025-02-01 20:13:18 +01:00
drmortalwombat d0b45fce78 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-01-31 18:43:07 +01:00
drmortalwombat 0126dd53a3 Fix infinite optimizer loop 2025-01-31 18:43:01 +01:00
drmortalwombat 901c8459ec
Merge pull request #186 from seclorum/main
Created a CMakeLists.txt for the project
2025-01-24 20:09:43 +01:00
Jay Vaughan 746fed6704 Get target_sources through glob'ing instead of explicit filenames 2025-01-24 19:07:18 +01:00
Jay Vaughan 54c0f2a670 Created a CMakeLists.txt for the project - oscar64 can now be built on MacOS/Darwin with cmake 2025-01-24 15:17:31 +01:00
drmortalwombat 28ea8ef24f Fix integer value range for ext8to16 unsigned 2025-01-22 21:40:51 +01:00
drmortalwombat 115129e1dd Reorder lda x, cmp y to reuse y 2025-01-21 22:26:57 +01:00
drmortalwombat f41d594015 Fix load/binop/store with different sizes 2025-01-19 21:26:25 +01:00
drmortalwombat c8abb42c3c Optimize outliner compile time performance 2025-01-19 18:10:02 +01:00
drmortalwombat 95732265f6 Add experimental native code outliner 2025-01-19 17:28:20 +01:00
drmortalwombat 9f834c4232 Fix integer type coercion with cast operator 2025-01-18 10:13:29 +01:00
drmortalwombat d10d8bf7ae Optimize index register use for one bit high byte 2025-01-10 21:09:03 +01:00
drmortalwombat f6a2db7866 Reuse index register transfer to avoid compare 2025-01-09 20:12:09 +01:00
drmortalwombat d2fdbd29f5 Add loop sinking optimization 2025-01-09 10:54:45 +01:00
drmortalwombat f5dff9620b Fix degrading merge of stores that prevent absolute addressing 2025-01-07 22:07:36 +01:00
drmortalwombat 28e75a8fa2 Fix invalid double dereference reorder 2025-01-06 22:05:43 +01:00
drmortalwombat 6170c81af3 Improve 8 to 16 bit signed add 2025-01-06 18:54:21 +01:00
drmortalwombat 3d578170db Improve 16bit op pair reordering 2025-01-06 15:58:41 +01:00
drmortalwombat d99499b6e3 Improve double indexed pointer from table 2025-01-04 11:11:37 +01:00
drmortalwombat 950c434157 Improve const range propagation after byte compare 2025-01-04 09:12:56 +01:00
drmortalwombat d6362a305f Improve const bitmask optimization 2025-01-03 14:29:08 +01:00
drmortalwombat 38bb033328 Fix global variable changes bypassing assembly blocks 2024-12-30 18:06:26 +01:00
drmortalwombat 87f1ddd27f Fix usage of assembler labels as pointer initializer 2024-12-29 10:22:01 +01:00
drmortalwombat 9e994560a7 Improve double indexed loop with fixed stride 2024-12-29 09:46:33 +01:00
drmortalwombat e37de95079 Add bounded integer class 2024-12-26 14:57:23 +01:00
drmortalwombat 8e46ae95ec Improve unsigned compare result propagation 2024-12-24 15:23:02 +01:00
drmortalwombat e7cece0f0f Fix debug assert for negative array index intermediate result 2024-12-23 22:31:04 +01:00
drmortalwombat 890a4b996e Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2024-12-22 21:22:08 +01:00
drmortalwombat 5b2ae228cc Improve table pointer forwarding 2024-12-22 21:22:05 +01:00
drmortalwombat 9fc8315f92
Merge pull request #179 from root42/pet-kbhit
kbhit variant for CBM PET
2024-12-18 12:02:31 +01:00
Arne Schmitz 32935cd7a1 use keyboard buffer instead 2024-12-18 11:59:01 +01:00
Arne Schmitz fd02382d38 kbhit variant for CBM PET 2024-12-18 11:47:26 +01:00
drmortalwombat 4fce263228 Optimize hires line draw 2024-12-15 16:34:53 +01:00
drmortalwombat 50c7e10814 Add forward declaration of __asm code 2024-12-08 12:05:02 +01:00
drmortalwombat 7c8ab991be Bump version number 2024-12-07 13:08:37 +01:00
drmortalwombat 067e169803 Fix analysis of register usage of inline assembler 2024-12-06 18:54:55 +01:00
drmortalwombat ccdbbe799a Fix assert in linux autotest 2024-12-05 08:05:43 +01:00
drmortalwombat fac53cfd54 Add "-strict" command line option, to loosen C syntax and allow default arguments when not set 2024-12-03 09:03:43 +01:00
drmortalwombat cfe2c7bed5 Fix infinite loop in parser due to failure to detect label 2024-12-02 16:27:13 +01:00
drmortalwombat f0b9b5cce4 More C++ aggregate initialization 2024-12-02 15:39:14 +01:00
drmortalwombat 803b868356 Improve zero page addressing of global variables in inline assembler 2024-12-01 15:33:51 +01:00
drmortalwombat 907452d918 Fix rirq_sort when called from within interrupt 2024-11-30 13:01:09 +01:00
drmortalwombat c12bca7b4e Fix crash in optimizer due to lack of updated register dependecy set when splitting block in loop 2024-11-30 09:40:26 +01:00
drmortalwombat e1736c8214 Reverse shift with negated distance 2024-11-21 22:02:25 +01:00
drmortalwombat d3e7a991a4 Fix int to bool coercion 2024-11-19 18:42:07 +01:00
drmortalwombat e7b0d17a83 Add some std library functions 2024-11-19 16:22:09 +01:00
drmortalwombat df18dc273e Forward binary op in txax 2024-11-17 21:54:55 +01:00
drmortalwombat b6341e402d Fix const bool to int conversion in loop 2024-11-16 13:48:47 +01:00
drmortalwombat 3f2f703936 Bump version number 2024-11-14 17:37:07 +01:00
drmortalwombat 4acee4531c Remove needless register transfers from inner loops 2024-11-12 13:37:50 +01:00
drmortalwombat 2a476d3372 Fix const void * type propagation 2024-11-07 10:56:21 +01:00
drmortalwombat 0a41cb044c Relax rules for argument forwarding in direct call chains 2024-11-05 17:20:22 +01:00
drmortalwombat 5a0f736d41 Fix in block branch collides with fcall proxy generation 2024-11-05 08:17:18 +01:00
drmortalwombat 020534dbc8 Bump version number 2024-11-03 17:35:19 +01:00
drmortalwombat cee2801847 Fixed negative offset leas 2024-11-03 15:36:53 +01:00
drmortalwombat 51c38a4723 Fix short lea coalescing with negative offsets 2024-11-03 10:14:18 +01:00
drmortalwombat bb01d1024a Fix striped indirect arrays 2024-11-02 14:52:06 +01:00
drmortalwombat 903a5d9b8b
Update README.md 2024-11-02 11:45:31 +01:00
drmortalwombat e360dea558 Fix link text 2024-11-02 11:40:02 +01:00
drmortalwombat 582443ef5c Split readme and reference 2024-11-02 11:36:30 +01:00
drmortalwombat 80a42216c7 Prepare split of readme and manual 2024-11-02 10:30:11 +01:00
drmortalwombat 6576f4d090
Merge pull request #170 from sehugg/main
Fixed stack-use-after-return bug found with -fsanitize=address,undefined
2024-11-01 22:37:25 +01:00
Steven Hugg 55e983e5a1 Fixed stack-use-after-return bug found with -fsanitize 2024-11-01 15:30:17 -05:00
drmortalwombat a6f9c733a1 Fix drop of reading from volatile with discarding result 2024-11-01 20:32:54 +01:00
drmortalwombat 3c129ff4e5 Fix complex diamond pointer forwarding
Forwarding failed when pointer was used and modified in one branch of the diamond
2024-10-31 22:48:34 +01:00
drmortalwombat db386a5958 Fix multi indirection lea propagation 2024-10-31 07:13:30 +01:00
drmortalwombat 179cc694e3 Reduce code size by recycling nearby jmp for far branches 2024-10-27 16:56:35 +01:00
drmortalwombat 887a51b176 Fix array in struct const declaration without braces 2024-10-26 18:35:29 +02:00
drmortalwombat 5b81379dac Fix const structs in arrays without braces 2024-10-26 17:28:13 +02:00
drmortalwombat 4fff9f7060 Add optional static memory profile output file 2024-10-24 13:58:14 +02:00
drmortalwombat 40c407782d Fix uppercase flag in iostream 2024-10-24 07:21:39 +02:00
drmortalwombat 5946f17632 Detangle XY abs load/store pairs 2024-10-22 17:17:29 +02:00
drmortalwombat 7e0ff7449c Fix address/register mismatch in 16bit sum forwarding 2024-10-22 13:21:16 +02:00
drmortalwombat d597219aea Fix loss of memory live status when shortcuting zp shift add 2024-10-21 21:36:18 +02:00
drmortalwombat a311396cf8 Loop optimization for x and y used in simple loop 2024-10-20 18:09:50 +02:00
drmortalwombat 94607cab7f Fix extern const struct merging 2024-10-20 11:11:43 +02:00
drmortalwombat 4d193a30b0 Fix cia init code 2024-10-19 09:19:07 +02:00
drmortalwombat c1ad265f47 Fix memory type propagation in loop strength reduction 2024-10-18 15:24:08 +02:00
drmortalwombat 4e2a2c99ba Fix x reg zp dependency during peephole shuffle 2024-10-17 18:12:08 +02:00
drmortalwombat ea33f253d4 Reduce branches in short basic block sequences 2024-10-15 07:37:35 +02:00
drmortalwombat ebc41560d9 Fix value forwarding register forgetting memory reference 2024-10-13 19:52:52 +02:00
drmortalwombat 2d2c696aa4 Add sprite pad tile import 2024-10-10 16:12:35 +02:00
drmortalwombat b622c25a56 FIx previous case for TYA as well 2024-10-06 22:31:22 +02:00
drmortalwombat 439cf499ed Fix peephole opt for while (x--) 2024-10-06 22:17:29 +02:00
drmortalwombat cd5f1daaba Fixing O3 cases for gcc tests 2024-10-06 16:44:22 +02:00
drmortalwombat ec95f6dc98 Fix dynamic variable initalizer 2024-10-06 13:59:06 +02:00
drmortalwombat 66dfe5df46 Fixed constant array bounds check regression 2024-10-06 12:47:53 +02:00
drmortalwombat 9117827cfc Bump version number 2024-10-05 21:57:23 +02:00
drmortalwombat ad115701d5 Fix sprite pad level 3 read 2024-10-05 21:39:51 +02:00
drmortalwombat a15125d6af Fix crash with const access to zero size array 2024-10-05 14:01:58 +02:00
drmortalwombat dadd8eb41c Extend number of usable variables in assembler block to 32 2024-10-05 13:42:39 +02:00
drmortalwombat 056b49e1d1 Optimize 8 by 16 bit multiply 2024-10-04 20:06:56 +02:00
drmortalwombat 1f492e7820 Improve size optimization 2024-10-03 20:57:01 +02:00
drmortalwombat 4c687dfa54 Improve struct value return propagation 2024-10-03 12:53:11 +02:00
drmortalwombat e1f5bdf48b Add named variadic macro arguments 2024-10-03 10:29:42 +02:00
drmortalwombat 3ba7e0a8a4 Bump Version Number 2024-10-02 21:58:35 +02:00
drmortalwombat a71fae5bb1 Add template based bank switch proxy code 2024-10-02 20:10:47 +02:00
drmortalwombat f6c78d57ef Add __forceinline storage specifier 2024-10-02 18:27:20 +02:00
drmortalwombat 6af50f5eae Add early dead code elimination to speed up template compilation 2024-10-01 18:30:07 +02:00
drmortalwombat 62ab925e01 Add raster IRQ handler for cartridge with ROM switching 2024-10-01 09:45:41 +02:00
drmortalwombat 5126ba482e Fixed placement of static class members 2024-09-30 20:41:33 +02:00
drmortalwombat fb477b33f7 Don't use floats as num counter replacement 2024-09-30 20:33:08 +02:00
drmortalwombat 756fe9354a Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2024-09-30 20:14:02 +02:00
drmortalwombat 73c2206a1a Improve bankof implementation 2024-09-30 20:13:54 +02:00
drmortalwombat c1071ecd3c
Merge pull request #155 from jadziamd/main
Standardise Implementation of get_s C function
2024-09-30 20:13:22 +02:00
John Schneiderman 534ddc3a4c Removes the include for STD bool since it's no longer used. 2024-09-30 20:07:44 +02:00
John Schneiderman ebce50320f Fixes incorrect specification implementation not reading all the
characters.
Simplfies the buffer size checks.
2024-09-30 20:04:33 +02:00
John Schneiderman cfd2e5142a Changes from being mostly assembly to be based upon a C version.
Adds the additional error conditions for get_s: truncation
	and too small buffer.
2024-09-30 19:32:23 +02:00
drmortalwombat 581137ade7 Fix template void return of reference parameter 2024-09-30 16:54:50 +02:00
drmortalwombat c3b46d6a78 Fix condition hoisting side path check 2024-09-30 13:31:31 +02:00
drmortalwombat 84a8bf22e8 Constant folding of pointer type cast 2024-09-29 17:24:42 +02:00
drmortalwombat daeb3ddfdd Add non constant structured initializers 2024-09-29 14:31:05 +02:00
drmortalwombat bf5f5a807c Reduce inline assembly in stdio and conio 2024-09-28 12:25:44 +02:00
drmortalwombat 3dfba389ff Fix command line parsing for -O and -O1 2024-09-28 11:15:49 +02:00
drmortalwombat a4f1341587 bump version number 2024-09-27 20:14:10 +02:00
drmortalwombat 57d8747cb7 Reduce generated code size with -Os 2024-09-27 20:01:22 +02:00
drmortalwombat 1fb68c1bf3 Add -rpt option to generate error map and asm files if linker fails 2024-09-26 20:32:20 +02:00
drmortalwombat 5613a719c5 Fix linux make dependencies 2024-09-26 17:56:55 +02:00
drmortalwombat bf6343616b Fix XY detangling in loop 2024-09-26 14:03:42 +02:00
drmortalwombat 861eeaefe2 Improve signed integer compare 2024-09-26 12:39:38 +02:00
drmortalwombat db3c6a3135 Peephole optimizations 2024-09-26 09:15:09 +02:00
drmortalwombat 4c7dafed25 Bump version number 2024-09-24 11:36:36 +02:00
drmortalwombat b1440a9b3f Fix zero page parameter aliasing 2024-09-23 21:27:27 +02:00
drmortalwombat 21b5e75ddb Improve redundant loop counter removal 2024-09-23 17:53:12 +02:00
drmortalwombat 49893f6976 Fix various gcc torture tests 2024-09-22 21:40:27 +02:00
drmortalwombat c87887cbd1 Fix drop of Y register in asm code 2024-09-22 13:46:29 +02:00
drmortalwombat bcd118a8b3 Fix temporary object structured initialization 2024-09-21 23:02:59 +02:00
drmortalwombat d7bfd0a668 Fix invalid function parameter crossing 2024-09-21 22:00:54 +02:00
drmortalwombat aeceb36e2a Fix reverse 8bit unsigned range 2024-09-21 20:48:38 +02:00
drmortalwombat f67d537c7c Add abort to stddef calling exit(-1) 2024-09-21 18:12:10 +02:00
drmortalwombat 87d2163f2d Fix constant int value function return type coercion 2024-09-21 17:00:34 +02:00
drmortalwombat 639008b990 Fix direction of constant folded ordered bool comparison 2024-09-21 16:48:22 +02:00
drmortalwombat 3c21ecb1d3 Fix constant float and long conversion during data flow analysis 2024-09-21 16:24:24 +02:00
drmortalwombat f764cf1936 Avoid infinite recursion when coercing to base class reference 2024-09-21 15:36:05 +02:00
drmortalwombat 44a9aaf89b Fix range correction for post dec loop counters 2024-09-21 15:17:15 +02:00
drmortalwombat 925ee9d8f3 Fix constant pointer if conditions 2024-09-21 14:38:35 +02:00
drmortalwombat a04b09c737 Fix wrong loop invariant when result temp used before 2024-09-21 13:50:14 +02:00
drmortalwombat 2c9fd0e1a6 Fix immediate coalescing with zero flag loss 2024-09-21 13:06:06 +02:00
drmortalwombat d7c9f15593 Fix constant fold of byte right shift 2024-09-21 12:49:29 +02:00
drmortalwombat b61aa37f71 Disable const parameter optimization in variadic functions 2024-09-21 12:13:19 +02:00
drmortalwombat e80f9812ef Fix invalid destruct on shortcut evaluation 2024-09-20 19:22:12 +02:00
drmortalwombat 84a0a9660f Fix constructor call on declaration 2024-09-20 18:10:01 +02:00
drmortalwombat a93b495ac5 Fix param value range on store with index 2024-09-20 16:15:02 +02:00
drmortalwombat 5d7dcf9373 Fix crash on select statement with void result 2024-09-20 13:26:59 +02:00
drmortalwombat 2f5faaa5ab Fix compare value range of longs 2024-09-20 12:34:01 +02:00
drmortalwombat dfe233a95e Fix pointer to object size propagation 2024-09-19 21:55:24 +02:00
drmortalwombat 92b72b19ec Fix loop wrap around aliasing 2024-09-19 21:01:24 +02:00
drmortalwombat ff4a0802ea Fix invalid memory range requirements due to select statement 2024-09-19 20:05:19 +02:00
drmortalwombat 9adcbd2706 Avoid inline of functions with missing return statement 2024-09-19 18:02:01 +02:00
drmortalwombat 6981b28a64 Fixed assignment of numeric 0 to pointer after inline expansion 2024-09-19 14:24:56 +02:00
drmortalwombat 7f41936df0 Fix constant pointer difference 2024-09-19 14:10:23 +02:00
drmortalwombat ccf72c6b77 Fix returning numeric 0 as nullptr 2024-09-19 13:46:34 +02:00
drmortalwombat c508d94d7c Fix loop exit value of loop counter derived values 2024-09-19 11:27:30 +02:00
drmortalwombat ce710fca5d Add float long conversion 2024-09-19 09:49:16 +02:00
drmortalwombat ce0ac30280 Fix value propagation in loop dependency analysis 2024-09-19 08:12:04 +02:00
drmortalwombat dec7580d8d Revert address of array type to pointer to array
not realy sure why I changed it in the first place
2024-09-19 07:47:34 +02:00
drmortalwombat 40001164d4 Fix missing error in const function return 2024-09-18 22:33:40 +02:00
drmortalwombat 8bd5ec76c3 Fix optimizing loop with subtract negative constant on counter 2024-09-18 18:30:53 +02:00
drmortalwombat 534a42d2fe Implement C vs C++ void pointer semantics 2024-09-18 16:27:16 +02:00
drmortalwombat 226d8afc24 Fix type handling in pointer const folding 2024-09-18 14:47:09 +02:00
drmortalwombat 47531ac5e8 Fix flat initializer for stacked arrays 2024-09-18 14:14:11 +02:00
drmortalwombat b3be121f41 Fix constant fold mixed signed long 2024-09-17 20:53:13 +02:00
drmortalwombat e7e53580ea Add ul / lu suffix for numbers 2024-09-17 20:30:41 +02:00
drmortalwombat 8a1eeee22d Fix arrow dereferencing of array variables 2024-09-17 15:34:41 +02:00
drmortalwombat 3e78933e9c Fix negative range propabation on binary or 2024-09-17 15:19:01 +02:00
drmortalwombat 637a10b234 Fix float const propagation 2024-09-17 14:49:07 +02:00
drmortalwombat c5dff3caf3 Fix sizeof string literals with zero byte 2024-09-17 14:27:23 +02:00
drmortalwombat c529fc2b59 Fix lvalue in switch expression 2024-09-17 09:31:01 +02:00
drmortalwombat 4886d0194f Fix bit field member naming and placement 2024-09-17 09:19:16 +02:00
drmortalwombat aae7d81cc6 Fix bitfield delcaration in function local struct 2024-09-16 22:30:19 +02:00
drmortalwombat 8d18969940 Fix unsigned division constant folding 2024-09-16 18:05:03 +02:00
drmortalwombat 68b57bb9a8 Fix short param forwarding of struct elements 2024-09-16 17:45:32 +02:00
drmortalwombat 5aeec2fad4 Fix function pointer const propagation 2024-09-16 17:16:45 +02:00
drmortalwombat 73dece7b58 Fix crash with unnamed unions 2024-09-16 16:45:51 +02:00
drmortalwombat bfa1254eb7 Fix octal string escaped 2024-09-16 16:36:06 +02:00
drmortalwombat e89aa11e86 Implement parse of octal numbers 2024-09-16 13:31:03 +02:00
drmortalwombat 4423837888 fixed varadic function inlining 2024-09-15 20:18:33 +02:00
drmortalwombat 723f407757 FIx unary not for unsigned const long 2024-09-15 19:54:00 +02:00
drmortalwombat f2338f1d13 Allow "long unsigned" type 2024-09-15 18:38:53 +02:00
drmortalwombat 235cbbc227 Add list expressions in for statement 2024-09-15 18:31:10 +02:00
drmortalwombat a2ca0de809 Fix compare pointer to rvalue refs 2024-09-15 16:14:44 +02:00
drmortalwombat f7b00eff95 Fix object array member init regression 2024-09-15 13:00:33 +02:00
drmortalwombat 163354b33e
Merge pull request #94 from jadziamd/main
Adds Diagnostic Directives & Fixes comparison between different enumeration types
2024-09-15 12:16:24 +02:00
drmortalwombat 7efd512ee9 Fix class member array initialization 2024-09-15 12:13:28 +02:00
John Schneiderman 7b7fe6c5a9 Adds the warning diagnositc directive. 2024-09-15 10:49:33 +02:00
John Schneiderman 7abd615a18 Adds support for the error diagnostic directive. 2024-09-15 10:28:25 +02:00
John Schneiderman 14e5896e37 Fixes comparison between different enumeration types. 2024-09-15 08:53:38 +02:00
drmortalwombat 381aaa1509 Fix compiler crash with empty switch statement 2024-09-11 13:13:40 +02:00
drmortalwombat f0f174e439 Optimize conditional select of const values 2024-09-10 22:26:34 +02:00
drmortalwombat 1f9226255a Fix default member constructor for single sized member arrays 2024-09-04 12:17:58 +02:00
drmortalwombat dcfa50e36e Fix float fast parameter aliasing 2024-09-02 22:01:50 +02:00
drmortalwombat 0b2c36ab1a Fix for sidfx in tight loop
Change might have been disregarded due to missing volatile
2024-09-02 15:26:05 +02:00
drmortalwombat 0163fb729a
Merge pull request #86 from polluks/patch-1
Shorter build call
2024-09-02 13:03:42 +02:00
Stefan d6c4828bef
Shorter build call 2024-09-02 11:05:00 +02:00
drmortalwombat e7dbd39adf Fix macos build 2024-09-01 09:51:11 +02:00
drmortalwombat 759a701df8 Add kernal banking for plus/4 kernalio.c 2024-08-30 18:40:48 +02:00
drmortalwombat 17ec90cfe7 Bump version number 2024-08-29 14:36:08 +02:00
drmortalwombat e7ec859dfc Fix unused parameter optimization for deep call stacks 2024-08-29 14:18:01 +02:00
drmortalwombat da93410468 Fix cascaded type casts 2024-08-29 13:34:55 +02:00
drmortalwombat f38b366d81 Fix error message for undefined identifier in case statement 2024-08-27 08:05:28 +02:00
drmortalwombat 8fbe96b9ac Add options to disable BSS clear on startup 2024-08-23 20:31:17 +02:00
drmortalwombat b48b8b836d Extended line limit to 32k 2024-08-23 18:16:42 +02:00
drmortalwombat 967b315be5 Add qualified constructor invocation 2024-08-23 17:53:58 +02:00
drmortalwombat ca995bf342 Fix zero delimiter on opp::string for fixed range string constructor 2024-08-21 19:28:40 +02:00
drmortalwombat c58bb46e7e Fix invalid abs,y to abs,x propagation 2024-08-18 13:26:35 +02:00
drmortalwombat 122dc12d40 Eliminate stores to unused function arguments 2024-08-17 20:55:00 +02:00
drmortalwombat cc576bd640 Fix name space pollution in __asm sections 2024-08-17 17:03:57 +02:00
drmortalwombat 09641d16f5 Add PLx and PHx to non simple asm instructions 2024-08-17 16:08:36 +02:00
drmortalwombat 552c4945bf Fix template expansion of out of class constructor/destructor 2024-08-16 18:03:32 +02:00
drmortalwombat 34d6131471 Fix __asm example in readme 2024-08-15 17:00:57 +02:00
drmortalwombat 9ecf1546cc Fix invalid "ldx abs,x" code generation when propagating 16bit values in merge tree 2024-08-14 22:53:14 +02:00
drmortalwombat 7ffa623d92 Fix clrscr() for VIC20 2024-08-13 19:16:19 +02:00
drmortalwombat 8e81e6aad5
Merge pull request #82 from polluks/main
Fixed sh #81
2024-08-12 14:55:02 +02:00
Stefan 3a3a76a2e1
Update makefile 2024-08-12 14:23:40 +02:00
drmortalwombat 4027b2dbe0 Add optional define for basic upstart line 2024-08-11 14:54:50 +02:00
drmortalwombat 62cede95ce Optimize right shift with small 16 bit values 2024-08-11 14:11:07 +02:00
drmortalwombat abb2d7a417
Merge pull request #79 from jadziamd/main
Support Installed Oscar64 Usage
2024-08-11 14:03:59 +02:00
John Schneiderman f9afb3edb7 Fixes being unable to use the compiler when
installed in the system.
2024-08-11 13:41:55 +02:00
John Schneiderman 32c090880b Adds the definition files as they're needed when
building code outside the repository.
2024-08-11 13:28:59 +02:00
drmortalwombat be5626adc9
Merge pull request #78 from jadziamd/main
Adds the ability to build from the top-level directory.
2024-08-11 10:18:23 +02:00
John Schneiderman b1c68d04dd Adds the ability to build from the top-level directory. 2024-08-11 09:59:53 +02:00
drmortalwombat f9b7dd8418 Fix breakpoint to tail jmp conversion 2024-08-09 20:14:45 +02:00
drmortalwombat 8a6e3eb924 Add breakpoint intrinsic in oscar.h 2024-08-09 18:05:44 +02:00
drmortalwombat 932c7ec222 Fix static stack in recursion
Fix static stack allocation and placement for non recursive sub trees in a recursive call tree
2024-08-09 16:18:38 +02:00
drmortalwombat e4e997fef2 Fix gcc build autotest 2024-08-08 22:47:18 +02:00
drmortalwombat 3ec8a7bc06
Merge pull request #74 from jadziamd/main
Change to a packagable makefile
2024-08-08 22:08:20 +02:00
drmortalwombat d98c4b760f Optimize sprite multiplexer 2024-08-08 22:07:44 +02:00
John Schneiderman d67980d79f Updates the instructions on how to build. 2024-08-08 20:34:19 +02:00
John Schneiderman 092592a05b Adds an installation target.
Adds an uninstallation target.
2024-08-08 20:16:11 +02:00
John Schneiderman 586fab6b6b Changes to use a top-level variable for the Oscar compiler uses. 2024-08-07 21:24:40 +02:00
John Schneiderman eab2a490f4 Adds the tests to the all target.
Silences the cleaning targets.
2024-08-07 20:39:05 +02:00
John Schneiderman 95992df67d Adds the samples building to the all target. 2024-08-07 20:14:56 +02:00
John Schneiderman 89ba57e18d Adds disclean and prep targets for building. 2024-08-07 19:43:27 +02:00
drmortalwombat 6f069946ba Pointer arguments in constexpr evaluation 2024-08-05 18:19:54 +02:00
drmortalwombat 3df85b09fc Align heap allocation on four byte boundaries 2024-08-04 18:02:04 +02:00
John Schneiderman fb5b69ae5c Changes to use commands from variables. 2024-08-04 17:32:13 +02:00
John Schneiderman 7350b11001 Changes to compile all the files in the build directory. 2024-08-04 17:08:19 +02:00
John Schneiderman b7d7614471 Determines the directory lcoation of the project. 2024-08-04 16:47:25 +02:00
drmortalwombat f49027b2d7 Fix loss of carry when moving shift up to store 2024-08-04 11:53:26 +02:00
drmortalwombat d24e666f92 Fix left shift 1ul for upper 16 bits 2024-08-03 19:18:17 +02:00
drmortalwombat 2ba46283b2 Optimize line draw for vertical/horizontal lines 2024-08-02 19:56:38 +02:00
drmortalwombat 65b9c58504 Move zero page shift up to previous store 2024-08-01 22:19:16 +02:00
drmortalwombat 02a2874a19 Bump version number 2024-08-01 15:49:51 +02:00
drmortalwombat 60868c71d3 Fix single tail loop opt for search loops (e.g. strlen) 2024-07-31 21:11:13 +02:00
drmortalwombat 9013952431 Fix missing int range adaption on complex address optimization 2024-07-31 17:59:20 +02:00
drmortalwombat 0b8304b40d More cross block const pointer forwarding 2024-07-28 17:52:07 +02:00
drmortalwombat 1bc5a2ad7e Add compile time error for undefined labels 2024-07-28 14:41:29 +02:00
drmortalwombat 5bb8ca0b89 Improve fix point arithmetic 2024-07-28 14:41:17 +02:00
drmortalwombat 7ecd6adb20 Improve global address in register reuse 2024-07-24 15:31:23 +02:00
drmortalwombat 5b50389340 Optimize 32bit shifts 2024-07-21 21:43:59 +02:00
drmortalwombat 5f2e05d1dd Fix some partial value forwarding errors 2024-07-21 17:53:52 +02:00
drmortalwombat 3cc37acaa4 Bump version number 2024-07-21 11:47:37 +02:00
drmortalwombat 4680ee32f0 Allow defines for #embed arguments 2024-07-21 11:12:34 +02:00
drmortalwombat 3dd23ec789 Additional register allocation step after late inlining 2024-07-21 10:40:37 +02:00
drmortalwombat efd688320f Improve peephole optimizer for shifts 2024-07-18 14:18:06 +02:00
drmortalwombat d0fb062006 Make log and exp intrinsics for const evaluation 2024-07-17 12:42:15 +02:00
drmortalwombat c229a27992 Improve cross loop value propagation 2024-07-16 08:36:52 +02:00
drmortalwombat d3536a718e Merge partially common register loads across basic blocks 2024-07-13 20:44:49 +02:00
drmortalwombat 5909db71d5 Fix loss of dependency when propagating (zp),y single use load across basic blocks 2024-07-12 21:02:46 +02:00
drmortalwombat 96ada6e22a Optimize int->long conversion for known positive values 2024-07-11 16:32:11 +02:00
drmortalwombat 85f01b833c Fix invalid index propagation 2024-07-10 18:49:10 +02:00
drmortalwombat 68a648440a Fix crash on short lea optimization due to lost temp dependencies 2024-07-10 18:31:32 +02:00
drmortalwombat a3bf7296bb Reduce index register usage, where ORA Imm would suffice 2024-07-09 11:24:02 +02:00
drmortalwombat dd1f5b9043 Fix literal string concatenation in parser 2024-07-07 21:18:17 +02:00
drmortalwombat fcc2cbbebe Remove superfluous CPX/CPY with #0 2024-07-06 15:08:03 +02:00
drmortalwombat 470462fe8b Optimize consecutive increments 2024-07-05 22:59:16 +02:00
drmortalwombat 301431f12a Eliminate duplicate loop counting variables 2024-07-05 10:12:55 +02:00
drmortalwombat c0e524cd82 Bump version number 2024-07-04 11:01:58 +02:00
drmortalwombat 4068957442 Fix register dependency update in multi block loop optimization 2024-07-04 10:42:22 +02:00
drmortalwombat bf89d7af33 Improve loop register allocation 2024-07-03 22:23:27 +02:00
drmortalwombat d070e32b4d Loop unrolling for pointer limited short loops 2024-06-30 21:54:56 +02:00
drmortalwombat ad310f8484 Fix sign flag propagationa after immediate ora 2024-06-30 21:28:35 +02:00
drmortalwombat 7eb149a71b Optimize value range of right shifts 2024-06-30 15:45:34 +02:00
drmortalwombat 1c0db235a8 Fix emulator cycle count 2024-06-30 12:29:41 +02:00
drmortalwombat 94181326ca Add uppercase -D for define without separate argument 2024-06-28 16:00:48 +02:00
drmortalwombat cd7567452a Fix return of reference of simple type from inlined function into non ref argument 2024-06-27 19:34:57 +02:00
drmortalwombat 2fec9f066f Refactor large peephole optimizer loop 2024-06-27 15:28:21 +02:00
drmortalwombat fe736289e6 Fix goto to label connection in inlined functions 2024-06-25 21:56:36 +02:00
drmortalwombat 715f295f5e Add goto and labels in C code 2024-06-25 20:45:44 +02:00
drmortalwombat a71c433fc4 Add -D for gcc compliant defines 2024-06-24 18:14:07 +02:00
drmortalwombat 9678814654 Fix crash with extern object pointer arithmetic 2024-06-23 17:05:46 +02:00
drmortalwombat 1598360b65 Fix relational bool ops constant folding 2024-06-22 15:41:02 +02:00
drmortalwombat 9d890228bf
Merge pull request #68 from Kopromaster/main
Windows: support of GCC (MinGW)
2024-06-22 13:56:57 +02:00
Test User 2d82727565 Fixed spacing 2024-06-21 23:17:09 +02:00
Kopromaster 3851a4c2db
Merge branch 'drmortalwombat:main' into main 2024-06-21 21:08:24 +00:00
Test User 17f56d0a69 Bugfix for GCC: order of objects and libs matters; prepared list of libs for GCC (MinGW) 2024-06-21 23:00:17 +02:00
drmortalwombat 1a6a98e57e Reduce stack usage when compiled with MSVC due to optimizer function size limit 2024-06-21 12:04:39 +02:00
Test User 5ddfc628dc Bugfix: __try and __except are MSVC specific 2024-06-20 23:01:46 +02:00
drmortalwombat bf5099f57b Improve auto inline heuristics 2024-06-20 21:02:55 +02:00
drmortalwombat d4a381f71c Fix size heuristic of loop condition slicing 2024-06-20 09:42:22 +02:00
drmortalwombat 17002e4c78 More native code load/store forwarding 2024-06-19 21:40:38 +02:00
drmortalwombat cf9a006005 Retain Z flag when restoring Y after index reduction 2024-06-19 17:45:20 +02:00
drmortalwombat 1fa9828f6a Add additiona raster irq for kernal with potential no IO 2024-06-18 20:35:38 +02:00
drmortalwombat 3f9d042863 Optimize xy before loop index register assignment 2024-06-18 16:08:53 +02:00
drmortalwombat 277afd156d Fix over eager const pointer forwarding 2024-06-16 09:01:36 +02:00
drmortalwombat b428b608b5 Fix extern undefined struct in header file 2024-06-15 17:24:04 +02:00
drmortalwombat 58361e39b8 Fix crash on late const typecast to pointer 2024-06-15 13:35:17 +02:00
drmortalwombat 3770a05aee Add fast loader library flossiec 2024-06-13 21:16:42 +02:00
drmortalwombat 5993f75c92 Bump version number 2024-06-12 21:30:16 +02:00
drmortalwombat d7a2b98b4d Add buffered lzo decompress 2024-06-12 21:07:58 +02:00
drmortalwombat 02b28096af fix pragma optimize inline 2024-06-12 07:36:30 +02:00
drmortalwombat 02e921364b Add support for charpad 9 format 2024-06-11 22:26:10 +02:00
drmortalwombat 4cf64ee170 Fix loop inversion invariant integer range recovery 2024-06-11 21:01:20 +02:00
drmortalwombat c99c1756a9 Fix parameter address reference in __asm embedding 2024-06-11 13:07:50 +02:00
drmortalwombat 5ccfab0342 Fix IEC code for non interrupt usage 2024-06-11 12:12:29 +02:00
drmortalwombat 42eea7f8f4 Mark krnio_save as noinline to ensure zpage params 2024-06-10 22:36:07 +02:00
drmortalwombat ff6bb8ccd5 Fix type of addressof reference 2024-06-08 16:48:44 +02:00
drmortalwombat 2e3aea9d96 Fix reference parameter capture 2024-06-08 16:43:33 +02:00
drmortalwombat 4954a285e7 Add interleave option for sectors in disk image 2024-06-05 22:21:21 +02:00
drmortalwombat 46b52a57f7 Add binary not operator to inline assembler operand parsing 2024-06-04 09:07:50 +02:00
drmortalwombat 41ba2e73f2 Fix labels in inline assembler with an offset > 255 2024-06-03 13:06:45 +02:00
drmortalwombat fbc9607e17 Ensure actual update of index variable in loops in non debug builds 2024-05-30 17:51:59 +02:00
drmortalwombat 2e696d9e1a Optimize small inline function calls 2024-05-30 17:51:34 +02:00
drmortalwombat b09e9a2434 Delete oscar64.zip 2024-05-28 10:11:39 +02:00
drmortalwombat 2e1c020db4 Bump version number 2024-05-26 08:43:14 +02:00
drmortalwombat 13629c70d4 Fix auto deduction of void return type 2024-05-25 22:25:59 +02:00
drmortalwombat b1b5ee737b Fix functional for no parameters 2024-05-25 22:05:31 +02:00
drmortalwombat 884fe50dd7 Add missing assigns for opp::function 2024-05-25 21:26:23 +02:00
drmortalwombat af38f64a99 Add opp::function 2024-05-25 21:25:02 +02:00
drmortalwombat a22dfa6ba7 Add pure virtual functions 2024-05-23 21:15:47 +02:00
drmortalwombat 9fa8b644a7 Add object placement retry if page locking does not fit 2024-05-23 09:54:07 +02:00
drmortalwombat 375307822e Fix auto template expansion of class constructor 2024-05-22 22:44:53 +02:00
drmortalwombat c0152b1ce4 fix template deduction for member functions 2024-05-22 20:53:23 +02:00
drmortalwombat 3460c06508 Improve strength reduction in loops 2024-05-22 20:36:22 +02:00
drmortalwombat d3734a66e0 Fix complex loop intercode index reversal 2024-05-22 12:16:30 +02:00
drmortalwombat ccf13c78f0 Fix index register conflict when removing condition check after load 2024-05-21 22:03:51 +02:00
drmortalwombat 2c28551ca3 Improve index register cross block handling 2024-05-20 16:24:28 +02:00
drmortalwombat 4fb35a7af2 Add error when exceeding assembler limits 2024-05-20 09:03:41 +02:00
drmortalwombat a2a22476ed Add constexpr pointers for inline assembler 2024-05-19 22:20:52 +02:00
drmortalwombat 1b22a5e3c5 Fix constant fold error 2024-05-19 21:38:19 +02:00
drmortalwombat ab06d85a91 Add global inline assembler optimization for static const to immediate propagation 2024-05-19 20:48:14 +02:00
drmortalwombat 80b1683fa2 Document member offset in inline assembler 2024-05-19 19:14:01 +02:00
drmortalwombat d79aae3078 Fix inline mapper for inline assembler 2024-05-19 19:11:48 +02:00
drmortalwombat 4c0e737508 Fix over eager pre processor tokenizer 2024-05-19 17:16:14 +02:00
drmortalwombat 86e0cbf9c2 Alternate forward and backward int value range check 2024-05-19 10:19:42 +02:00
drmortalwombat 142bc988b1 Bump version number 2024-05-17 13:12:24 +02:00
drmortalwombat 3ea44d1979 Fix usage of "ldx abs,x" in some corner cases 2024-05-16 17:45:36 +02:00
drmortalwombat 04d1abd803 Some peephole loop optimizations 2024-05-12 21:06:50 +02:00
drmortalwombat ba1bc29b1a Fix X vz Z flag swapping 2024-05-05 20:54:21 +02:00
drmortalwombat 37776dfaee Remove more conditional branches from loops 2024-05-05 13:14:23 +02:00
drmortalwombat c28f342f3e Remove some superflous range violation warnings 2024-05-03 14:54:58 +02:00
drmortalwombat 354a420aa4 Bump version number 2024-05-01 15:49:17 +02:00
drmortalwombat fb72e8baf8 Fix over eager parameter reordering 2024-05-01 15:30:18 +02:00
drmortalwombat 976703f713 Fix O2 parameter forwarding optimization 2024-05-01 14:08:42 +02:00
drmortalwombat dc5afa6e79 Fix shift optimization had wrong address check 2024-04-30 08:51:22 +02:00
drmortalwombat 740762d4a1 Fix loss of zero flag in 16bit optimization 2024-04-30 08:06:20 +02:00
drmortalwombat f0b7cddeb1 Optimize indirecte 16bit store by flipping low/high order 2024-04-28 21:13:41 +02:00
drmortalwombat 9b47a34840 Improve reordering of function arguments 2024-04-28 20:15:17 +02:00
drmortalwombat bb8c31bf32 Some peephole optimization 2024-04-23 20:54:48 +02:00
drmortalwombat 87ca43e5b7 Add spritepad version 1 file parsing 2024-04-23 17:51:42 +02:00
drmortalwombat 411648b130 Improve long counting loops 2024-04-22 22:48:15 +02:00
drmortalwombat 611f672b81 Add warning for static buffer overflow 2024-04-15 15:40:37 +02:00
drmortalwombat 755c9234e1 Update C128 exit code 2024-04-13 19:49:40 +02:00
drmortalwombat c3c0583f19 Fix const array dereference 2024-04-12 16:51:26 +02:00
drmortalwombat 55ddce2211 Fix const array access folding 2024-04-12 16:11:47 +02:00
drmortalwombat 5971f9a80f bump version number 2024-04-12 15:54:54 +02:00
drmortalwombat fbfd597306 Fix float param to const propagation 2024-04-12 15:50:46 +02:00
drmortalwombat 0184a550c5 Fix volatile violation when recycling immediates 2024-04-10 15:15:22 +02:00
drmortalwombat 2cdc95ba05 Fix assert in samples 2024-04-09 15:57:53 +02:00
drmortalwombat fefa462730 Improve zero page variable usage 2024-04-08 22:04:50 +02:00
drmortalwombat 7b20e6cca0 Optimize 16 bit counting loops 2024-03-31 14:29:22 +02:00
drmortalwombat ed82e3595b Bump version number 2024-03-30 10:40:00 +01:00
drmortalwombat 6cfdc0ce5f Fix removal of consecutive indexed stores in unrolled loop 2024-03-29 18:49:58 +01:00
drmortalwombat 1f17f1c198 Fix assert in peephole optimizer 2024-03-26 08:23:13 +01:00
drmortalwombat 99da637734 Fix include guard of kernalio.h 2024-03-25 12:25:56 +01:00
drmortalwombat afcc8bc101
Merge pull request #53 from Ecte86/patch-2
Update kernalio.h
2024-03-25 12:24:00 +01:00
Ecte 4b2525b7a4
Update kernalio.h
Removed extra "#ifndef C64_KERNALIO_H" to fix "unterminated conditional directive" error.
2024-03-25 17:38:27 +10:30
drmortalwombat aa601a5727 Change memset and memclr to intrinsic functions 2024-03-24 11:22:13 +01:00
drmortalwombat 85fad64e9c Optimize post inc/dec while loop conditions 2024-03-21 19:33:50 +01:00
drmortalwombat 30d942478f Fix infinite loop in move condition out of loop 2024-03-13 22:14:29 +01:00
drmortalwombat 89750c3f73 promote array of const members to be const as well 2024-03-11 13:40:54 +01:00
drmortalwombat ee43223543 Fix missing member definition in opp string 2024-03-09 14:16:28 +01:00
drmortalwombat 89ac4ee9b9
Merge pull request #52 from Ecte86/patch-1
added standard c++ method c_str to opp::string that calls cstr method.
2024-03-09 14:14:32 +01:00
Ecte b411178aae
added standard c++ method c_str to opp::string that calls cstr method.
This should help Intellisense while allowing code that still uses the cstr method to work.
2024-03-09 19:44:59 +10:30
drmortalwombat 45246a2f2d Fix variable size when defining extern struct with anon struct 2024-03-07 20:42:21 +01:00
drmortalwombat 0c43952e37 Improve constant branch forwarding 2024-03-07 13:20:39 +01:00
drmortalwombat f877e5b8c2 Fix assert in linux sample build 2024-02-28 21:26:25 +01:00
drmortalwombat 2d50d56606 Fix copy and load with striped arrays 2024-02-27 18:02:12 +01:00
drmortalwombat bdecbe77e4 Fix 16bit zero page global variable inc/dec 2024-02-27 09:08:56 +01:00
drmortalwombat f39cb38eb3 Fix unary ops on striped struct members 2024-02-26 20:38:02 +01:00
drmortalwombat 148c288942 Add extract char operator to istream 2024-02-26 18:22:21 +01:00
drmortalwombat e2f822e7d1 Improve short function call loop 2024-02-25 18:43:53 +01:00
drmortalwombat 0b58e9eaaf Fix global aliasing collision with striped data 2024-02-25 18:00:10 +01:00
drmortalwombat 0a76a57f18 Bump version number 2024-02-24 15:50:47 +01:00
drmortalwombat 22ffbfa63c Fix source location when coalescing JSR and RTS in JMP 2024-02-24 09:52:32 +01:00
drmortalwombat 94a3097ba7 Fix find loop optimization with mirrored condition 2024-02-21 15:05:17 +01:00
drmortalwombat c05bd269ad Fix stop petscii definition 2024-02-21 12:12:29 +01:00
drmortalwombat aab71cbab3 Add more std c include files 2024-02-20 14:16:32 +01:00
drmortalwombat 1041ef03eb Bump version number 2024-02-19 14:30:53 +01:00
drmortalwombat e2f36bbb9a Fix parse embed with hex skip or size setting 2024-02-19 14:19:15 +01:00
drmortalwombat 5e9df61ffc Fix read after write hazzard in function param proxy size optimization 2024-02-18 20:35:07 +01:00
drmortalwombat cc5a90ac21 Fix long unsigned int comparison 2024-02-18 18:30:51 +01:00
drmortalwombat 3900e1cf92 fix pragma strings with petscii 2024-02-18 17:57:27 +01:00
drmortalwombat 6b98a44fc0 Improve auto inlining decision with O2 2024-02-18 14:35:41 +01:00
drmortalwombat 2698595302 bump version number 2024-02-18 10:02:29 +01:00
drmortalwombat f6ab79319f More compatibility fixes for -psci 2024-02-18 09:31:05 +01:00
drmortalwombat 264a80d88e Pausing petscii string options for #include and #embed 2024-02-17 17:43:24 +01:00
drmortalwombat 020ab117a4 Fix value copy crossing function call 2024-02-17 17:37:47 +01:00
drmortalwombat 8457316815 Fix unsigned promotion for binary not operator 2024-02-17 13:10:14 +01:00
drmortalwombat 58ffe2ad06 Fix hex arguments for pragmas 2024-02-17 12:53:31 +01:00
drmortalwombat 6f7efd9efc Optimized long multiply 2024-02-17 12:06:15 +01:00
drmortalwombat b84cce7609 Improve compatibility with some C quirks 2024-02-16 21:39:35 +01:00
drmortalwombat 8fc382c11e Fix high byte address calculation cascade 2024-02-15 20:52:10 +01:00
drmortalwombat fadcb61bc7 bump version number 2024-02-15 16:20:15 +01:00
drmortalwombat 7ebf71b161 Switch to Visual Studio 2022 toolset 2024-02-15 15:36:25 +01:00
drmortalwombat 003550337a Fix debug and linux build 2024-02-15 13:29:02 +01:00
drmortalwombat c909995011 Reduce compiler memory footprint 2024-02-15 09:58:26 +01:00
drmortalwombat 18cfbc713a Force some inline calls in vdc 2024-02-14 15:24:01 +01:00
drmortalwombat 806539a2d6 add "tan" to intrinsic functions 2024-02-13 20:49:11 +01:00
drmortalwombat 77f035e2b5
Merge pull request #47 from polluks/patch-1
Fixed warning
2024-02-13 19:12:33 +01:00
Stefan 1d49e0a987
Fixed warning
c++ -c -g -O2 -std=c++11 -Wno-switch ../oscar64/oscar64.cpp -o oscar64.o
../oscar64/Scanner.cpp:768:29: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
                                        while (mTokenString[i] = def->mString[i])
                                               ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
../oscar64/Scanner.cpp:768:29: note: place parentheses around the assignment to silence this warning
                                        while (mTokenString[i] = def->mString[i])
                                                               ^
                                               (                                )
../oscar64/Scanner.cpp:768:29: note: use '==' to turn this assignment into an equality comparison
                                        while (mTokenString[i] = def->mString[i])
                                                               ^
                                                               ==
1 warning generated.
2024-02-13 18:28:33 +01:00
drmortalwombat bcc20d3986 Switch to x64 compiler binary 2024-02-13 16:53:44 +01:00
drmortalwombat 431c5d3282 Add info message, if object cannot be placed by linker 2024-02-12 18:06:30 +01:00
drmortalwombat ce5be92225 Fix linux build 2024-02-12 17:40:03 +01:00
drmortalwombat 2ed3d8b445 Bump version number 2024-02-04 11:26:37 +01:00
drmortalwombat f498da5e42 Add __DATE__ and __TIME__ defines 2024-02-04 10:45:02 +01:00
drmortalwombat 7d6eb36ee7 Fix assignment of immediates to returned struct 2024-02-04 09:43:52 +01:00
drmortalwombat ecaab1b5b3 Fix crash compiling infinite loop 2024-01-30 15:04:13 +01:00
drmortalwombat 623b511ce6 restore order of vdc 16 bit writes 2024-01-29 12:42:13 +01:00
drmortalwombat 80efe2351b Optimize short wait loop handling 2024-01-28 19:09:59 +01:00
drmortalwombat 91c907be7e Improve BYT operands in inline assembler 2024-01-28 09:39:40 +01:00
drmortalwombat fafbbe82d1 Fix prevent swap of X and Y when used in JSR 2024-01-27 19:50:34 +01:00
drmortalwombat b3d80bcb0f Limit inline asm check to same section 2024-01-27 17:50:53 +01:00
drmortalwombat 4901e015f6 Undo JSR optimization for testing 2024-01-27 17:48:30 +01:00
drmortalwombat fdb52bcdc6 Limit JSR->JMP forwarding 2024-01-27 17:43:08 +01:00
drmortalwombat 974688a8a5 Fix overlay prg file save 2024-01-27 17:11:10 +01:00
drmortalwombat 2ad71ef867 Bump version number 2024-01-27 10:26:22 +01:00
drmortalwombat c1083b44dc Optimize constant loops 2024-01-27 10:19:14 +01:00
drmortalwombat b0dc6fdd1e Add save as .prg for overlay files 2024-01-27 09:37:48 +01:00
drmortalwombat 7f51d6330e Fixed 1 - i for bytes, wrong operand order 2024-01-26 12:41:13 +01:00
drmortalwombat 3992b1d547 Add warning for out of bounds accesses 2024-01-24 17:30:03 +01:00
drmortalwombat 2c1a87ce02 Control assert with _DEBUG to avoid gcc core dump 2024-01-23 16:53:30 +01:00
drmortalwombat 529618ffa4 Changed error format to "oscar64:" when error outside of source file 2024-01-23 15:58:47 +01:00
drmortalwombat bcc5e9d362 Fix propagation of conditions out of loops 2024-01-23 09:02:38 +01:00
drmortalwombat 6444ba58cf bump version number 2024-01-21 15:39:26 +01:00
drmortalwombat 4fc3e019d5 Add ranges in case statements (gcc extension) 2024-01-21 15:17:46 +01:00
drmortalwombat dcebdeaa5f Fix parsing of trailing comma in initializer list 2024-01-21 09:25:34 +01:00
drmortalwombat 8a49ffd111 Improve unrolled loops towards zero 2024-01-20 13:49:25 +01:00
drmortalwombat a19469d851 Fix exportet variable alignment calculation 2024-01-16 08:12:47 +01:00
drmortalwombat 265be6e766 Move linker chattyness into -v2 2024-01-12 22:51:11 +01:00
drmortalwombat cac7db4358 Fix memory size mismatch in reverse integer range propagation due to register renaming 2024-01-10 22:59:45 +01:00
drmortalwombat 4eaa6c8b1e Add immediate variable address parameter in inline assembler 2024-01-10 12:22:46 +01:00
drmortalwombat 9a0256449b
Merge pull request #43 from xahmol/main
Proposals for krnio additions: setbnk and save
2024-01-10 11:49:35 +01:00
Xander Mol 299374aa50 Proposals for krnio additions: setbnk and save 2024-01-09 23:50:46 +01:00
drmortalwombat 5634abdba4 Fix compiler warnings on linux/macos 2024-01-09 20:04:40 +01:00
drmortalwombat a6b3533e61 Fix struct volatile cast 2024-01-08 20:41:48 +01:00
drmortalwombat 4ea3633b5a Fixed fix 2024-01-08 20:11:11 +01:00
drmortalwombat bcf19136d4 Fix zp clear in C128 on exit 2024-01-08 20:10:46 +01:00
drmortalwombat 1abdd1476e Fix error message when propagating invalid function parameter to const 2024-01-08 18:20:55 +01:00
drmortalwombat 7f31ee9c71
Merge pull request #41 from polluks/patch-1
Fixed README typos
2024-01-08 18:20:16 +01:00
Stefan 4ca9c82a2e
Fixed README typos 2024-01-08 13:15:09 +01:00
drmortalwombat 0bc4e7cda6 Fix inc/mov of absolute values 2024-01-07 16:13:01 +01:00
drmortalwombat 36d6fc6760 Fix placement of proxy variables for unused parameters 2024-01-06 20:00:55 +01:00
drmortalwombat 7ea4356361 Fix function end location in dbj file 2024-01-06 17:07:10 +01:00
drmortalwombat 3821b228e9 Fix missing defines for c128e conio 2024-01-06 14:18:00 +01:00
drmortalwombat d676ccc1bd Fix dbj file reference with optimized variable 2024-01-06 14:03:29 +01:00
drmortalwombat 1c1d7fefaa Add c128e target machine 2024-01-06 09:09:52 +01:00
drmortalwombat a7d7db37df Bump version number 2024-01-04 17:56:42 +01:00
drmortalwombat 5d51cf75e8 Fix cross block zp move optimization 2024-01-04 14:14:28 +01:00
drmortalwombat d9f81ad653 Improve cross function memory aliasing analysis 2024-01-03 22:23:20 +01:00
drmortalwombat 34947da898 Fix loop integer range propagation 2024-01-02 22:21:05 +01:00
drmortalwombat 0d7ffd787f
Merge pull request #39 from ra1fh/out-of-bounds-access
Fix out of bounds access to LinkerObjectTypeNames
2024-01-01 18:15:39 +01:00
Ralf Horstmann fc6c83e9cd Fix out of bounds access to LinkerObjectTypeNames
One entry was missing, causing segmentation fault on some platforms.
2024-01-01 14:16:02 +01:00
drmortalwombat 940cb4a5b9 Add declaration to reference list in dbj 2023-12-31 13:30:29 +01:00
drmortalwombat c138c0f2ae Fix loss of zp dependency on diamond register propagation 2023-12-31 10:29:59 +01:00
drmortalwombat 2911321914 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2023-12-30 12:17:54 +01:00
drmortalwombat 5a3cbff259 Add references to dbj file 2023-12-30 12:17:46 +01:00
drmortalwombat 2ff3b6d3d5
Merge pull request #38 from polluks/patch-2
Updated makefile
2023-12-30 09:24:46 +01:00
drmortalwombat da20b4d27a Fix atan2, failed in mathtest.c 2023-12-30 09:21:17 +01:00
Stefan bc45bc08b9
Updated makefile 2023-12-30 00:01:19 +01:00
drmortalwombat 064bf0f8e5 Bump Version Number 2023-12-23 10:45:00 +01:00
drmortalwombat a305dbb1cd Improve function placement in linker 2023-12-23 10:40:45 +01:00
drmortalwombat 59b1d971d0 Changes sprintf to snprintf 2023-12-18 13:00:54 +01:00
drmortalwombat ef6598e94b Fix unnamed structs 2023-12-18 07:40:31 +01:00
drmortalwombat 5055635d3d fix unnamed union in math.c until supported by compiler 2023-12-17 22:47:14 +01:00
drmortalwombat 04518e4ff3 Add error message for unnamed structs 2023-12-17 22:45:21 +01:00
drmortalwombat 4a8010a3a0 Fix loss of zero page dependency in tail code merge 2023-12-17 12:40:09 +01:00
drmortalwombat ae4b48c445 Various loop optimizations 2023-12-16 21:03:09 +01:00
drmortalwombat 6cf8466dfd Fix overeager lda/sta join of tail blocks 2023-12-12 22:39:22 +01:00
drmortalwombat 6bbf325720 Add BIT instruction for sign check, add inlay sections in linker 2023-12-12 11:08:59 +01:00
drmortalwombat 2b0f074c94 Change C128 vdc ready check 2023-12-11 12:23:34 +01:00
drmortalwombat f76599ac08 Change C128 bank 1 code to use __noinline 2023-12-10 16:48:49 +01:00
drmortalwombat ee67c6dec1 Add more HEAPCHECK 2023-12-10 12:41:37 +01:00
drmortalwombat 16810b63d4 Fix over eager lda/sta movement 2023-12-10 09:48:23 +01:00
drmortalwombat 1e0450cd8a Optimize sprite multiplexer 2023-12-09 13:40:58 +01:00
drmortalwombat 1d337f1244 Fix accu train movement to end of block 2023-12-07 14:22:05 +01:00
drmortalwombat cce2f272ef Add optimization section to readme 2023-12-06 13:55:38 +01:00
drmortalwombat d48da32586 Improve placement of "if" cascades 2023-12-04 22:09:33 +01:00
drmortalwombat 11f454390e Add HEAPCHECK 2023-12-03 10:50:00 +01:00
drmortalwombat 8a33fe3e60 Bump version number 2023-12-02 11:04:20 +01:00
drmortalwombat 8ab46e29dd Direct parameter forwarding 2023-12-02 10:58:20 +01:00
drmortalwombat 003306f961 Fix noinline, improve cartridge use of bank 0 2023-11-29 20:53:04 +01:00
drmortalwombat cf28c1a618 Move conditions out of loops 2023-11-28 17:40:44 +01:00
drmortalwombat 8fd560a643 Bump version number 2023-11-26 22:41:17 +01:00
drmortalwombat d5026ed9b0 Fix join common branch sequence 2023-11-26 21:34:06 +01:00
drmortalwombat 57537cd43a Join common branch code sequences 2023-11-26 15:46:59 +01:00
drmortalwombat eec4ed45d1 Fix global array aliasing error 2023-11-20 22:53:12 +01:00
drmortalwombat a9fc83d63c Add xname attribute to .dbj file 2023-11-20 17:28:48 +01:00
drmortalwombat a5f4cf3252 Fix default constructor with classes in header file 2023-11-20 17:03:34 +01:00
drmortalwombat 6995f5a683 Decorate vcall multiplexer 2023-11-20 13:07:29 +01:00
drmortalwombat 0309fcb286 Fixed copy with offset 2023-11-20 08:29:23 +01:00
drmortalwombat 38e1cd0bab Fix join entry loadstore zp if accu is used cross block 2023-11-16 21:52:06 +01:00
drmortalwombat 157f9c00e5 Fix do while loop with function condition 2023-11-16 16:40:11 +01:00
drmortalwombat 44e6921842 Change string literal processing to use unsigned chars 2023-11-14 15:02:35 +01:00
drmortalwombat ee03f08f52 Fix over eager zp parameter reuse 2023-11-11 22:37:35 +01:00
drmortalwombat a59f55c1f3 Fix block join target move zp 2023-11-10 20:53:20 +01:00
drmortalwombat 3be6d20006 Add enum class 2023-11-09 16:33:50 +01:00
drmortalwombat 70c6fb23cc Fix for stack virtual call 2023-11-08 15:35:45 +01:00
drmortalwombat e43c086545 Add enum to int conversion in function call overload 2023-11-07 08:08:44 +01:00
drmortalwombat 06ab48461b Implement striped unions 2023-11-06 21:33:04 +01:00
drmortalwombat 8ea991db81 Optimize div/mod unsigned pairs 2023-11-03 20:16:23 +01:00
drmortalwombat d9c84e3a15 Disable vtable dispatcher inlining 2023-11-02 08:18:09 +01:00
drmortalwombat 8aeddf0316 Fix previous fix 2023-10-30 19:43:37 +01:00
drmortalwombat 8a27cba1f9 Fix inifinite pumping loop in integer range optimizer 2023-10-30 18:02:34 +01:00
drmortalwombat f808309058 Fix wrong string mangling for auto param names 2023-10-30 13:17:23 +01:00
drmortalwombat ae15eca0ef Fix array to pointer cast in const initializer 2023-10-29 20:00:38 +01:00
drmortalwombat 781bb83dd1 Bump version number 2023-10-29 17:57:32 +01:00
drmortalwombat 1d4eb70414 Optimize struct copies 2023-10-29 17:55:26 +01:00
drmortalwombat 75301fa12d Fix crash with array new 2023-10-28 12:02:28 +02:00
drmortalwombat f541cf3848 Fix per tile color in charpad import 2023-10-27 17:59:37 +02:00
drmortalwombat d9a8c5ea08 Fix template expansion of member functions 2023-10-27 14:53:19 +02:00
drmortalwombat 0889afbdae
Merge pull request #34 from polluks/patch-1
Optimisation crt.c
2023-10-26 16:52:04 +02:00
Stefan 25a0c0b4ad
Optimisation crt.c 2023-10-26 16:37:51 +02:00
drmortalwombat 0080a85345 Fix deadlock on empty switch statement 2023-10-26 07:54:03 +02:00
drmortalwombat 50031f56af
Merge pull request #32 from icepic/main
Simplify samples/build.sh by using subshells
2023-10-25 10:59:19 +02:00
drmortalwombat 7d80dfac25
Merge pull request #33 from icepic/patch-1
small readme update
2023-10-25 10:58:35 +02:00
drmortalwombat f6536a412e Fix SAR/MUL optimization 2023-10-24 21:20:07 +02:00
Janne Johansson 0f539d239c
Merge branch 'drmortalwombat:main' into patch-1 2023-10-24 21:06:24 +02:00
Janne Johansson a0ef0b3be2 Simplify samples/build.sh by using subshells 2023-10-24 21:02:51 +02:00
drmortalwombat 982fe17aed Fix compiler crash when using function result in if condition 2023-10-24 14:29:46 +02:00
drmortalwombat 0a3ad006b7 Fix simple struct member optimization for array cases 2023-10-22 19:50:26 +02:00
drmortalwombat f8f81f6d4c Optimize compile time 2023-10-22 19:35:37 +02:00
drmortalwombat 3377ac04fc Fix const use and vtable incompatibility 2023-10-22 12:34:26 +02:00
drmortalwombat aad35e0243 Fix IEC drive timing 2023-10-22 12:14:15 +02:00
drmortalwombat 6e4bf52781 Optimize switch case tree 2023-10-19 21:15:01 +02:00
drmortalwombat 6cb15fd7d9 Improve incompatible type error message 2023-10-19 17:27:09 +02:00
drmortalwombat f7d6b52074 Fixed striped auto pointer 2023-10-18 20:26:11 +02:00
drmortalwombat 0f5e933002 Optimize cross block constant propagation 2023-10-18 15:57:59 +02:00
drmortalwombat 9e3b014927 Eliminate some simple dead X/Y loops 2023-10-16 21:51:20 +02:00
drmortalwombat f5c13c02af Some native code opts 2023-10-16 21:29:42 +02:00
drmortalwombat 63725f3511 Fix const eval of sin/cos 2023-10-16 17:24:35 +02:00
drmortalwombat da5326cc5f Fix local multi dim array init 2023-10-16 15:01:30 +02:00
drmortalwombat 19e2498cc8 Fix member constructor for multi dim array members 2023-10-16 14:13:20 +02:00
drmortalwombat 7858e32d12 Improve handling of single member structs 2023-10-15 20:17:04 +02:00
drmortalwombat 454c4f5dbe Bump version number 2023-10-15 14:22:59 +02:00
drmortalwombat eb16767bdb Optimize wide right shift 2023-10-15 13:59:30 +02:00
drmortalwombat 6e6e3b2adb Fix line directive over consumption 2023-10-15 12:26:32 +02:00
drmortalwombat 3da58bf1ca Fix line directive off by one error 2023-10-15 12:01:24 +02:00
drmortalwombat 4e76b34f53 constexpr constructor 2023-10-14 18:50:27 +02:00
drmortalwombat d160b2ae65 Optimize bitfields 2023-10-14 16:51:33 +02:00
drmortalwombat 4f76ffa311 Implement #line directive 2023-10-14 15:19:24 +02:00
drmortalwombat 9156db9c32 Restart integer range estimation from full state 2023-10-14 13:43:11 +02:00
drmortalwombat ecf8e69cf2 Add restricted pointer attribute to newly allocated memory 2023-10-13 11:18:16 +02:00
drmortalwombat 2027ac5d4c Fix template expansion in multiple cpp 2023-10-12 14:10:34 +02:00
drmortalwombat 020afb8722 bump version number 2023-10-10 09:06:31 +02:00
drmortalwombat 6a30a38415 Fix multi instantiation of inline constructors 2023-10-10 09:02:30 +02:00
drmortalwombat 312914d78c Bump version number 2023-10-08 21:44:30 +02:00
drmortalwombat d4f979b1bc Fix accu return with temp spilling 2023-10-08 21:30:53 +02:00
drmortalwombat 33d692194a Add iterators to string 2023-10-08 16:27:52 +02:00
drmortalwombat e084035a71 Common sub expression across if 2023-10-03 15:21:33 +02:00
drmortalwombat 313b6dcf93 Fix struct assign in constexpr 2023-10-03 12:47:24 +02:00
drmortalwombat 4e6769d81c Add <new> header file 2023-10-02 18:43:58 +02:00
drmortalwombat c53a288d0b Optimize index chains 2023-10-01 21:48:09 +02:00
drmortalwombat 235437be56 Fix absolute address high byte propagation error 2023-09-30 22:22:33 +02:00
drmortalwombat 078d14861c Some data path optimizations 2023-09-30 18:10:03 +02:00
drmortalwombat c98ff08f56 Fix infinite loop eating the entry block 2023-09-27 18:53:35 +02:00
drmortalwombat e6b865130a Fix volatile in vsprites 2023-09-25 19:20:30 +02:00
drmortalwombat d93cffaa30 Fix const pointers in vic_setmode 2023-09-25 19:18:22 +02:00
drmortalwombat 619c4f8962 Join consecutive functions in linker 2023-09-24 22:22:48 +02:00
drmortalwombat da29a87477 Fix address of array in const declaration to return correct pointer type 2023-09-24 11:03:54 +02:00
drmortalwombat bba8931860 Fix const node polution in const param optimization 2023-09-23 18:52:26 +02:00
drmortalwombat cda66f3ec4 Function pointer forwarding 2023-09-23 18:01:28 +02:00
drmortalwombat 9d8c6991e8 Add global optimizer for parameter/return optimizations 2023-09-23 14:56:04 +02:00
drmortalwombat c7f919e22e Bump version number 2023-09-20 18:06:48 +02:00
drmortalwombat a0409002b6 Fix pointers in constexpr 2023-09-20 14:19:56 +02:00
drmortalwombat e20c098ab1 Fix samples build error 2023-09-18 07:41:49 +02:00
drmortalwombat f211eef837 Add fold expressions for argument packs 2023-09-17 20:34:42 +02:00
drmortalwombat 38274fb4f7 Add emplace_back in vector 2023-09-17 15:40:05 +02:00
drmortalwombat c674fc9a8b Add variadic sizeof... 2023-09-17 11:39:18 +02:00
drmortalwombat 06ebf85d9d Recursive variadic templates 2023-09-17 10:24:28 +02:00
drmortalwombat 935a38607b Bump version number 2023-09-14 19:45:55 +02:00
drmortalwombat d9106be820 Lambda in constexpr 2023-09-14 12:03:28 +02:00
drmortalwombat 0e6cb5557a Auto parameters in lambdas 2023-09-14 10:30:52 +02:00
drmortalwombat 64b3bfa30f Optimize temporary object livetime 2023-09-13 19:05:33 +02:00
drmortalwombat 532bf51718 Range for loop with reference iteration 2023-09-13 17:24:38 +02:00
drmortalwombat eccb2787dc Add simple range for loop 2023-09-12 21:33:59 +02:00
drmortalwombat d94d52b852 fix assert in linux autotest 2023-09-12 15:44:16 +02:00
drmortalwombat 2b51f20b1c Add lambda 2023-09-12 15:36:24 +02:00
drmortalwombat c926456560 Add simple return type deduction 2023-09-11 17:49:04 +02:00
drmortalwombat ab49281b0d Implement operator() 2023-09-11 16:19:11 +02:00
drmortalwombat 1b50baf852 Fix wrong unicode character in error message 2023-09-11 13:03:07 +02:00
drmortalwombat c1ecf1c281 Added bitfields 2023-09-11 08:04:09 +02:00
drmortalwombat 3374544ced Fix base type compare in template check 2023-09-10 10:28:25 +02:00
drmortalwombat bd37877c8c Add heap support to constexpr 2023-09-09 12:09:05 +02:00
drmortalwombat 4dd3cd967a Add switch, break and continue to constexpr 2023-09-08 21:03:18 +02:00
drmortalwombat ab273181f5 First shot implementing constexpr 2023-09-08 20:12:38 +02:00
drmortalwombat cb352fcc7c Bump version number 2023-09-04 22:23:00 +02:00
drmortalwombat e9afd5e284 Fix template function included multiple ways 2023-08-31 20:17:39 +02:00
drmortalwombat da9b8f2a42 Fix return of const array as pointer 2023-08-31 14:13:43 +02:00
drmortalwombat fa19e466de Fix opp string append char 2023-08-28 18:52:14 +02:00
drmortalwombat 7bf5ce7581 Add debug file docu to readme 2023-08-25 11:03:49 +02:00
drmortalwombat 5b4e5b545d Add or/and/shift to inline assembler 2023-08-20 19:06:24 +02:00
drmortalwombat 54296bdd71 Add friend classes 2023-08-20 15:06:51 +02:00
drmortalwombat 4732f76bd5 Add static member variables 2023-08-20 14:17:40 +02:00
drmortalwombat 07dc6dc4db Optimize simple virtual with const return to table lookup 2023-08-20 12:02:06 +02:00
drmortalwombat 6ff2409596 Fix return register optimization in v table call 2023-08-20 09:26:26 +02:00
drmortalwombat 04b10bb04d Update readme 2023-08-19 22:01:16 +02:00
drmortalwombat bd3c7571c5 bump version number 2023-08-19 21:57:44 +02:00
drmortalwombat 8dc37e9ab2 Mangling function types in template expansion 2023-08-18 23:03:15 +02:00
drmortalwombat 3a9cd85072 Optimize simple const ref to value in functions 2023-08-18 13:13:39 +02:00
drmortalwombat 0440f0ef19 More template support 2023-08-17 14:55:43 +02:00
drmortalwombat b7daafcac8 Add list and iterators to opp 2023-08-16 16:16:04 +02:00
drmortalwombat 82dff88ba8 Added numeric conversion to opp strings 2023-08-15 16:55:58 +02:00
drmortalwombat 952d087a2b Add using with list of names 2023-08-15 13:16:39 +02:00
drmortalwombat 69b46c4b7b Fix namespaces for templates 2023-08-15 12:46:57 +02:00
drmortalwombat 50cc2afb52 Add template algorithm sort 2023-08-15 11:05:52 +02:00
drmortalwombat ae2fbb6256 Global object initialization 2023-08-14 18:09:35 +02:00
drmortalwombat 80426d974c Add RValue Reference 2023-08-13 20:53:39 +02:00
drmortalwombat 61f8b68c2f Fix duplicate member cons/destructor if class included from multiple cpp 2023-08-13 11:00:02 +02:00
drmortalwombat 9d6691cf91 Copy constructor and destruct for scalar types 2023-08-12 18:19:46 +02:00
drmortalwombat cb5451b9b9 Automatic function template expansion 2023-08-12 15:25:30 +02:00
drmortalwombat 5b7334bb17 Add placement new and destructor call 2023-08-11 19:04:13 +02:00
drmortalwombat fef6bc29bc Add templates 2023-08-11 07:41:27 +02:00
drmortalwombat 07969d1fa6 Fix type coercion from empty string pointer to 0 2023-08-08 17:33:47 +02:00
drmortalwombat b7630450f1 Improve C++ compliance 2023-08-08 14:19:08 +02:00
Janne Johansson 576d2a96cd
Update README.md for unix builds 2023-06-21 15:16:02 +02:00
189 changed files with 66345 additions and 14795 deletions

5
.gitignore vendored
View File

@ -349,3 +349,8 @@ make/oscar64
*.recipe *.recipe
*.exe *.exe
*.dbj *.dbj
*.json
*.mapd
*.idb
oscar64/Releasex64/oscar64.vcxproj.FileListAbsolute.txt
/oscar64/Debugx64

67
CMakeLists.txt Normal file
View File

@ -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
)

1303
README.md

File diff suppressed because it is too large Load Diff

View File

@ -136,19 +136,17 @@ void test_member_assign(void)
int main(void) int main(void)
{ {
#if 0
test_local_init(); test_local_init();
test_member_init(); test_member_init();
#endif
test_member_array_init(); test_member_array_init();
#if 0
test_local_copy(); test_local_copy();
test_member_copy(); test_member_copy();
test_local_assign(); test_local_assign();
test_member_assign(); test_member_assign();
#endif
return 0; return 0;
} }

View File

@ -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;
}

View File

@ -1,36 +1,75 @@
rem @echo off rem @echo off
@call :test opp_string.cpp @call :test rolrortest.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test opp_streamtest.cpp @call :test bitfields.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test operatoroverload.cpp @call :testn autorefreturn.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test virtualdestruct.cpp @call :testh opp_string.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test vcalltest.cpp @call :testh opp_array.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test vcalltree.cpp @call :testh opp_vector.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test constructortest.cpp @call :testh opp_static_vector.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test copyconstructor.cpp @call :testh opp_vector_string.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test copyassign.cpp @call :testh opp_string_init.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test arrayconstruct.cpp @call :testh opp_streamtest.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test stdlibtest.c @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 @if %errorlevel% neq 0 goto :error
@call :test testint16.c @call :test testint16.c
@ -57,6 +96,9 @@ rem @echo off
@call :test fastcalltest.c @call :test fastcalltest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test strlen.c
@if %errorlevel% neq 0 goto :error
@call :test strcmptest.c @call :test strcmptest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -81,6 +123,9 @@ rem @echo off
@call :test floatmultest.c @call :test floatmultest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test floatinttest.c
@if %errorlevel% neq 0 goto :error
@call :test staticconsttest.c @call :test staticconsttest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -120,6 +165,9 @@ rem @echo off
@call :test qsorttest.c @call :test qsorttest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testn plasma.c
@if %errorlevel% neq 0 goto :error
@call :test loopdomtest.c @call :test loopdomtest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -147,6 +195,12 @@ rem @echo off
@call :test divmodtest.c @call :test divmodtest.c
@if %errorlevel% neq 0 goto :error @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 @call :test enumswitch.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -198,77 +252,149 @@ rem @echo off
@call :testn stripedarraytest.c @call :testn stripedarraytest.c
@if %errorlevel% neq 0 goto :error @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 @exit /b 0
:error :error
echo Failed with error #%errorlevel%. echo Failed with error #%errorlevel%.
exit /b %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 :test
..\release\oscar64 -e -bc %~1 ..\bin\oscar64 -e -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n %~1 ..\bin\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O2 -bc %~1 ..\bin\oscar64 -e -O2 -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O2 -n %~1 ..\bin\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O0 -bc %~1 ..\bin\oscar64 -e -O0 -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O0 -n %~1 ..\bin\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -Os -bc %~1 ..\bin\oscar64 -e -Os -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -Os -n %~1 ..\bin\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O3 -bc %~1 ..\bin\oscar64 -e -O3 -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O3 -n %~1 ..\bin\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:testb :testb
..\release\oscar64 -e -bc %~1 ..\bin\oscar64 -e -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -bc -O2 %~1 ..\bin\oscar64 -e -bc -O2 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -bc -O0 %~1 ..\bin\oscar64 -e -bc -O0 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -bc -Os %~1 ..\bin\oscar64 -e -bc -Os %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -bc -O3 %~1 ..\bin\oscar64 -e -bc -O3 %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:testn :testn
..\release\oscar64 -e -n %~1 ..\bin\oscar64 -e -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O2 -n %~1 ..\bin\oscar64 -e -O2 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O0 -n %~1 ..\bin\oscar64 -e -O0 -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -Os -n %~1 ..\bin\oscar64 -e -Os -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O3 -n %~1 ..\bin\oscar64 -e -O3 -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0

354
autotest/bitfields.cpp Normal file
View File

@ -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;
}

View File

@ -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(shl32n)
#pragma native(shr32n) #pragma native(shr32n)
@ -373,24 +385,30 @@ int main(void)
shr16n(0xfedc, 0xfedc); shr16n(0xfedc, 0xfedc);
shl32b(0x00000000UL, 0x00000000L); shl32b(0x00000000UL, 0x00000000L);
shl32b(0x00000001UL, 0x00000001L);
shl32b(0xffffffffUL, 0xffffffffL); shl32b(0xffffffffUL, 0xffffffffL);
shl32b(0x12345678UL, 0x12345678L); shl32b(0x12345678UL, 0x12345678L);
shl32b(0xfedcba98UL, 0xfedcba98L); shl32b(0xfedcba98UL, 0xfedcba98L);
shr32b(0x00000000UL, 0x00000000L); shr32b(0x00000000UL, 0x00000000L);
shr32b(0x00000001UL, 0x00000001L);
shr32b(0xffffffffUL, 0xffffffffL); shr32b(0xffffffffUL, 0xffffffffL);
shr32b(0x12345678UL, 0x12345678L); shr32b(0x12345678UL, 0x12345678L);
shr32b(0xfedcba98UL, 0xfedcba98L); shr32b(0xfedcba98UL, 0xfedcba98L);
shl32n(0x00000000UL, 0x00000000L); shl32n(0x00000000UL, 0x00000000L);
shl32n(0x00000001UL, 0x00000001L);
shl32n(0xffffffffUL, 0xffffffffL); shl32n(0xffffffffUL, 0xffffffffL);
shl32n(0x12345678UL, 0x12345678L); shl32n(0x12345678UL, 0x12345678L);
shl32n(0xfedcba98UL, 0xfedcba98L); shl32n(0xfedcba98UL, 0xfedcba98L);
shr32n(0x00000000UL, 0x00000000L); shr32n(0x00000000UL, 0x00000000L);
shr32n(0x00000001UL, 0x00000001L);
shr32n(0xffffffffUL, 0xffffffffL); shr32n(0xffffffffUL, 0xffffffffL);
shr32n(0x12345678UL, 0x12345678L); shr32n(0x12345678UL, 0x12345678L);
shr32n(0xfedcba98UL, 0xfedcba98L); shr32n(0xfedcba98UL, 0xfedcba98L);
shl1_32n();
return 0; return 0;
} }

View File

@ -1,4 +1,5 @@
#include <assert.h> #include <assert.h>
#include <stdio.h>
int t, n; int t, n;
@ -161,7 +162,7 @@ void test_return_value(void)
C2 c(test_ret_v()); C2 c(test_ret_v());
} }
assert(n == 4 && t == 0); assert(n == 6 && t == 0);
} }
void test_return_reference(void) void test_return_reference(void)
@ -184,7 +185,7 @@ void test_retparam_value(void)
test_param_fv(test_ret_v()); test_param_fv(test_ret_v());
} }
assert(n == 4 && t == 0); assert(n == 6 && t == 0);
} }
void test_retparam_reference(void) void test_retparam_reference(void)
@ -200,7 +201,6 @@ void test_retparam_reference(void)
int main(void) int main(void)
{ {
#if 0
test_dcopy_init(); test_dcopy_init();
test_copy_init(); test_copy_init();
test_minit(); test_minit();
@ -208,9 +208,8 @@ int main(void)
test_param_value(); test_param_value();
test_param_ref(); test_param_ref();
test_return_value(); test_return_value();
#endif
test_retparam_value(); test_retparam_value();
// test_retparam_reference(); test_retparam_reference();
return 0; return 0;
} }

36
autotest/divmod32test.c Normal file
View File

@ -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;
}

90
autotest/fixmathtest.c Normal file
View File

@ -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;
}

75
autotest/floatinttest.c Normal file
View File

@ -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;
}

View File

@ -1,50 +1,60 @@
CC=../bin/oscar64 SRCS=$(filter-out opp_part1.cpp opp_part2.cpp, $(wildcard *.c *.cpp))
CXX=$(CC)
SRCS=$(wildcard *.c *.cpp)
EXES=$(patsubst %.c,%,$(SRCS)) EXES=$(patsubst %.c,%,$(SRCS))
EXES:=$(patsubst %.cpp,%,$(EXES)) EXES:=$(patsubst %.cpp,%,$(EXES))
all: $(EXES) all: $(EXES)
%: %.c %: %.c
$(CC) -e -bc $< $(OSCAR64_CC) -e -bc $<
$(CC) -e -n $< $(OSCAR64_CC) -e -n $<
$(CC) -e -O2 -bc $< $(OSCAR64_CC) -e -O2 -bc $<
$(CC) -e -O2 -n $< $(OSCAR64_CC) -e -O2 -n $<
$(CC) -e -O0 -bc $< $(OSCAR64_CC) -e -O0 -bc $<
$(CC) -e -O0 -n $< $(OSCAR64_CC) -e -O0 -n $<
$(CC) -e -Os -bc $< $(OSCAR64_CC) -e -Os -bc $<
$(CC) -e -Os -n $< $(OSCAR64_CC) -e -Os -n $<
$(CC) -e -O3 -bc $< $(OSCAR64_CC) -e -O3 -bc $<
$(CC) -e -O3 -n $< $(OSCAR64_CC) -e -O3 -n $<
%: %.cpp %: %.cpp
$(CXX) -e -bc $< $(OSCAR64_CXX) -e -bc $<
$(CXX) -e -n $< $(OSCAR64_CXX) -e -n $<
$(CXX) -e -O2 -bc $< $(OSCAR64_CXX) -e -O2 -bc $<
$(CXX) -e -O2 -n $< $(OSCAR64_CXX) -e -O2 -n $<
$(CXX) -e -O0 -bc $< $(OSCAR64_CXX) -e -O0 -bc $<
$(CXX) -e -O0 -n $< $(OSCAR64_CXX) -e -O0 -n $<
$(CXX) -e -Os -bc $< $(OSCAR64_CXX) -e -Os -bc $<
$(CXX) -e -Os -n $< $(OSCAR64_CXX) -e -Os -n $<
$(CXX) -e -O3 -bc $< $(OSCAR64_CXX) -e -O3 -bc $<
$(CXX) -e -O3 -n $< $(OSCAR64_CXX) -e -O3 -n $<
# testb # testb
bitshifttest: bitshifttest.c bitshifttest: bitshifttest.c
$(CC) -e -bc $< $(OSCAR64_CC) -e -bc $<
$(CC) -e -bc -O2 $< $(OSCAR64_CC) -e -bc -O2 $<
$(CC) -e -bc -O0 $< $(OSCAR64_CC) -e -bc -O0 $<
$(CC) -e -bc -Os $< $(OSCAR64_CC) -e -bc -Os $<
$(CC) -e -bc -O3 $< $(OSCAR64_CC) -e -bc -O3 $<
$(CC) -e -n $< $(OSCAR64_CC) -e -n $<
# testn # testn
stripedarraytest: stripedarraytest.c stripedarraytest: stripedarraytest.c
$(CC) -e -O2 -n $< $(OSCAR64_CC) -e -O2 -n $<
$(CC) -e -O0 -n $< $(OSCAR64_CC) -e -O0 -n $<
$(CC) -e -Os -n $< $(OSCAR64_CC) -e -Os -n $<
$(CC) -e -O3 -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: clean:
$(RM) *.asm *.bcs *.int *.lbl *.map *.prg @$(RM) *.asm *.bcs *.int *.lbl *.map *.prg

43
autotest/mmultest.c Normal file
View File

@ -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;
}

23
autotest/opp_array.cpp Normal file
View File

@ -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;
}

View File

@ -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;
}

57
autotest/opp_list.cpp Normal file
View File

@ -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;
}

28
autotest/opp_pairtest.cpp Normal file
View File

@ -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;
}

2
autotest/opp_part1.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "opp_part1.h"

40
autotest/opp_part1.h Normal file
View File

@ -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")

13
autotest/opp_part2.cpp Normal file
View File

@ -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;
}

16
autotest/opp_part2.h Normal file
View File

@ -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")

25
autotest/opp_parts.cpp Normal file
View File

@ -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;
}

View File

@ -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;
}

View File

@ -4,6 +4,10 @@
#include <opp/sstream.h> #include <opp/sstream.h>
#include <math.h> #include <math.h>
using opp::ostringstream;
using opp::istringstream;
using opp::endl;
float fdist(float a, float b) float fdist(float a, float b)
{ {
float d = fabs(a - b); float d = fabs(a - b);
@ -21,8 +25,6 @@ int main(void)
os << i << endl; os << i << endl;
} }
costream cout;
istringstream is(os.str()); istringstream is(os.str());
int j = 0, k = 47; int j = 0, k = 47;
@ -35,7 +37,7 @@ int main(void)
assert(j == 40); assert(j == 40);
#endif #endif
os.str(string()); os.str(opp::string());
#if 0 #if 0
cout << "[" << os.str() << "]" << endl; cout << "[" << os.str() << "]" << endl;

View File

@ -3,12 +3,14 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
using opp::string;
static const char HelloWorld[] = "Hello World"; static const char HelloWorld[] = "Hello World";
static const char AndBeyond[] = "And Beyond"; static const char AndBeyond[] = "And Beyond";
static const char And[] = "And"; static const char And[] = "And";
static const char HelloWorldAndBeyond[] = "Hello World And Beyond"; static const char HelloWorldAndBeyond[] = "Hello World And Beyond";
void test_create(void) __noinline void test_create(void)
{ {
string s1(); string s1();
string s2(HelloWorld); string s2(HelloWorld);
@ -20,7 +22,7 @@ void test_create(void)
assert(s4.size() == 1 && s4[0] == 'a'); assert(s4.size() == 1 && s4[0] == 'a');
} }
void test_concat(void) __noinline void test_concat(void)
{ {
string s1(); string s1();
string s2(HelloWorld); string s2(HelloWorld);
@ -49,7 +51,7 @@ __noinline void test_find(void)
assert(s1.find(' ', 6) == 11); assert(s1.find(' ', 6) == 11);
} }
void test_assign(void) __noinline void test_assign(void)
{ {
string s1(HelloWorld); string s1(HelloWorld);
string s2(AndBeyond); string s2(AndBeyond);
@ -75,9 +77,12 @@ void test_assign(void)
assert(!strcmp(s3.tocstr(), HelloWorld)); assert(!strcmp(s3.tocstr(), HelloWorld));
} }
static char * test;
int main(void) int main(void)
{ {
char * p = new char; test = new char;
unsigned avail = heapfree(); unsigned avail = heapfree();
test_create(); test_create();
@ -92,5 +97,7 @@ int main(void)
test_assign(); test_assign();
assert(avail == heapfree()); assert(avail == heapfree());
delete test;
return 0; return 0;
} }

View File

@ -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;
}

78
autotest/opp_vector.cpp Normal file
View File

@ -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;
}

View File

@ -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;
}

145
autotest/plasma.c Normal file
View File

@ -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;
}

76
autotest/rolrortest.cpp Normal file
View File

@ -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;
}

27
autotest/strlen.c Normal file
View File

@ -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;
}

View File

@ -5,6 +5,11 @@ void testmuli(long a, long b, long ab)
assert (a * b == 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) void testdivi(long a, long b, long ab)
{ {
assert (a / b == ab); assert (a / b == ab);
@ -80,6 +85,26 @@ int main(void)
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); testdivi(-1, 1, -1);
testdivi( 1, -1, -1); testdivi( 1, -1, -1);

View File

@ -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) bool beqz(long a)
{ {
return a == 0; 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 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); 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); 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) void cmpz(long a)
{ {
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(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); 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) int main(void)
{ {
cmp( 0, 1); cmp( 0, 1);
@ -327,6 +454,10 @@ int main(void)
cmp1(256); cmp1(256);
cmp1(10000); cmp1(10000);
cmp1(20000); cmp1(20000);
cmp1(1000000l);
cmp1(2000000l);
cmp1(100000000l);
cmp1(200000000l);
cmp1(-1); cmp1(-1);
cmp1(-2); cmp1(-2);
cmp1(-3); cmp1(-3);
@ -334,6 +465,34 @@ int main(void)
cmp1(-256); cmp1(-256);
cmp1(-10000); cmp1(-10000);
cmp1(-20000); 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; return 0;

83
autotest/tileexpand.cpp Normal file
View File

@ -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;
}

View File

@ -10,12 +10,13 @@ enum SIDFXState
SIDFX_WAIT SIDFX_WAIT
}; };
static struct SIDFXChannel __striped static struct SIDFXChannel
{ {
const SIDFX * com; const SIDFX * volatile com;
byte delay, cnt, priority; byte delay, priority;
volatile SIDFXState state; volatile byte cnt;
unsigned freq, pwm; volatile SIDFXState state;
unsigned freq, pwm;
} channels[3]; } channels[3];
@ -26,9 +27,20 @@ void sidfx_init(void)
channels[i].com = nullptr; channels[i].com = nullptr;
channels[i].state = SIDFX_IDLE; channels[i].state = SIDFX_IDLE;
channels[i].priority = 0; 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) void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
{ {
SIDFXState ns = channels[chn].state; SIDFXState ns = channels[chn].state;
@ -41,6 +53,7 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
return; return;
channels[chn].state = SIDFX_IDLE; channels[chn].state = SIDFX_IDLE;
channels[chn].delay = 1;
channels[chn].com = fx; channels[chn].com = fx;
channels[chn].cnt = cnt - 1; channels[chn].cnt = cnt - 1;
@ -53,103 +66,126 @@ void sidfx_stop(byte chn)
{ {
channels[chn].com = nullptr; channels[chn].com = nullptr;
if (channels[chn].state != SIDFX_IDLE) if (channels[chn].state != SIDFX_IDLE)
{
channels[chn].state = SIDFX_RESET_0; channels[chn].state = SIDFX_RESET_0;
channels[chn].delay = 1;
}
} }
inline void sidfx_loop_ch(byte ch) inline void sidfx_loop_ch(byte ch)
{ {
switch (channels[ch].state) if (channels[ch].state)
{ {
case SIDFX_IDLE: const SIDFX * com = channels[ch].com;
break;
case SIDFX_RESET_0:
sid.voices[ch].ctrl = 0;
sid.voices[ch].attdec = 0;
sid.voices[ch].susrel = 0;
channels[ch].state = SIDFX_RESET_1;
break;
case SIDFX_RESET_1:
sid.voices[ch].ctrl = SID_CTRL_TEST;
channels[ch].state = SIDFX_READY;
break;
case SIDFX_READY:
if (channels[ch].com)
{
channels[ch].freq = channels[ch].com->freq;
channels[ch].pwm = channels[ch].com->pwm;
sid.voices[ch].freq = channels[ch].com->freq; channels[ch].delay--;
sid.voices[ch].pwm = channels[ch].com->pwm; if (channels[ch].delay)
sid.voices[ch].attdec = channels[ch].com->attdec; {
sid.voices[ch].susrel = channels[ch].com->susrel; if (com->dfreq)
sid.voices[ch].ctrl = channels[ch].com->ctrl;
channels[ch].delay = channels[ch].com->time1;
channels[ch].state = SIDFX_PLAY;
}
else
channels[ch].state = SIDFX_IDLE;
break;
case SIDFX_PLAY:
if (channels[ch].com->dfreq)
{ {
channels[ch].freq += channels[ch].com->dfreq; channels[ch].freq += com->dfreq;
sid.voices[ch].freq = channels[ch].freq; sid.voices[ch].freq = channels[ch].freq;
} }
if (channels[ch].com->dpwm) if (com->dpwm)
{ {
channels[ch].pwm += channels[ch].com->dpwm; channels[ch].pwm += com->dpwm;
sid.voices[ch].pwm = channels[ch].pwm; sid.voices[ch].pwm = channels[ch].pwm;
} }
}
if (channels[ch].delay) while (!channels[ch].delay)
channels[ch].delay--; {
else if (channels[ch].com->time0) switch (channels[ch].state)
{ {
sid.voices[ch].ctrl = channels[ch].com->ctrl & ~SID_CTRL_GATE; case SIDFX_IDLE:
channels[ch].delay = channels[ch].com->time0; channels[ch].delay = 1;
channels[ch].state = SIDFX_WAIT; break;
} case SIDFX_RESET_0:
else if (channels[ch].cnt) sid.voices[ch].ctrl = 0;
{ sid.voices[ch].attdec = 0;
channels[ch].cnt--; sid.voices[ch].susrel = 0;
channels[ch].com++; if (com)
channels[ch].priority = channels[ch].com->priority; 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; channels[ch].state = SIDFX_READY;
} break;
else case SIDFX_READY:
{ channels[ch].freq = com->freq;
channels[ch].com = nullptr; channels[ch].pwm = com->pwm;
channels[ch].state = SIDFX_RESET_0;
}
break;
case SIDFX_WAIT:
if (channels[ch].com->dfreq)
{
channels[ch].freq += channels[ch].com->dfreq;
sid.voices[ch].freq = channels[ch].freq;
}
if (channels[ch].com->dpwm)
{
channels[ch].pwm += channels[ch].com->dpwm;
sid.voices[ch].pwm = channels[ch].pwm;
}
if (channels[ch].delay) sid.voices[ch].freq = com->freq;
channels[ch].delay--; sid.voices[ch].pwm = com->pwm;
else if (channels[ch].cnt) sid.voices[ch].attdec = com->attdec;
{ sid.voices[ch].susrel = com->susrel;
channels[ch].cnt--; sid.voices[ch].ctrl = com->ctrl;
channels[ch].com++;
channels[ch].priority = channels[ch].com->priority; if (com->ctrl & SID_CTRL_GATE)
channels[ch].state = SIDFX_RESET_0; {
channels[ch].delay = com->time1;
channels[ch].state = SIDFX_PLAY;
}
else
{
channels[ch].delay = com->time0;
channels[ch].state = SIDFX_PLAY;
}
break;
case SIDFX_PLAY:
if (com->time0)
{
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
channels[ch].delay = com->time0 - 1;
channels[ch].state = SIDFX_WAIT;
}
else if (channels[ch].cnt)
{
char sr = com->susrel & 0xf0;
com++;
char ctrl = com->ctrl;
if ((com->attdec & 0xef) == 0 && (ctrl & SID_CTRL_GATE) && (com->susrel & 0xf0) > sr)
{
sid.voices[ch].ctrl = ctrl & ~SID_CTRL_GATE;
sid.voices[ch].ctrl = ctrl | SID_CTRL_GATE;
}
channels[ch].cnt--;
channels[ch].com = com;
channels[ch].priority = com->priority;
channels[ch].state = SIDFX_READY;
}
else
{
com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
case SIDFX_WAIT:
if (channels[ch].cnt)
{
com++;
channels[ch].cnt--;
channels[ch].com = com;
channels[ch].priority = com->priority;
if (com->ctrl & SID_CTRL_GATE)
channels[ch].state = SIDFX_RESET_0;
else
channels[ch].state = SIDFX_READY;
}
else
{
com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
} }
else }
{
channels[ch].com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
} }
} }

View File

@ -14,10 +14,14 @@ struct SIDFX
void sidfx_init(void); void sidfx_init(void);
inline bool sidfx_idle(byte chn);
inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt); inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
void sidfx_stop(byte chn); void sidfx_stop(byte chn);
char sidfx_cnt(byte chn);
void sidfx_loop(void); void sidfx_loop(void);
void sidfx_loop_2(void); void sidfx_loop_2(void);

View File

@ -10,22 +10,22 @@ void bnk1_init(void);
#pragma code(bnk1code) #pragma code(bnk1code)
char bnk1_readb(volatile char * p); __noinline char bnk1_readb(volatile char * p);
unsigned bnk1_readw(volatile unsigned * p); __noinline unsigned bnk1_readw(volatile unsigned * p);
unsigned long bnk1_readl(volatile unsigned long * p); __noinline unsigned long bnk1_readl(volatile unsigned long * p);
void bnk1_readm(char * dp, volatile char * sp, unsigned size); __noinline void bnk1_readm(char * dp, volatile char * sp, unsigned size);
void bnk1_writeb(volatile char * p, char b); __noinline void bnk1_writeb(volatile char * p, char b);
void bnk1_writew(volatile unsigned * p, unsigned w); __noinline void bnk1_writew(volatile unsigned * p, unsigned w);
void bnk1_writel(volatile unsigned long * p, unsigned long l); __noinline void bnk1_writel(volatile unsigned long * p, unsigned long l);
void bnk1_writem(volatile char * dp, const char * sp, unsigned size); __noinline void bnk1_writem(volatile char * dp, const char * sp, unsigned size);
#pragma code(code) #pragma code(code)

View File

@ -1 +1,8 @@
#include "mmu.h" #include "mmu.h"
inline char mmu_set(char cr)
{
char pcr = mmu.cr;
mmu.cr = cr;
return pcr;
}

View File

@ -27,6 +27,7 @@ struct XMMU
#define xmmu (*((struct XMMU *)0xd500)) #define xmmu (*((struct XMMU *)0xd500))
inline char mmu_set(char cr);
#pragma compile("mmu.c") #pragma compile("mmu.c")

View File

@ -4,16 +4,17 @@
inline void vdc_reg(VDCRegister reg) inline void vdc_reg(VDCRegister reg)
{ {
vdc.addr = reg; vdc.addr = reg;
do {} while (vdc.addr < 128);
} }
inline void vdc_write(byte data) inline void vdc_write(byte data)
{ {
do {} while (vdc.addr < 128);
vdc.data = data; vdc.data = data;
} }
inline byte vdc_read(void) inline byte vdc_read(void)
{ {
do {} while (vdc.addr < 128);
return vdc.data; return vdc.data;
} }
@ -33,8 +34,11 @@ byte vdc_reg_read(VDCRegister reg)
void vdc_mem_addr(unsigned addr) void vdc_mem_addr(unsigned addr)
{ {
#pragma callinline()
vdc_reg_write(VDCR_ADDRH, addr >> 8); vdc_reg_write(VDCR_ADDRH, addr >> 8);
#pragma callinline()
vdc_reg_write(VDCR_ADDRL, addr); vdc_reg_write(VDCR_ADDRL, addr);
#pragma callinline()
vdc_reg(VDCR_DATA); vdc_reg(VDCR_DATA);
} }
@ -51,12 +55,14 @@ inline char vdc_mem_read(void)
void vdc_mem_write_at(unsigned addr, char data) void vdc_mem_write_at(unsigned addr, char data)
{ {
#pragma callinline()
vdc_mem_addr(addr); vdc_mem_addr(addr);
vdc_write(data); vdc_write(data);
} }
char vdc_mem_read_at(unsigned addr) char vdc_mem_read_at(unsigned addr)
{ {
#pragma callinline()
vdc_mem_addr(addr); vdc_mem_addr(addr);
return vdc_read(); return vdc_read();
} }

View File

@ -16,7 +16,7 @@ void cia_init(void)
cia2.ddrb = 0x00; cia2.ddrb = 0x00;
cia1.ddra = 0xff; cia1.ddra = 0xff;
cia2.prb = 0x07; cia2.pra = 0x07;
cia2.ddra = 0x3f; cia2.ddra = 0x3f;
char i0 = cia1.icr; char i0 = cia1.icr;

View File

@ -18,6 +18,46 @@ struct EasyFlash
#define eflash (*(EasyFlash *)0xde00) #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 #endif

608
include/c64/flossiec.c Normal file
View File

@ -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;
}

79
include/c64/flossiec.h Normal file
View File

@ -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

View File

@ -2,7 +2,8 @@
#include <c64/cia.h> #include <c64/cia.h>
#include <c64/vic.h> #include <c64/vic.h>
IEC_STATUS iec_status; IEC_STATUS iec_status;
char iec_queue;
#define CIA2B_ATNOUT 0x08 #define CIA2B_ATNOUT 0x08
#define CIA2B_CLKOUT 0x10 #define CIA2B_CLKOUT 0x10
@ -14,139 +15,180 @@ IEC_STATUS iec_status;
#pragma optimize(push) #pragma optimize(push)
#pragma optimize(1) #pragma optimize(1)
// multiples of 5us
static void delay(char n) static void delay(char n)
{ {
while (n) __asm {
{ ldx n
__asm { l1:
nop dex
} bne l1
n--;
} }
} }
static inline void data_low(void) static inline void data_true(void)
{ {
cia2.pra &= ~CIA2B_DATAOUT; cia2.pra &= ~CIA2B_DATAOUT;
} }
static inline void data_high(void) static inline void data_false(void)
{ {
cia2.pra |= CIA2B_DATAOUT; cia2.pra |= CIA2B_DATAOUT;
} }
static inline void clock_low(void) static inline void clock_true(void)
{ {
cia2.pra &= ~CIA2B_CLKOUT; cia2.pra &= ~CIA2B_CLKOUT;
} }
static inline void cdata_low(void) static inline void cdata_true(void)
{ {
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT); cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
} }
static inline void clock_high(void) static inline void clock_false(void)
{ {
cia2.pra |= CIA2B_CLKOUT; cia2.pra |= CIA2B_CLKOUT;
} }
static inline void atn_low(void) static inline void atn_true(void)
{ {
cia2.pra &= ~CIA2B_ATNOUT; cia2.pra &= ~CIA2B_ATNOUT;
} }
static inline void atn_high(void) static inline void atn_false(void)
{ {
cia2.pra |= CIA2B_ATNOUT; 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) static bool data_check(void)
{ {
char cnt = 100; char cnt = 200;
while (cnt > 0 && (cia2.pra & CIA2B_DATAIN)) while (cnt > 0 && data_in())
{
delay(5);
cnt--; cnt--;
}
if (cnt) if (cnt)
return true; return true;
else else
{ {
iec_status = IEC_TIMEOUT; iec_status = IEC_DATA_CHECK;
return false; return false;
} }
} }
bool iec_eoi(void) static bool iec_eoib(void)
{ {
cdata_low(); clock_true();
while (!(cia2.pra & CIA2B_DATAIN)) while (!data_in());
;
delay(50); delay(40);
return data_check(); 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) bool iec_write(char b)
{ {
cdata_low(); if (iec_status == IEC_QUEUED)
while (!(cia2.pra & CIA2B_DATAIN))
;
for(char i=0; i<8; i++)
{ {
clock_high();
if (b & 1)
data_low();
else
data_high();
clock_low();
b >>= 1;
__asm __asm
{ {
nop php
nop sei
nop
nop
} }
}
data_low();
clock_high();
return data_check(); iec_status = IEC_OK;
iec_writeb(iec_queue);
__asm
{
plp
}
data_check();
}
if (iec_status < IEC_ERROR)
{
iec_queue = b;
iec_status = IEC_QUEUED;
return true;
}
return false;
} }
char iec_read(void) char iec_read(void)
{ {
while (!(cia2.pra & CIA2B_CLKIN)) while (!clock_in());
;
data_low(); __asm
{
php
sei
}
data_true();
char cnt = 100; char cnt = 100;
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN)) while (cnt > 0 && clock_in())
cnt--; cnt--;
if (cnt == 0) if (cnt == 0)
{ {
iec_status = IEC_EOF; iec_status = IEC_EOF;
data_high(); data_false();
__asm delay(10);
{ data_true();
nop
nop
nop
nop
}
data_low();
cnt = 200; cnt = 200;
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN)) while (cnt > 0 && clock_in())
cnt--; cnt--;
if (cnt == 0) if (cnt == 0)
{ {
iec_status = IEC_TIMEOUT; iec_status = IEC_TIMEOUT;
__asm
{
plp
}
return 0; return 0;
} }
} }
@ -165,24 +207,36 @@ char iec_read(void)
; ;
} }
data_high(); data_false();
__asm
{
plp
}
return b; return b;
} }
void iec_atn(char dev, char sec) void iec_atn(char dev, char sec)
{ {
atn_high(); clock_true();
clock_high(); data_true();
atn_false();
clock_false();
delay(100); delay(200);
iec_write(dev); while (data_in());
iec_writeb(dev);
data_check();
if (sec != 0xff) if (sec != 0xff)
iec_write(sec); {
iec_writeb(sec);
data_check();
}
data_high(); atn_true();
atn_low();
} }
@ -190,8 +244,26 @@ void iec_talk(char dev, char sec)
{ {
iec_status = IEC_OK; iec_status = IEC_OK;
iec_atn(dev | 0x40, sec); iec_atn(dev | 0x40, sec | 0x60);
clock_low(); data_false();
__asm
{
php
sei
}
clock_true();
char cnt = 200;
while (cnt > 0 && clock_in())
cnt--;
__asm
{
plp
}
delay(10);
} }
void iec_untalk(void) void iec_untalk(void)
@ -203,12 +275,32 @@ void iec_listen(char dev, char sec)
{ {
iec_status = IEC_OK; iec_status = IEC_OK;
iec_atn(dev | 0x20, sec); iec_atn(dev | 0x20, sec | 0x60);
} }
void iec_unlisten(void) 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); iec_atn(0x3f, 0xff);
clock_true();
__asm
{
plp
}
} }
void iec_open(char dev, char sec, const char * fname) void iec_open(char dev, char sec, const char * fname)
@ -216,11 +308,10 @@ void iec_open(char dev, char sec, const char * fname)
iec_status = IEC_OK; iec_status = IEC_OK;
iec_atn(dev | 0x20, sec | 0xf0); iec_atn(dev | 0x20, sec | 0xf0);
char i = 0; char i = 0;
while (fname[i]) while (fname[i])
{ {
if (!fname[i + 1])
iec_eoi();
iec_write(fname[i]); iec_write(fname[i]);
i++; i++;
} }
@ -233,6 +324,30 @@ void iec_close(char dev, char sec)
iec_unlisten(); 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) #pragma optimize(pop)

View File

@ -5,15 +5,15 @@ enum IEC_STATUS
{ {
IEC_OK = 0x00, IEC_OK = 0x00,
IEC_EOF = 0x01, IEC_EOF = 0x01,
IEC_QUEUED = 0x02,
IEC_ERROR = 0x80, IEC_ERROR = 0x80,
IEC_TIMEOUT IEC_TIMEOUT,
IEC_DATA_CHECK,
}; };
extern IEC_STATUS iec_status; extern IEC_STATUS iec_status;
bool iec_eoi(void);
bool iec_write(char b); bool iec_write(char b);
char iec_read(void); char iec_read(void);
@ -32,6 +32,11 @@ void iec_open(char dev, char sec, const char * fname);
void iec_close(char dev, char sec); 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") #pragma compile("iecbus.c")
#endif #endif

View File

@ -2,7 +2,32 @@
krnioerr krnio_pstatus[16]; 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 __asm
{ {
@ -17,22 +42,41 @@ void krnio_setnam(const char * name)
tya tya
W1: ldx name W1: ldx name
ldy name + 1 ldy name + 1
BANKIN
jsr $ffbd // setnam jsr $ffbd // setnam
BANKOUT
} }
} }
#pragma native(krnio_setnam) #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; krnio_pstatus[fnum] = KRNIO_OK;
__asm return char(__asm
{ {
lda #0 lda #0
sta accu sta accu
sta accu + 1 sta accu + 1
BANKIN
lda fnum lda fnum
ldx device ldx device
ldy channel ldy channel
@ -47,46 +91,48 @@ bool krnio_open(char fnum, char device, char channel)
W1: W1:
lda #1 lda #1
sta accu sta accu
E2:
}
BANKOUT
E2:
});
} }
#pragma native(krnio_open) #pragma native(krnio_open)
void krnio_close(char fnum) BANKINLINE void krnio_close(char fnum)
{ {
__asm __asm
{ {
BANKIN
lda fnum lda fnum
jsr $ffc3 // close jsr $ffc3 // close
BANKOUT
} }
} }
#pragma native(krnio_close) #pragma native(krnio_close)
krnioerr krnio_status(void) BANKINLINE krnioerr krnio_status(void)
{ {
__asm return __asm
{ {
BANKIN
jsr $ffb7 // readst jsr $ffb7 // readst
BANKOUT
sta accu sta accu
lda #0 lda #0
sta accu + 1 sta accu + 1
} };
} }
#pragma native(krnio_status) #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 BANKIN
sta accu
sta accu + 1
lda fnum lda fnum
ldx device ldx device
ldy channel ldy channel
@ -95,89 +141,123 @@ bool krnio_load(char fnum, char device, char channel)
lda #0 lda #0
ldx #0 ldx #0
ldy #0 ldy #0
jsr $FFD5 // open jsr $FFD5 // load
bcc W1 BANKOUT
lda #0 lda #0
jmp E2 rol
W1: eor #1
lda #1 sta accu
sta accu });
E2:
}
} }
#pragma native(krnio_load) #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 ldx fnum
jsr $ffc9 // chkout jsr $ffc9 // chkout
BANKOUT
lda #0 lda #0
sta accu + 1 rol
bcs W1 eor #1
lda #1 sta accu
W1: sta accu });
}
} }
#pragma native(krnio_chkout) #pragma native(krnio_chkout)
bool krnio_chkin(char fnum) BANKINLINE bool krnio_chkin(char fnum)
{ {
__asm return char(__asm
{ {
BANKIN
ldx fnum ldx fnum
jsr $ffc6 // chkin jsr $ffc6 // chkin
BANKOUT
lda #0 lda #0
sta accu + 1 rol
bcs W1 eor #1
lda #1 sta accu
W1: sta accu });
}
} }
#pragma native(krnio_chkin) #pragma native(krnio_chkin)
void krnio_clrchn(void) BANKINLINE void krnio_clrchn(void)
{ {
__asm __asm
{ {
BANKIN
jsr $ffcc // clrchn jsr $ffcc // clrchn
BANKOUT
} }
} }
#pragma native(krnio_clrchn) #pragma native(krnio_clrchn)
bool krnio_chrout(char ch) BANKINLINE bool krnio_chrout(char ch)
{ {
__asm return char(__asm
{ {
BANKIN
lda ch lda ch
jsr $ffd2 // chrout jsr $ffd2 // chrout
sta accu sta accu
lda #0 BANKOUT
sta accu + 1 });
}
} }
#pragma native(krnio_chrout) #pragma native(krnio_chrout)
int krnio_chrin(void) BANKINLINE char krnio_chrin(void)
{ {
__asm return __asm
{ {
BANKIN
jsr $ffcf // chrin jsr $ffcf // chrin
sta accu sta accu
lda #0 BANKOUT
sta accu + 1 };
}
} }
#pragma native(krnio_chrin) #pragma native(krnio_chrin)
#if defined(__PLUS4__)
#pragma code(code)
#endif
int krnio_getch(char fnum) int krnio_getch(char fnum)
{ {
if (krnio_pstatus[fnum] == KRNIO_EOF) if (krnio_pstatus[fnum] == KRNIO_EOF)
@ -341,7 +421,7 @@ int krnio_gets(char fnum, char * data, int num)
if (krnio_chkin(fnum)) if (krnio_chkin(fnum))
{ {
krnioerr err; krnioerr err = KRNIO_OK;
int i = 0; int i = 0;
int ch; int ch;
while (i + 1 < num) while (i + 1 < num)

View File

@ -1,5 +1,5 @@
#ifndef C64_KERNALIO_H #ifndef C64_KERNALIO_H
#ifndef C64_KERNALIO_H #define C64_KERNALIO_H
// Error and status codes returned by krnio_status // Error and status codes returned by krnio_status
@ -18,11 +18,18 @@ enum krnioerr
extern krnioerr krnio_pstatus[16]; 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 // Set filename for next krnio_open operation, make sure
// that the string is still valid when calling krnio_open // that the string is still valid when calling krnio_open
void krnio_setnam(const char * name); 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 // open a kernal file/stream/io channel, returns true on success
bool krnio_open(char fnum, char device, char channel); 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_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 // select the given file for stream output
bool krnio_chkout(char fnum); bool krnio_chkout(char fnum);
@ -55,7 +64,7 @@ bool krnio_chrout(char ch);
// read a single byte from the current input channel // 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 // read a single byte from the given file/channel, returns
// a negative result on failure. If this was the last byte // a negative result on failure. If this was the last byte

View File

@ -5,39 +5,42 @@
#include <c64/asm6502.h> #include <c64/asm6502.h>
#include <stdlib.h> #include <stdlib.h>
volatile char npos = 1, tpos = 0;
volatile byte rirq_count; volatile byte rirq_count;
static byte rirq_pcount;
byte rasterIRQRows[NUM_IRQS]; byte rasterIRQRows[NUM_IRQS + 1];
byte rasterIRQIndex[NUM_IRQS]; byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
byte rasterIRQNext[NUM_IRQS + 1]; #ifdef ZPAGE_IRQS
byte rasterIRQLow[NUM_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]; byte rasterIRQHigh[NUM_IRQS];
#ifdef ZPAGE_IRQS
__zeropage
#endif
byte nextIRQ; byte nextIRQ;
__asm irq0 // nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
{
pha
txa
pha
tya
pha
asl $d019 __asm rirq_isr_ram_io
{
stx plrx + 1
ldx nextIRQ ldx nextIRQ
bmi exi
sta plra + 1
sty plry + 1
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff ldy rasterIRQIndex + 1, x
beq e1 ldx rasterIRQLow, y
stx ji + 1
ldy rasterIRQIndex, x ldx rasterIRQHigh, y
tax stx ji + 2
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -45,21 +48,82 @@ ji:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
asl $d019
cpy #$ff
beq e2 beq e2
// carry is cleared at this point
tay
dey dey
sbc #2
cmp $d012
bcc l1
sty $d012 sty $d012
dey
cpy $d012
bcc l1
ex: plry:
ldy #0
plra:
lda #0
plrx:
ldx #0
rti
exi:
asl $d019
jmp plrx
// No more interrupts to service
e2:
inc rirq_count
ldy rasterIRQNext
dey
sty $d012
ldx #0
stx nextIRQ
beq plry
}
__asm rirq_isr_io
{
pha
txa
pha
tya
pha
kentry:
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
ji:
jsr $0000
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
beq e2
dey
sty $d012
dey
cpy $d012
bcc l1
exd:
pla pla
tay tay
pla pla
@ -67,56 +131,44 @@ ex:
pla pla
rti rti
e2: exi:
asl $d019
jmp exd
ldx npos e2:
stx tpos
inc rirq_count inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext ldy rasterIRQNext
dey dey
sty $d012 sty $d012
jmp ex ldx #0
stx nextIRQ
beq exd
} }
__asm irq2 __asm rirq_isr_noio
{ {
pha pha
txa txa
pha pha
tya tya
pha pha
kentry:
lda $01 lda $01
pha pha
lda #$35 lda #$35
sta $01 sta $01
asl $d019
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff ldy rasterIRQIndex + 1, x
beq e1 ldx rasterIRQLow, y
stx ji + 1
ldy rasterIRQIndex, x ldx rasterIRQHigh, y
tax stx ji + 2
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -124,21 +176,20 @@ ji:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
asl $d019
cpy #$ff
beq e2 beq e2
// carry is cleared at this point
tay
dey dey
sbc #2
cmp $d012
bcc l1
sty $d012 sty $d012
dey
cpy $d012
bcc l1
ex: exd:
pla pla
sta $01 sta $01
@ -149,45 +200,35 @@ ex:
pla pla
rti rti
e2: exi:
asl $d019
jmp exd
ldx npos e2:
stx tpos
inc rirq_count inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext ldy rasterIRQNext
dey dey
sty $d012 sty $d012
jmp ex ldx #0
stx nextIRQ
beq exd
} }
__asm irq1 __asm rirq_isr_kernal_io
{ {
lda $d019 lda $d019
bpl ex2 bpl ex2
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff ldy rasterIRQIndex + 1, x
beq e1 ldx rasterIRQLow, y
stx ji + 1
ldy rasterIRQIndex, x ldx rasterIRQHigh, y
tax stx ji + 2
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -196,45 +237,36 @@ jx:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
beq e2
tay
sec
sbc #4
cmp $d012
bcc l1
dey
sty $d012
w1:
jmp ex
e2:
ldx npos
stx tpos
inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
lda rasterIRQNext, x
sec
sbc #1
sta $d012
ex:
asl $d019 asl $d019
cpy #$ff
beq e2
dey
dey
sty $d012
dey
cpy $d012
bcc l1
exd:
jmp $ea81
exi:
asl $d019
jmp $ea81
e2:
inc rirq_count
ldy rasterIRQNext
dey
dey
sty $d012
ldx #0
stx nextIRQ
jmp $ea81 jmp $ea81
ex2: ex2:
@ -243,6 +275,76 @@ ex2:
jmp $ea31 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 // 0 lda #data0
// 2 ldy #data1 // 2 ldy #data1
// 4 cpx $d012 // 4 cpx $d012
@ -263,8 +365,8 @@ void rirq_build(RIRQCode * ic, byte size)
ic->size = size; ic->size = size;
asm_im(ic->code + 0, ASM_LDY, 0); asm_im(ic->code + 0, ASM_LDY, 0);
asm_im(ic->code + 2, ASM_LDA, 0); asm_im(ic->code + 2, ASM_LDX, 0);
asm_ab(ic->code + 4, ASM_CPX, 0xd012); asm_ab(ic->code + 4, ASM_CMP, 0xd012);
asm_rl(ic->code + 7, ASM_BCS, -5); asm_rl(ic->code + 7, ASM_BCS, -5);
asm_ab(ic->code + 9, ASM_STY, 0x0000); asm_ab(ic->code + 9, ASM_STY, 0x0000);
@ -278,7 +380,7 @@ void rirq_build(RIRQCode * ic, byte size)
} }
else else
{ {
asm_ab(ic->code + 12, ASM_STA, 0x0000); asm_ab(ic->code + 12, ASM_STX, 0x0000);
byte p = 15; byte p = 15;
for(byte i=2; i<size; i++) for(byte i=2; i<size; i++)
@ -328,10 +430,17 @@ void rirq_addr(RIRQCode * ic, byte n, void * addr)
ic->code[p + 1] = (unsigned)addr >> 8; 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) void rirq_data(RIRQCode * ic, byte n, byte data)
{ {
byte p = irqdi[n]; 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) void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
@ -370,21 +479,81 @@ void rirq_clear(byte n)
rasterIRQRows[n] = 255; rasterIRQRows[n] = 255;
} }
void rirq_init_kernal(void) void rirq_init_tables(void)
{ {
for(byte i=0; i<NUM_IRQS; i++) for(byte i=0; i<NUM_IRQS; i++)
{ {
rasterIRQRows[i] = 255; rasterIRQRows[i] = 255;
rasterIRQIndex[i] = i; rasterIRQIndex[i + 1] = i;
} }
rasterIRQIndex[0] = NUM_IRQS;
rasterIRQRows[NUM_IRQS] = 0;
rasterIRQNext[NUM_IRQS] = 255; rasterIRQNext[NUM_IRQS] = 255;
}
void rirq_init_kernal(void)
{
rirq_init_tables();
__asm __asm
{ {
sei sei
} }
*(void **)0x0314 = irq1; *(void **)0x0314 = rirq_isr_kernal_io;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_init_kernal_noio(void)
{
rirq_init_tables();
__asm
{
sei
}
*(void **)0x0314 = rirq_isr_kernal_noio;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_init_crt(void)
{
rirq_init_tables();
__asm
{
sei
}
*(void **)0x0314 = rirq_isr_io.kentry;
*(void **)0xfffe = rirq_isr_io;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_init_crt_noio(void)
{
rirq_init_tables();
__asm
{
sei
}
*(void **)0x0314 = rirq_isr_noio.kentry;
*(void **)0xfffe = rirq_isr_noio;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -394,19 +563,14 @@ void rirq_init_kernal(void)
void rirq_init_io(void) void rirq_init_io(void)
{ {
for(byte i=0; i<NUM_IRQS; i++) rirq_init_tables();
{
rasterIRQRows[i] = 255;
rasterIRQIndex[i] = i;
}
rasterIRQNext[NUM_IRQS] = 255;
__asm __asm
{ {
sei sei
} }
*(void **)0xfffe = irq0; *(void **)0xfffe = rirq_isr_ram_io;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -416,19 +580,14 @@ void rirq_init_io(void)
void rirq_init_memmap(void) void rirq_init_memmap(void)
{ {
for(byte i=0; i<NUM_IRQS; i++) rirq_init_tables();
{
rasterIRQRows[i] = 255;
rasterIRQIndex[i] = i;
}
rasterIRQNext[NUM_IRQS] = 255;
__asm __asm
{ {
sei sei
} }
*(void **)0xfffe = irq2; *(void **)0xfffe = rirq_isr_noio;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -446,12 +605,39 @@ void rirq_init(bool kernalIRQ)
void rirq_wait(void) void rirq_wait(void)
{ {
while (tpos != npos) ; char i0 = rirq_pcount;
npos++; 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++) for(byte i = 1; i<NUM_IRQS; i++)
{ {
byte ri = rasterIRQIndex[i]; byte ri = rasterIRQIndex[i];
@ -464,14 +650,32 @@ void rirq_sort(void)
} }
rasterIRQIndex[j] = ri; rasterIRQIndex[j] = ri;
} }
#endif
for(byte i=0; i<NUM_IRQS; i++) #if NUM_IRQS & 3
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i]]; 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++; rirq_pcount = rirq_count;
byte yp = rasterIRQNext[nextIRQ]; if (inirq)
if (yp != 0xff) nextIRQ = NUM_IRQS - 1;
vic.raster = yp - 1; else
{
byte yp = rasterIRQNext[0];
if (yp != 0xff)
{
vic.raster = yp - 1;
nextIRQ = 0;
}
}
} }
void rirq_start(void) void rirq_start(void)
@ -485,6 +689,7 @@ void rirq_start(void)
lda #100 lda #100
sta $d012 sta $d012
asl $d019
cli cli
} }
} }

View File

@ -123,13 +123,17 @@ inline void rirq_call(RIRQCode * ic, byte n, void * addr);
// Change the address of a raster IRQ write command // Change the address of a raster IRQ write command
inline void rirq_addr(RIRQCode * ic, byte n, void * addr); 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 // Change the data of a raster IRQ write command
inline void rirq_data(RIRQCode * ic, byte n, byte data); inline void rirq_data(RIRQCode * ic, byte n, byte data);
// Add a delay of 5 * cycles to a raster IRQ // Add a delay of 5 * cycles to a raster IRQ
inline void rirq_delay(RIRQCode * ic, byte cycles); 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); inline void rirq_set(byte n, byte row, RIRQCode * write);
// Remove a raster IRQ from one of the 16 slots // Remove a raster IRQ from one of the 16 slots
@ -144,10 +148,28 @@ inline void rirq_move(byte n, byte row);
// the less resource hungry option) // the less resource hungry option)
inline 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); 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); 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); void rirq_init_memmap(void);
// Start raster IRQ // Start raster IRQ
@ -157,8 +179,9 @@ void rirq_start(void);
void rirq_stop(void); void rirq_stop(void);
// Sort the raster IRQ, must be performed at the end of the frame after changing // Sort the raster IRQ, must be performed at the end of the frame after changing
// the vertical position of one of the interrupt operatins. // the vertical position of one of the interrupt operations.
void rirq_sort(void); // 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 // Wait for the last raster IRQ op to have completed. Must be called before a
// sort if the raster IRQ system is active // sort if the raster IRQ system is active

View File

@ -1,8 +1,11 @@
#include "sprites.h" #include "sprites.h"
#include "rasterirq.h" #include "rasterirq.h"
static char * vspriteScreen; static volatile char * vspriteScreen;
#ifdef VSPRITE_BSS
#pragma bss(VSPRITE_BSS)
#endif
void spr_init(char * screen) void spr_init(char * screen)
{ {
@ -108,6 +111,22 @@ void spr_color(char sp, char color)
vic.spr_color[sp] = color; vic.spr_color[sp] = color;
} }
void spr_expand(char sp, bool xexpand, bool yexpand)
{
__assume (sp < 8);
char m = 1 << sp;
if (xexpand)
vic.spr_expand_x |= m;
else
vic.spr_expand_x &= ~m;
if (yexpand)
vic.spr_expand_y |= m;
else
vic.spr_expand_y &= ~m;
}
static char vspriteYLow[VSPRITES_MAX], vspriteXLow[VSPRITES_MAX], vspriteXHigh[VSPRITES_MAX]; static char vspriteYLow[VSPRITES_MAX], vspriteXLow[VSPRITES_MAX], vspriteXHigh[VSPRITES_MAX];
static char vspriteImage[VSPRITES_MAX], vspriteColor[VSPRITES_MAX]; static char vspriteImage[VSPRITES_MAX], vspriteColor[VSPRITES_MAX];
@ -127,7 +146,11 @@ void vspr_init(char * screen)
for(int i=0; i<VSPRITES_MAX - 8; i++) for(int i=0; i<VSPRITES_MAX - 8; i++)
{ {
#ifdef VSPRITE_REVERSE
int j = (i & 7) ^ 7;
#else
int j = i & 7; int j = i & 7;
#endif
rirq_build(spirq + i, 5); rirq_build(spirq + i, 5);
rirq_write(spirq + i, 0, &vic.spr_color[j], 0); rirq_write(spirq + i, 0, &vic.spr_color[j], 0);
@ -148,6 +171,21 @@ void vspr_init(char * screen)
} }
} }
void vspr_shutdown(void)
{
for(int i=0; i<VSPRITES_MAX - 7; i++)
rirq_clear(i);
}
void vspr_screen(char * screen)
{
vspriteScreen = screen + 0x3f8;
char hi = (unsigned)vspriteScreen >> 8;
#pragma unroll(8)
for(int i=0; i<VSPRITES_MAX - 8; i++)
rirq_addrhi(spirq + i, 3, hi);
}
#pragma native(vspr_init) #pragma native(vspr_init)
void vspr_set(char sp, int xpos, int ypos, char image, char color) void vspr_set(char sp, int xpos, int ypos, char image, char color)
@ -176,6 +214,21 @@ void vspr_move(char sp, int xpos, int ypos)
vspriteXHigh[sp] = (char)(xpos >> 8); 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) void vspr_image(char sp, char image)
{ {
vspriteImage[sp] = image; vspriteImage[sp] = image;
@ -193,22 +246,30 @@ void vspr_hide(char sp)
void vspr_sort(void) void vspr_sort(void)
{ {
spriteYPos[1] = vspriteYLow[spriteOrder[0]]; byte rm = vspriteYLow[spriteOrder[0]];
spriteYPos[1] = rm;
for(char i = 1; i<VSPRITES_MAX; i++) for(char i = 1; i<VSPRITES_MAX; i++)
{ {
byte ri = spriteOrder[i]; byte ri = spriteOrder[i];
byte rr = vspriteYLow[ri]; byte rr = vspriteYLow[ri];
byte j = i, rj = spriteYPos[j]; if (rr < rm)
while (rr < rj)
{ {
spriteYPos[j + 1] = rj; byte j = i, rj = rm;
spriteOrder[j] = spriteOrder[j - 1]; do {
rj = spriteYPos[j - 1]; spriteYPos[j + 1] = rj;
j--; 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;
} }
} }
@ -217,45 +278,68 @@ void vspr_sort(void)
void vspr_update(void) void vspr_update(void)
{ {
char xymask = 0; char xymask = 0;
char * vsprs = vspriteScreen; volatile char * vsprs = vspriteScreen;
// char sypos[VSPRITES_MAX];
#pragma unroll(full) #pragma unroll(full)
for(char ui=0; ui<8; ui++) for(char ui=0; ui<8; ui++)
{ {
byte ri = spriteOrder[ui]; byte ri = spriteOrder[ui];
#ifdef VSPRITE_REVERSE
char uj = ui ^ 7;
#else
char uj = ui;
#endif
vic.spr_color[ui] = vspriteColor[ri]; vic.spr_color[uj] = vspriteColor[ri];
vsprs[ui] = vspriteImage[ri]; vsprs[uj] = vspriteImage[ri];
#ifdef VSPRITE_REVERSE
xymask = (xymask << 1) | (vspriteXHigh[ri] & 1);
#else
xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1; xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1;
vic.spr_pos[ui].x = vspriteXLow[ri]; #endif
vic.spr_pos[ui].y = vspriteYLow[ri]; vic.spr_pos[uj].x = vspriteXLow[ri];
vic.spr_pos[uj].y = spriteYPos[ui + 1];
// sypos[ui] = vspriteYLow[ri];
} }
vic.spr_msbx = xymask; vic.spr_msbx = xymask;
#pragma unroll(full) #pragma unroll(full)
bool done = false;
for(char ti=0; ti<VSPRITES_MAX - 8; ti++) for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
{ {
if (spriteYPos[ti + 8] < 250) if (!done && spriteYPos[ti + 9] < 250)
{ {
char m = 1 << (ti & 7);
byte ri = spriteOrder[ti + 8]; 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; xymask |= m;
if (!vspriteXHigh[ri]) if (!(vspriteXHigh[ri] & 1))
xymask ^= m; xymask ^= m;
rirq_data(spirq + ti, 2, spriteYPos[ti + 9]);
rirq_data(spirq + ti, 0, vspriteColor[ri]); rirq_data(spirq + ti, 0, vspriteColor[ri]);
rirq_data(spirq + ti, 1, vspriteXLow[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, 3, vspriteImage[ri]);
rirq_data(spirq + ti, 4, xymask); rirq_data(spirq + ti, 4, xymask);
rirq_move(ti, spriteYPos[ti + 1] + 23); // spriteYPos[ti + 9] = vspriteYLow[ri];
} }
else else
{
rirq_clear(ti); rirq_clear(ti);
done = true;
}
} }
} }

View File

@ -39,6 +39,10 @@ inline void spr_image(char sp, char image);
inline void spr_color(char sp, char color); 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 // The virtual sprite system works with the rasterirq library to multiplex
// 16 virtual sprites onto the actual eight hardware sprites. It uses the slots // 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 // 0 to 8 of the rasterirq library to switch the sprites mid screen. The
@ -64,6 +68,10 @@ inline void spr_color(char sp, char color);
void vspr_init(char * screen); void vspr_init(char * screen);
void vspr_shutdown(void);
void vspr_screen(char * screen);
// set one sprite with the given attribute // set one sprite with the given attribute
void vspr_set(char sp, int xpos, int ypos, char image, char color); void vspr_set(char sp, int xpos, int ypos, char image, char color);
@ -72,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_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 // change the image of a virtual sprite
inline void vspr_image(char sp, char image); inline void vspr_image(char sp, char image);

View File

@ -21,7 +21,7 @@ int vic_sprgetx(byte s)
return vic.spr_pos[s].x | ((vic.spr_msbx & (1 << s)) ? 256 : 0); return vic.spr_pos[s].x | ((vic.spr_msbx & (1 << s)) ? 256 : 0);
} }
void vic_setmode(VicMode mode, char * text, char * font) void vic_setmode(VicMode mode, const char * text, const char * font)
{ {
switch (mode) switch (mode)
{ {
@ -73,6 +73,15 @@ void vic_waitFrame(void)
; ;
} }
void vic_waitFrames(char n)
{
while (n > 0)
{
vic_waitFrame();
n--;
}
}
void vic_waitLine(int line) void vic_waitLine(int line)
{ {
char upper = (char)(line >> 1) & VIC_CTRL1_RST8; char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
@ -85,4 +94,41 @@ void vic_waitLine(int line)
} while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper); } 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) #pragma native(vic_waitLine)

View File

@ -91,7 +91,7 @@ enum VicMode
// set the display mode and base address. This will also // set the display mode and base address. This will also
// adapt the bank. // 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 // put a sprite at the given x/y location, taking care of the
// x MSB // x MSB
@ -109,9 +109,18 @@ inline void vic_waitTop(void);
// wait for the top of the frame and then for the bottom of the visual area // wait for the top of the frame and then for the bottom of the visual area
inline void vic_waitFrame(void); inline void vic_waitFrame(void);
// wait for n frames
void vic_waitFrames(char n);
// wait for a specific raster line // wait for a specific raster line
void vic_waitLine(int 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 // reference to the VIC chip
#define vic (*((struct VIC *)0xd000)) #define vic (*((struct VIC *)0xd000))

View File

@ -18,6 +18,13 @@ __asm bsin
jsr 0xffe4 jsr 0xffe4
sta 0xff01 sta 0xff01
} }
__asm bsget
{
lda #0
sta 0xff00
jsr 0xffcf
sta 0xff01
}
__asm bsplot __asm bsplot
{ {
lda #0 lda #0
@ -39,6 +46,13 @@ __asm dswap
sta 0xff01 sta 0xff01
} }
#pragma code(code) #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__) #elif defined(__PLUS4__)
#pragma code(lowcode) #pragma code(lowcode)
__asm bsout __asm bsout
@ -53,6 +67,12 @@ __asm bsin
jsr 0xffe4 jsr 0xffe4
sta 0xff3f sta 0xff3f
} }
__asm bsget
{
sta 0xff3e
jsr 0xffcf
sta 0xff3f
}
__asm bsplot __asm bsplot
{ {
sta 0xff3e sta 0xff3e
@ -85,6 +105,14 @@ __asm bsin
pha pha
} }
__asm bsget
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot __asm bsplot
{ {
@ -93,14 +121,37 @@ __asm bsinit
{ {
} }
#elif defined(__VIC20__)
#define bsout 0xffd2
#define bsin 0xffe4
#define bsplot 0xfff0
#define bsget 0xffcf
__asm bsinit
{
lda #147
jmp $ffd2
}
#elif defined(__CBMPET__)
#define bsout 0xffd2
#define bsin 0xffe4
__asm bsplot
{
/* no equivalent on PET */
}
__asm bsinit
{
/* no equivalent on PET */
}
#define bsget 0xffcf
#else #else
#define bsout 0xffd2 #define bsout 0xffd2
#define bsin 0xffe4 #define bsin 0xffe4
#define bsplot 0xfff0 #define bsplot 0xfff0
#define bsinit 0xff81 #define bsinit 0xff81
#define bsget 0xffcf
#endif #endif
#if defined(__C128__) #if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
void dispmode40col(void) void dispmode40col(void)
{ {
if (*(volatile char *)0xd7 >= 128) if (*(volatile char *)0xd7 >= 128)
@ -130,168 +181,195 @@ void iocharmap(IOCharMap chmap)
giocharmap = chmap; giocharmap = chmap;
#if !defined(__ATARI__) #if !defined(__ATARI__)
if (chmap == IOCHM_PETSCII_1) if (chmap == IOCHM_PETSCII_1)
putch(128 + 14); putrch(128 + 14);
else if (chmap == IOCHM_PETSCII_2) else if (chmap == IOCHM_PETSCII_2)
putch(14); putrch(14);
#endif #endif
} }
__asm putpch void putrch(char c)
{ {
ldx giocharmap __asm {
cpx #IOCHM_ASCII lda c
bcc w3 jsr bsout
}
cmp #10 }
bne w1
lda #13
w1:
cpx #IOCHM_PETSCII_1
bcc w3
cmp #65
bcc w3
cmp #123
bcs w3
#if defined(__CBMPET__)
cmp #97
bcs w4
cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
void putpch(char c)
{
#if defined(__ATARI__)
if (c == 10)
c = 0x9b;
#else #else
cmp #97 if (giocharmap >= IOCHM_ASCII)
bcs w2 {
cmp #91 if (c == '\n')
bcs w3 c = 13;
w2: else if (c == '\t')
eor #$20 {
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 #endif
cpx #IOCHM_PETSCII_2
beq w3 if (giocharmap == IOCHM_PETSCII_1)
and #$df c &= 0xdf;
w3: }
jmp bsout }
}
}
#endif
putrch(c);
} }
__asm getpch static char convch(char ch)
{ {
jsr bsin #if !defined(__ATARI__)
ldx giocharmap if (giocharmap >= IOCHM_ASCII)
cpx #IOCHM_ASCII {
bcc w3 if (ch == 13)
ch = 10;
else if (giocharmap >= IOCHM_PETSCII_1)
{
if (ch >= 65 && ch < 219)
{
if (ch >= 193)
ch ^= 0xa0;
if (ch < 123 && (ch >= 97 || ch < 91))
ch ^= 0x20;
}
}
}
cmp #13 #endif
bne w1 return ch;
lda #10 }
w1:
cpx #IOCHM_PETSCII_1
bcc w3
cmp #219 char getrch(void)
bcs w3 {
cmp #65 return __asm {
bcc w3 jsr bsget
sta accu
};
}
cmp #193 char getpch(void)
bcc w4 {
eor #$a0 return convch(getrch());
w4:
cmp #123
bcs w3
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
w3:
} }
int kbhit(void) char kbhit(void)
{ {
__asm #if defined(__CBMPET__)
return __asm
{
lda $9e
sta accu
};
#else
return __asm
{ {
lda $c6 lda $c6
sta accu sta accu
lda #0 };
sta accu + 1 #endif
}
} }
int getche(void) char getche(void)
{ {
__asm char ch;
{ do {
L1: ch = __asm {
jsr getpch jsr bsin
cmp #0 sta accu
beq L1 };
} while (!ch);
sta accu
jsr putpch
lda #0
sta accu + 1
}
}
int getch(void)
{
__asm
{
L1:
jsr getpch
cmp #0
beq L1
sta accu
lda #0
sta accu + 1
}
}
int getchx(void)
{
__asm
{
jsr getpch
sta accu
lda #0
sta accu + 1
}
}
void putch(int c)
{
__asm { __asm {
lda c lda ch
jsr bsout 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) void clrscr(void)
{ {
__asm putrch(147);
{
jsr bsinit
}
} }
void textcursor(bool show) 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 __asm
{ {
ldx cy ldx cy
@ -299,35 +377,50 @@ void gotoxy(int cx, int cy)
clc clc
jsr bsplot jsr bsplot
} }
#endif
} }
void textcolor(int c) void textcolor(char c)
{ {
__asm *(volatile char *)0x0286 = c;
{
lda c
sta $0286
}
} }
int wherex(void) void bgcolor(char c)
{ {
__asm *(volatile char *)0xd021 = c;
{
lda $d3
sta accu
lda #0
sta accu + 1
}
} }
int wherey(void) void bordercolor(char c)
{ {
__asm *(volatile char *)0xd020 = c;
{ }
lda $d6
sta accu void revers(char r)
lda #0 {
sta accu + 1 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
} }

View File

@ -18,36 +18,95 @@ extern IOCharMap giocharmap;
void iocharmap(IOCharMap chmap); void iocharmap(IOCharMap chmap);
#if defined(__C128__) #if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
void dispmode40col(void); void dispmode40col(void);
void dispmode80col(void); void dispmode80col(void);
#endif #endif
int kbhit(void); #define PETSCII_CURSOR_LEFT 0x9d
#define PETSCII_CURSOR_RIGHT 0x1d
#define PETSCII_CURSOR_UP 0x91
#define PETSCII_CURSOR_DOWN 0x11
#define PETSCII_HOME 0x13
#define PETSCII_CLEAR 0x94
#define PETSCII_DEL 0x14
#define PETSCII_INSERT 0x94
#define PETSCII_STOP 0x03
#define PETSCII_RETURN 0x0d
int getche(void); #define PETSCII_F1 0x85
#define PETSCII_F2 0x89
#define PETSCII_F3 0x86
#define PETSCII_F4 0x8a
#define PETSCII_F5 0x87
#define PETSCII_F6 0x8b
#define PETSCII_F7 0x88
#define PETSCII_F8 0x8c
int getch(void); enum ConioColors
{
COLOR_BLACK,
COLOR_WHITE,
COLOR_RED,
COLOR_CYAN,
COLOR_PURPLE,
COLOR_GREEN,
COLOR_BLUE,
COLOR_YELLOW,
COLOR_ORANGE,
COLOR_BROWN,
COLOR_LT_RED,
COLOR_DARK_GREY,
COLOR_MED_GREY,
COLOR_LT_GREEN,
COLOR_LT_BLUE,
COLOR_LT_GREY
};
// Lowlevel console in/out
// using petscii translation
void putpch(char c);
char getpch(void);
// using no translation
inline void putrch(char c);
inline char getrch(void);
// Standard console in/out
char kbhit(void);
char getche(void);
char getch(void);
// like getch but does not wait, returns zero if no // like getch but does not wait, returns zero if no
// key is pressed // key is pressed
int getchx(void); char getchx(void);
void putch(int c); void putch(char c);
void clrscr(void); 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 // show or hide the text cursor
void textcursor(bool show); inline void textcursor(bool show);
#pragma compile("conio.c") #pragma compile("conio.c")

File diff suppressed because it is too large Load Diff

View File

@ -144,8 +144,8 @@ enum ByteCode
BC_LOOP_U8, BC_LOOP_U8,
BC_MALLOC, BC_MALLOC,
BC_FREE, BC_FREE,
BC_UNUSED_4, BC_FILL,
BC_UNUSED_5, BC_FILL_LONG,
BC_UNUSED_6, BC_UNUSED_6,
BC_JSR, BC_JSR,
@ -186,6 +186,11 @@ enum ByteCode
BC_BINOP_SHR_I32, BC_BINOP_SHR_I32,
BC_BINOP_CMP_U32, BC_BINOP_CMP_U32,
BC_BINOP_CMP_S32, BC_BINOP_CMP_S32,
BC_CONV_U32_F32,
BC_CONV_I32_F32,
BC_CONV_F32_U32,
BC_CONV_F32_I32,
}; };
#endif #endif

View File

@ -1,4 +1,5 @@
#include "ctype.h" #include "ctype.h"
#include "conio.h"
#define CC_CTRL 0x00 #define CC_CTRL 0x00
#define CC_BREAK 0x01 #define CC_BREAK 0x01
@ -86,3 +87,19 @@ bool isxdigit(char c)
{ {
return (c < 128) && (_cinfo[c] & CC_HEX); return (c < 128) && (_cinfo[c] & CC_HEX);
} }
char tolower(char c)
{
if (c >= 'A' && c <= 'Z')
return c + ('a' - 'A');
else
return c;
}
char toupper(char c)
{
if (c >= 'a' && c <= 'z')
return c + ('A' - 'a');
else
return c;
}

View File

@ -25,6 +25,9 @@ inline bool isdigit(char c);
inline bool isxdigit(char c); inline bool isxdigit(char c);
char tolower(char c);
char toupper(char c);
#pragma compile("ctype.c") #pragma compile("ctype.c")

View File

@ -116,31 +116,38 @@ int lmul4f12s(int x, int y)
{ {
__asm __asm
{ {
bit y + 1
bpl W0
sec sec
lda #0 lda x
sbc y ror
sta y sta accu
lda #0
sbc y + 1
sta y + 1
sec
lda #0
sbc x
sta x
lda #0
sbc x + 1
sta x + 1
W0:
ldx #15
lda #0 lda #0
sta accu + 1 sta accu + 1
L1: lsr x + 1 bcc W4
ror x L2:
tay
clc
lda accu + 1
adc y
sta accu + 1
tya
adc y + 1
W4:
ror
ror accu + 1
lsr accu
bcc W4
bne L2
ldx x + 1
stx accu
ldx #7
lsr accu
L1:
bcc W1 bcc W1
tay tay
clc clc
@ -156,23 +163,31 @@ W1:
dex dex
bne L1 bne L1
lsr x
bcc W2 bcc W2
tay tay
sec // sec ; we know it is set here
lda accu + 1 lda accu + 1
sbc y sbc y
sta accu + 1 sta accu + 1
tya tya
sbc y + 1 sbc y + 1
sec
W2: W2:
ror ror
ror accu + 1 ror accu + 1
ror accu ror accu
bit y + 1
bpl W3
tax
sec
lda accu + 1
sbc x
sta accu + 1
txa
sbc x + 1
W3:
lsr lsr
ror accu + 1 ror accu + 1
ror accu ror accu
@ -270,15 +285,17 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
__asm __asm
{ {
lda #0 lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2 sta __tmp + 2
sta __tmp + 3 sta __tmp + 3
ldx #16 lda a
L1: lsr a + 1 sec
ror a T1:
ldy #8
L1:
ror
bcc W1 bcc W1
tax
clc clc
lda __tmp + 2 lda __tmp + 2
adc b adc b
@ -286,20 +303,38 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3 lda __tmp + 3
adc b + 1 adc b + 1
sta __tmp + 3 sta __tmp + 3
txa
W1: W1:
ror __tmp + 3 ror __tmp + 3
ror __tmp + 2 ror __tmp + 2
ror __tmp + 1 dey
ror __tmp
dex
bne L1 bne L1
ror
bcc T2
lda #0 sta __tmp + 0
sta accu lda a + 1
sta accu + 1 clc
bcc T1
ldx #17 T2:
sec
L3:
sta __tmp + 1
ldx #8
L2: L2:
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
bcc W3
lda __tmp + 2
sbc c
tay
lda __tmp + 3
sbc c + 1
sec
bcs W4
W3:
sec sec
lda __tmp + 2 lda __tmp + 2
sbc c sbc c
@ -307,33 +342,23 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
lda __tmp + 3 lda __tmp + 3
sbc c + 1 sbc c + 1
bcc W2 bcc W2
W4:
sta __tmp + 3 sta __tmp + 3
sty __tmp + 2 sty __tmp + 2
W2: W2:
rol accu
rol accu + 1
asl __tmp
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex dex
beq E2 bne L2
bcc L2 lda __tmp + 1
rol
lda __tmp + 2 bcc T3
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
} }
} }
int lmuldiv16s(int a, int b, int c) int lmuldiv16s(int a, int b, int c)
@ -358,15 +383,17 @@ int lmuldiv16s(int a, int b, int c)
__asm __asm
{ {
lda #0 lda #0
sta __tmp + 0
sta __tmp + 1
sta __tmp + 2 sta __tmp + 2
sta __tmp + 3 sta __tmp + 3
ldx #16 lda a
L1: lsr a + 1 sec
ror a T1:
ldy #8
L1:
ror
bcc W1 bcc W1
tax
clc clc
lda __tmp + 2 lda __tmp + 2
adc b adc b
@ -374,20 +401,38 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3 lda __tmp + 3
adc b + 1 adc b + 1
sta __tmp + 3 sta __tmp + 3
txa
W1: W1:
ror __tmp + 3 ror __tmp + 3
ror __tmp + 2 ror __tmp + 2
ror __tmp + 1 dey
ror __tmp
dex
bne L1 bne L1
ror
bcc T2
lda #0 sta __tmp + 0
sta accu lda a + 1
sta accu + 1 clc
bcc T1
ldx #17 T2:
sec
L3:
sta __tmp + 1
ldx #8
L2: L2:
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
bcc W3
lda __tmp + 2
sbc c
tay
lda __tmp + 3
sbc c + 1
sec
bcs W4
W3:
sec sec
lda __tmp + 2 lda __tmp + 2
sbc c sbc c
@ -395,30 +440,23 @@ int lmuldiv16s(int a, int b, int c)
lda __tmp + 3 lda __tmp + 3
sbc c + 1 sbc c + 1
bcc W2 bcc W2
W4:
sta __tmp + 3 sta __tmp + 3
sty __tmp + 2 sty __tmp + 2
W2: W2:
rol accu
rol accu + 1
asl __tmp
rol __tmp + 1
rol __tmp + 2
rol __tmp + 3
dex dex
beq E2 bne L2
bcc L2 lda __tmp + 1
rol
bcc T3
sta accu + 1
lda __tmp + 0
clc
bcc L3
T3:
sta accu
lda __tmp + 2
sbc c
sta __tmp + 2
lda __tmp + 3
sbc c + 1
sta __tmp + 3
sec
bcs W2
E2:
lda sign lda sign
beq E1 beq E1
@ -610,3 +648,264 @@ unsigned usqrt(unsigned n)
return p; return p;
} }
unsigned long lmul16f16(unsigned long x, unsigned long y)
{
unsigned long hh = lmul16u(x >> 16, y >> 16);
unsigned long lh = lmul16u(x, y >> 16);
unsigned long hl = lmul16u(x >> 16, y);
unsigned long ll = lmul16u(x, y);
if (ll & 0x8000)
lh++;
ll >>= 16;
ll |= hh << 16;
ll += lh;
ll += hl;
return ll;
}
#if 1
long lmul16f16s(long x, long y)
{
__asm
{
lda #0
// fractional
sta __tmp + 0
sta __tmp + 1
// result
sta __accu + 0
sta __accu + 1
sta __accu + 2
sta __accu + 3
lda x + 0
ora x + 1
ora y + 0
ora y + 1
bne w0b
l2:
lsr x + 2
bcc ws1
clc
lda y + 2
adc __accu + 2
sta __accu + 2
lda y + 3
adc __accu + 3
sta __accu + 3
ws1:
lsr x + 3
bcc ws2
clc
lda y + 2
adc __accu + 3
sta __accu + 3
ws2:
asl y + 2
rol y + 3
lda x + 2
ora x + 3
bne l2
rts
w0b:
lda y + 3
and #$80
beq w0
lda #$ff
w0:
// overflow
sta __tmp + 2
sta __tmp + 3
lda x + 3
bpl w0a
sec
lda #0
sbc y + 0
sta __accu + 2
lda #0
sbc y + 1
sta __accu + 3
w0a:
ldx #8
l1:
lsr x + 0
bcc w1
clc
lda y + 0
adc __tmp + 0
sta __tmp + 0
lda y + 1
adc __tmp + 1
sta __tmp + 1
lda y + 2
adc __accu + 0
sta __accu + 0
lda y + 3
adc __accu + 1
sta __accu + 1
lda __tmp + 2
adc __accu + 2
sta __accu + 2
lda __tmp + 3
adc __accu + 3
sta __accu + 3
w1:
lsr x + 1
bcc w2
clc
lda y + 0
adc __tmp + 1
sta __tmp + 1
lda y + 1
adc __accu + 0
sta __accu + 0
lda y + 2
adc __accu + 1
sta __accu + 1
lda y + 3
adc __accu + 2
sta __accu + 2
lda __tmp + 2
adc __accu + 3
sta __accu + 3
w2:
lsr x + 2
bcc w3
clc
lda y + 0
adc __accu + 0
sta __accu + 0
lda y + 1
adc __accu + 1
sta __accu + 1
lda y + 2
adc __accu + 2
sta __accu + 2
lda y + 3
adc __accu + 3
sta __accu + 3
w3:
lsr x + 3
bcc w4
clc
lda y + 0
adc __accu + 1
sta __accu + 1
lda y + 1
adc __accu + 2
sta __accu + 2
lda y + 2
adc __accu + 3
sta __accu + 3
w4:
asl y + 0
rol y + 1
rol y + 2
rol y + 3
rol __tmp + 2
rol __tmp + 3
dex
beq w5
jmp l1
w5:
}
}
#else
__native long lmul16f16s(long x, long y)
{
unsigned lox = x;
int hix = x >> 16;
unsigned loy = y;
int hiy = y >> 16;
long r = (long)(hix * hiy) << 16;
if (lox)
{
r += lmul16u(lox, hiy);
if (hiy < 0)
r -= (unsigned long)lox << 16;
}
if (loy)
{
r += lmul16u(loy, hix);
if (hix < 0)
r -= (unsigned long)loy << 16;
}
if (lox && loy)
{
r += lmul16u(lox, loy) >> 16;
}
return r;
}
#endif
__native unsigned long ldiv16f16(unsigned long x, unsigned long y)
{
unsigned long k = x >> 16, d = 0;
x <<= 16;
for(char i=0; i<32; i++)
{
d <<= 1;
k <<= 1;
k |= (x >> 31);
x <<= 1;
if (k >= y)
{
k -= y;
d |= 1;
}
}
return d;
}
__native long ldiv16f16s(long x, long y)
{
bool sign = false;
if (x < 0)
{
x = -x;
sign = true;
}
if (y < 0)
{
y = -y;
sign = !sign;
}
x = ldiv16f16(x, y);
if (sign)
return -x;
else
return x;
}

View File

@ -50,6 +50,15 @@ __native unsigned lmuldiv8by8(char a, char b, char c);
__native unsigned usqrt(unsigned n); __native unsigned usqrt(unsigned n);
__native unsigned long lmul16f16(unsigned long x, unsigned long y);
__native long lmul16f16s(long x, long y);
__native unsigned long ldiv16f16(unsigned long x, unsigned long y);
__native long ldiv16f16s(long x, long y);
#pragma compile("fixmath.c") #pragma compile("fixmath.c")
#endif #endif

View File

@ -525,7 +525,7 @@ void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int
static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op) static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
{ {
char ip = 0; char ip = 0;
bool delta16 = ((dx | dy) & 0xff80) != 0; bool delta16 =((dx | dy) & 0xff80) != 0;
// ylow // ylow
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly); ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly);
@ -579,59 +579,105 @@ static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool
break; break;
} }
// m >= 0 if (dy)
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, delta16 ? 5 + 15 + 13 + 2 : 5 + 15 + 7 + 2);
ip += asm_np(BLIT_CODE + ip, up ? ASM_DEY : ASM_INY);
ip += asm_im(BLIT_CODE + ip, ASM_CPY, up ? 0xff : 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 15);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, up ? 0x07 : 0x00);
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{ {
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); bool delta8 = false;
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1); if (dx)
{
// m >= 0
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
char n = delta16 ? 18 + 13 + 2 : 18 + 7 + 2;
if (!up) n++;
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, n);
delta8 = !delta16;
}
if (up)
{
ip += asm_np(BLIT_CODE + ip, ASM_DEY);
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta8 ? 17 : 15);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x07);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
}
else
{
ip += asm_np(BLIT_CODE + ip, ASM_INY);
ip += asm_im(BLIT_CODE + ip, ASM_CPY, 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, delta8 ? 16 : 14);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x00);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
}
if (dx)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 13 + 4 + 12);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
}
else
{
// We know regdp to be in the accu at this point
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 5 + 4 + 12);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
}
}
// m < 0
} }
// m < 0 if (dx)
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta16 ? 4 + 15 + 13 : 4 + 15 + 7);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 15);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xf8 : 0x08);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xff : 0x00);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{ {
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8); ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
if (left)
{
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0xf8);
ip += asm_rl(BLIT_CODE + ip, ASM_BCS, 2);
ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_SP + 1);
}
else
{
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 2);
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_SP + 1);
}
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
} }
// l -- // l --
@ -649,6 +695,7 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern)
{ {
__asm __asm
{ {
lda dst lda dst
sta REG_SP sta REG_SP
lda dst + 1 lda dst + 1

26
include/inttypes.c Normal file
View File

@ -0,0 +1,26 @@
#include "inttypes.h"
#include "stdlib.h"
intmax_t imaxabs(intmax_t n)
{
return n < 0 ? -n : n;
}
imaxdiv_t imaxdiv(intmax_t l, intmax_t r)
{
imaxdiv_t t;
t.quot = l / r;
t.rem = l % r;
return t;
}
inline intmax_t strtoimax(const char * s, char ** endp, int base)
{
return strtol(s, endp, base);
}
inline uintmax_t strtoumax(const char * s, char ** endp, int base)
{
return strtoul(s, endp, base);
}

98
include/inttypes.h Normal file
View File

@ -0,0 +1,98 @@
#ifndef INTTYPES_H
#define INTTYPES_H
#include <stdint.h>
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "ld"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "ld"
#define PRIdFAST8 "d"
#define PRIdFAST16 "d"
#define PRIdFAST32 "ld"
#define PRIdMAX "ld"
#define PRIdPTR "d"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "lo"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "lo"
#define PRIoFAST8 "o"
#define PRIoFAST16 "o"
#define PRIoFAST32 "lo"
#define PRIoMAX "lo"
#define PRIoPTR "o"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "lu"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "lu"
#define PRIuFAST8 "u"
#define PRIuFAST16 "u"
#define PRIuFAST32 "lu"
#define PRIuMAX "lu"
#define PRIuPTR "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "lx"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "lx"
#define PRIxFAST8 "x"
#define PRIxFAST16 "x"
#define PRIxFAST32 "lx"
#define PRIxMAX "lx"
#define PRIxPTR "x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "lX"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "lX"
#define PRIXFAST8 "X"
#define PRIXFAST16 "X"
#define PRIXFAST32 "lX"
#define PRIXMAX "lX"
#define PRIXPTR "X"
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
intmax_t imaxabs(intmax_t n);
imaxdiv_t imaxdiv(intmax_t l, intmax_t r);
intmax_t strtoimax(const char * s, char ** endp, int base);
uintmax_t strtoumax(const char * s, char ** endp, int base);
#pragma compile("inttypes.c")
#endif

16
include/iso646.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef ISO646_H
#define ISO646_H
#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=
#endif

View File

@ -11,7 +11,7 @@
#define CHAR_MIN SCHAR_MIN #define CHAR_MIN SCHAR_MIN
#define CHAR_MAX SCHAR_MAX #define CHAR_MAX SCHAR_MAX
#define INT_MIN -32767 #define INT_MIN (-32767-1)
#define INT_MAX 32767 #define INT_MAX 32767
#define UINT_MAX 65535 #define UINT_MAX 65535

View File

@ -110,12 +110,12 @@ float atan2(float p, float q)
return s; return s;
} }
#define F_EXP_0 1.0000003 #define F_EXP_0 1.0
#define F_EXP_1 0.693147059 #define F_EXP_1 0.69315668
#define F_EXP_2 0.240173099 #define F_EXP_2 0.240132068
#define F_EXP_3 0.055816392 #define F_EXP_3 0.055876024
#define F_EXP_4 0.008965036 #define F_EXP_4 0.008940801
#define F_EXP_5 0.001898429 #define F_EXP_5 0.001894414
float exp(float f) float exp(float f)
{ {
@ -143,12 +143,12 @@ float exp(float f)
return s * x.f; return s * x.f;
} }
#define F_LOG_0 -3.78712618 #define F_LOG_0 -3.78717706
#define F_LOG_1 10.0957081 #define F_LOG_1 10.0960498
#define F_LOG_2 -13.9747486 #define F_LOG_2 -13.975654
#define F_LOG_3 12.7568806 #define F_LOG_3 12.7580616
#define F_LOG_4 -6.48114552 #define F_LOG_4 -6.48190725
#define F_LOG_5 1.39045416 #define F_LOG_5 1.39064767
float log(float f) float log(float f)
{ {

View File

@ -30,6 +30,18 @@ bool isfinite(float f);
#pragma intrinsic(floor) #pragma intrinsic(floor)
#pragma intrinsic(ceil) #pragma intrinsic(ceil)
#pragma intrinsic(sin)
#pragma intrinsic(cos)
#pragma intrinsic(tan)
#pragma intrinsic(atan)
#pragma intrinsic(atan2)
#pragma intrinsic(log)
#pragma intrinsic(exp)
#pragma intrinsic(pow)
#pragma intrinsic(sqrt)
#pragma compile("math.c") #pragma compile("math.c")

11
include/new Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include "stddef.h"
namespace std
{
void * operator new(size_t size);
void * operator new(void * ptr, size_t size);
}

84
include/opp/algorithm.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef OPP_ALGORITHM_H
#define OPP_ALGORITHM_H
#include "utility.h"
namespace opp {
template<class T, class LT>
void sort(T s, T e)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (LT(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort<T, LT>(s, p);
p++;
s = p;
}
}
template<class T, class LF>
void sort(T s, T e, LF lt)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (lt(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort(s, p, lt);
p++;
s = p;
}
}
template<class II, class OI>
OI copy(II first, II last, OI result)
{
while (first != last)
{
*result = *first;
++result; ++first;
}
return result;
}
template<class II, class T>
II find (II first, II last, const T& val)
{
while (first != last)
{
if (*first == val) return first;
++first;
}
return last;
}
}
#endif

120
include/opp/array.h Normal file
View File

@ -0,0 +1,120 @@
#ifndef OPP_ARRAY_H
#define OPP_ARRAY_H
namespace opp {
template <class T, int n>
class array
{
protected:
T _data[n];
public:
typedef T element_type;
int size(void) const
{
return n;
}
int max_size(void) const
{
return n;
}
bool empty(void) const
{
return n == 0;
}
const T & at(int at) const
{
return _data[at];
}
T & at(int at)
{
return _data[at];
}
T & operator[] (int at)
{
return _data[at];
}
const T & operator[] (int at) const
{
return _data[at];
}
T * begin(void)
{
return _data;
}
const T * begin(void) const
{
return _data;
}
const T * cbegin(void) const
{
return _data;
}
T * end(void)
{
return _data + n;
}
const T * end(void) const
{
return _data + n;
}
const T * cend(void) const
{
return _data + n;
}
T & back(void)
{
return _data[n - 1];
}
const T & back(void) const
{
return _data[n - 1];
}
T & front(void)
{
return _data[0];
}
const T & front(void) const
{
return _data[0];
}
T * data(void)
{
return _data;
}
const T * data(void) const
{
return _data;
}
void fill(const T & t)
{
for(int i=0; i<n; i++)
_data[i] = t;
}
};
}
#endif

207
include/opp/bidxlist.h Normal file
View File

@ -0,0 +1,207 @@
#ifndef OPP_BIDXLIST_H
#ifndef OPP_BIDXLIST_H
template <class T, int n>
class bindexlist
{
public:
char _free;
char _pred[n], _succ[n];
T _data[n];
class iterator
{
public:
bindexlist * _l;
char _i;
iterator(void) : _l(nullptr) {}
iterator(bindexlist * l, char i)
: _l(l), _i(i) {}
iterator(const iterator & li) : _l(li._l), _i(li._i) {}
iterator & operator=(const iterator & li)
{
_l = li._l;
_i = li._i;
return *this;
}
T & operator*()
{
return _l->_data[_i];
}
T * operator->()
{
return _l->_data + _i;
}
iterator & operator++(void)
{
_i = _l->_succ[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_succ[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator+=(char n)
{
while (n--)
_i = _l->_succ[_i];
return *this;
}
iterator & operator--(void)
{
_i = _l->_pred[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_pred[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator-=(char n)
{
while (n--)
_i = _l->_pred[_i];
return *this;
}
bool operator==(const iterator & li)
{
return _i == li._i;
}
bool operator!=(const iterator & li)
{
return _i != li._i;
}
};
public:
typedef T element_type;
typedef iterator iterator_type;
bindexlist(void)
{
_succ[0] = 0;
_pred[0] = 0;
for(char i=1; i<n; i++)
_succ[i] = i + 1;
_free = 1;
}
~bindexlist(void)
{
}
iterator begin(void)
{
return iterator(this, _succ[0]);
}
iterator end(void)
{
return iterator(this, 0);
}
T & front(void)
{
return _data[_succ[0]];
}
const T & front(void) const
{
return _data[_succ[0]];
}
T & back(void)
{
return _data[_pred[0]];
}
const T & back(void) const
{
return _data[_pred[0]];
}
iterator erase(iterator it)
{
char s = _succ[it._i];
_succ[_pred[it._i]] = _pred[it._i];
_pred[_succ[it._i]] = s;
_succ[it._i] = _free;
_free = it._i;
return iterator(this, s);
}
iterator erase(iterator first, iterator last)
{
char s = _succ[last._i];
_succ[_pred[last._i]] = _pred[first._i];
_pred[_succ[first._i]] = s;
_succ[last._i] = _free;
_free = first._i;
return iterator(this, s);
}
void pop_front(void)
{
char i = _succ[0];
char s = _succ[i];
_pred[s] = 0;
_succ[0] = s;
_succ[i] = _free;
_free = i;
}
void pop_back(void)
{
char i = _pred[0];
char p = _pred[i];
_succ[p] = 0;
_pred[0] = p;
_pred[i] = _free;
_free = i;
}
void push_back(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_pred[i] = _pred[0];
_succ[_pred[0]] = i;
_pred[0] = i;
}
void push_front(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_succ[i] = _succ[0];
_pred[_succ[0]] = i;
_succ[0] = i;
}
};
#endif

59
include/opp/boundint.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef OPP_BOUNDINT_H
#define OPP_BOUNDINT_H
namespace opp {
template<int tmin, int tmax>
constexpr auto boundinttype(void)
{
if constexpr (tmin >= 0 && tmax <= 255)
return (char)0;
else if constexpr (tmin >= -128 && tmax <= 127)
return (signed char)0;
else
return (int)0;
}
template<int tmin, int tmax>
class boundint
{
protected:
decltype(boundinttype<tmin, tmax>()) v;
public:
boundint(int i)
: v(i)
{
}
void operator=(int k)
{
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator+=(int k)
{
k += v;
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator-=(int k)
{
k = v - k;
__assume(k >= tmin && k <= tmax);
v = k;
}
operator int() const
{
int k = v;
__assume(k >= tmin && k <= tmax);
return k;
}
};
}
#endif

93
include/opp/functional.h Normal file
View File

@ -0,0 +1,93 @@
#ifndef OPP_FUNCTIONAL_H
#define OPP_FUNCTIONAL_H
namespace opp
{
template <class F>
class function;
template <class R, class ... P>
class function<R(P...)>
{
private:
struct callif
{
virtual R call(P...) = 0;
virtual ~callif() {}
virtual callif * clone(void) const = 0;
};
template<class CA>
struct callable : callif
{
CA ca;
callable(CA ca_) : ca(ca_) {}
R call(P... p) {return ca(p...);}
callif * clone(void) const
{
return new callable(ca);
}
};
callif * c;
public:
template <class F>
function(F f)
{
c = new callable<F>(f);
}
function(const function & f)
{
c = f.c->clone();
}
function(function && f)
{
c = f.c;
f.c = nullptr;
}
function(void)
{
c = nullptr;
}
function & operator=(const function & f)
{
if (c != f.c)
{
delete c;
c = f.c;
}
return *this;
}
function & operator=(function && f)
{
if (c != f.c)
{
c = f.c;
f.c = nullptr;
}
return *this;
}
~function(void)
{
delete c;
}
R operator()(P ... p) const
{
return c->call(p...);
}
};
}
#endif

View File

@ -1,10 +1,12 @@
#include "ifstream.h" #include "ifstream.h"
#include <c64/kernalio.h> #include <c64/kernalio.h>
namespace opp {
ifstream::ifstream(char fnum, char device, char channel, const string & name) ifstream::ifstream(char fnum, char device, char channel, const string & name)
{ {
this->fnum = fnum; this->fnum = fnum;
krnio_setnam(name); krnio_setnam(name.tocstr());
krnio_open(fnum, device, channel); krnio_open(fnum, device, channel);
} }
@ -19,3 +21,4 @@ void ifstream::refill(void)
mBufferFill = krnio_read(fnum, mBuffer, 32); mBufferFill = krnio_read(fnum, mBuffer, 32);
} }
}

View File

@ -4,6 +4,7 @@
#include "iostream.h" #include "iostream.h"
#include "string.h" #include "string.h"
namespace opp {
class ifstream : public istream class ifstream : public istream
{ {
@ -17,7 +18,7 @@ protected:
char fnum; char fnum;
}; };
}
#pragma compile("ifstream.cpp") #pragma compile("ifstream.cpp")

View File

@ -2,6 +2,8 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
namespace opp {
ios::ios(void) ios::ios(void)
: mFlags(0), mState(0), mWidth(0), mPrecision(6), mFill(' ') : mFlags(0), mState(0), mWidth(0), mPrecision(6), mFill(' ')
{} {}
@ -11,7 +13,7 @@ inline ios::~ios(void)
} }
char ios::fill(void) char ios::fill(void) const
{ {
return mFill; return mFill;
} }
@ -251,10 +253,11 @@ void ostream::numput(unsigned n, char sign)
if (mFlags & uppercase) if (mFlags & uppercase)
o = 'A' - 10; o = 'A' - 10;
while (n) unsigned nt = n;
while (nt)
{ {
char d = n % base; char d = nt % base;
n /= base; nt /= base;
if (d < 10) if (d < 10)
d += '0'; d += '0';
@ -287,10 +290,11 @@ void ostream::numput(unsigned long n, char sign)
if (mFlags & uppercase) if (mFlags & uppercase)
o = 'A' - 10; o = 'A' - 10;
while (n) unsigned long nt = n;
while (nt)
{ {
char d = n % base; char d = nt % base;
n /= base; nt /= base;
if (d < 10) if (d < 10)
d += '0'; d += '0';
@ -318,6 +322,12 @@ ostream & ostream::operator<<(bool val)
return *this; return *this;
} }
ostream & ostream::operator<<(char val)
{
bput(val);
return *this;
}
ostream & ostream::operator<<(int val) ostream & ostream::operator<<(int val)
{ {
if (val < 0) if (val < 0)
@ -942,6 +952,13 @@ istream & istream::operator>>(float & val)
return *this; return *this;
} }
istream & istream::operator>>(char & val)
{
doskipws();
val = get();
return *this;
}
istream & istream::operator>>(char * p) istream & istream::operator>>(char * p)
{ {
doskipws(); doskipws();
@ -955,21 +972,39 @@ istream & istream::operator>>(char * p)
return *this; return *this;
} }
istream & istream::operator>>(string & s)
{
doskipws();
s.clear();
char c = get();
while (c > ' ')
{
s += c;
c = get();
}
return *this;
}
cistream::cistream(void) cistream::cistream(void)
{} {}
void cistream::refill(void) void cistream::refill(void)
{ {
mBufferFill = 0;
mBufferPos = 0; mBufferPos = 0;
char ch; char fill = 0;
while (mBufferFill < 32) while (fill < 32)
{ {
char ch = getchar(); char ch = getchar();
mBuffer[mBufferFill++] = ch; mBuffer[fill++] = ch;
if (ch == '\n') if (ch == '\n')
break; break;
} }
mBufferFill = fill;
} }
cistream cin;
costream cout;
}

View File

@ -3,11 +3,13 @@
#include <opp/string.h> #include <opp/string.h>
namespace opp {
class ios class ios
{ {
public: public:
ios(void); constexpr ios(void);
virtual ~ios(void); virtual ~ios(void);
char fill() const; char fill() const;
@ -35,7 +37,7 @@ public:
showpos = 0x0800, showpos = 0x0800,
skipws = 0x1000, skipws = 0x1000,
unitbuf = 0x2000, unitbuf = 0x2000,
uppercase = 0x3000, uppercase = 0x4000,
adjustfield = 0x00b0, adjustfield = 0x00b0,
basefield = 0x004a, basefield = 0x004a,
@ -83,12 +85,13 @@ typedef ostream & (* manip)(ostream &);
class ostream : public ios class ostream : public ios
{ {
public: public:
ostream(void); constexpr ostream(void);
ostream & put(char c); ostream & put(char c);
ostream & write(const char * s, int n); ostream & write(const char * s, int n);
ostream & operator<<(bool val); ostream & operator<<(bool val);
ostream & operator<<(char val);
ostream & operator<<(int val); ostream & operator<<(int val);
ostream & operator<<(unsigned val); ostream & operator<<(unsigned val);
ostream & operator<<(long val); ostream & operator<<(long val);
@ -121,6 +124,7 @@ public:
istream & putback(char c); istream & putback(char c);
istream & unget(void); istream & unget(void);
istream & operator>>(char & val);
istream & operator>>(bool & val); istream & operator>>(bool & val);
istream & operator>>(int & val); istream & operator>>(int & val);
istream & operator>>(unsigned & val); istream & operator>>(unsigned & val);
@ -129,6 +133,7 @@ public:
istream & operator>>(float & val); istream & operator>>(float & val);
istream & operator>>(char * p); istream & operator>>(char * p);
istream & operator>>(string & s);
istream(void); istream(void);
protected: protected:
@ -147,7 +152,7 @@ protected:
class costream : public ostream class costream : public ostream
{ {
public: public:
costream(void); constexpr costream(void);
protected: protected:
void bput(char ch); void bput(char ch);
@ -202,6 +207,10 @@ iosetfill setfill(char fill);
ostream & operator<<(ostream & os, const iosetfill & s); ostream & operator<<(ostream & os, const iosetfill & s);
extern cistream cin;
extern costream cout;
}
#pragma compile("iostream.cpp"); #pragma compile("iostream.cpp");

137
include/opp/iterator.h Normal file
View File

@ -0,0 +1,137 @@
#ifndef OPP_ITERATOR_H
#define OPP_ITERATOR_H
namespace opp
{
template <class CT>
class back_insert_iterator
{
protected:
CT * co;
public:
back_insert_iterator (CT & c) : co(&c) {}
back_insert_iterator & operator= (const CT::element_type & t)
{
co->push_back(t);
return *this;
}
back_insert_iterator & operator= (CT::element_type && t)
{
co->push_back(t);
return *this;
}
back_insert_iterator & operator* (void)
{
return *this;
}
back_insert_iterator & operator++ (void)
{
return *this;
}
back_insert_iterator operator++ (int)
{
return *this;
}
};
template <class CT>
class front_insert_iterator
{
protected:
CT * co;
public:
front_insert_iterator (CT & c) : co(&c) {}
front_insert_iterator & operator= (const CT::element_type & t)
{
co->push_front(t);
return *this;
}
front_insert_iterator & operator= (CT::element_type && t)
{
co->push_front(t);
return *this;
}
front_insert_iterator & operator* (void)
{
return *this;
}
front_insert_iterator & operator++ (void)
{
return *this;
}
front_insert_iterator operator++ (int)
{
return *this;
}
};
template <class CT>
class insert_iterator
{
protected:
CT * co;
CT::iterator_type ci;
public:
insert_iterator (CT & c, const CT::iterator_type & i) : co(&c), ci(i) {}
insert_iterator & operator= (const CT::element_type & t)
{
ci = co->insert(ci, t); ++ci;
return *this;
}
insert_iterator & operator= (CT::element_type && t)
{
ci = co->insert(ci, t); ++ci;
return *this;
}
insert_iterator & operator* (void)
{
return *this;
}
insert_iterator & operator++ (void)
{
return *this;
}
insert_iterator operator++ (int)
{
return *this;
}
};
template <class CT>
front_insert_iterator<CT> front_inserter (CT & c)
{
return front_insert_iterator<CT>(c);
}
template <class CT>
back_insert_iterator<CT> back_inserter (CT & c)
{
return back_insert_iterator<CT>(c);
}
template <class CT>
insert_iterator<CT> inserter (CT & c, const CT::iterator_type & i)
{
return insert_iterator<CT>(c, i);
}
}

370
include/opp/list.h Normal file
View File

@ -0,0 +1,370 @@
#ifndef OPP_LIST
#define OPP_LIST
namespace opp
{
template <class T>
class listhead
{
public:
listnode<T> * succ, * pred;
listhead()
{
succ = (listnode<T> *)this;
pred = (listnode<T> *)this;
}
};
template <class T>
class listnode : public listhead<T>
{
public:
T data;
listnode(const T & t) : data(t) {}
listnode(T && t) : data(t) {}
};
template <class T>
class list_iterator
{
public:
listnode<T> * node;
public:
list_iterator(void) : node(nullptr) {}
list_iterator(listnode<T> * n) : node(n) {}
list_iterator(const list_iterator & li) : node(li.node) {}
list_iterator & operator=(const list_iterator & li)
{
node = li.node;
return *this;
}
T & operator*()
{
return node->data;
}
T * operator->()
{
return &(node->data);
}
list_iterator & operator++(void)
{
node = node->succ;
return *this;
}
list_iterator operator++(int)
{
listnode<T> * n = node;
node = node->succ;
return list_iterator(n);
}
list_iterator & operator+=(int n)
{
while (n--)
node = node->succ;
return *this;
}
list_iterator & operator--(void)
{
node = node->pred;
return *this;
}
list_iterator operator++(int)
{
listnode<T> * n = node;
node = node->pred;
return list_iterator(n);
}
list_iterator & operator-=(int n)
{
while (n--)
node = node->pred;
return *this;
}
bool operator==(const list_iterator & li)
{
return node == li.node;
}
bool operator!=(const list_iterator & li)
{
return node != li.node;
}
};
template <class T>
class list
{
private:
typedef listnode<T> ln;
listhead<T> head;
public:
typedef T element_type;
typedef list_iterator<T> iterator_type;
list(void)
{}
list(const list & l);
list(list && l)
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
}
list & operator=(const list & l);
list & operator=(list && l)
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
return *this;
}
~list(void)
{
listnode<T> * n = head.succ;
while (n != &head)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
}
list_iterator<T> begin(void)
{
return list_iterator<T>(head.succ);
}
list_iterator<T> end(void)
{
return list_iterator<T>((listnode<T> *)&head);
}
T & front(void)
{
return head.succ->data;
}
const T & front(void) const
{
return head.succ->data;
}
T & back(void)
{
return head.pred->data;
}
const T & back(void) const
{
return head.pred->data;
}
list_iterator<T> erase(list_iterator<T> it);
list_iterator<T> erase(list_iterator<T> first, list_iterator<T> last);
void pop_front(void);
void pop_back(void);
void push_front(const T & t);
void push_front(T && t);
void push_back(const T & t);
void push_back(T && t);
void clear(void);
void append(const list & l);
list_iterator<T> insert(list_iterator<T> it, const T & t);
list_iterator<T> insert(list_iterator<T> it, T && t);
};
template <class T>
list<T>::list(const list<T> & l)
{
append(l);
}
template <class T>
list<T> & list<T>::operator=(const list<T> & l)
{
if (&l != this)
{
clear();
append(l);
}
return *this;
}
template <class T>
void list<T>::pop_front(void)
{
listnode<T> * n = head.succ;
head.succ = n->succ;
n->succ->pred = (listnode<T> *)&head;
delete n;
}
template <class T>
void list<T>::pop_back(void)
{
listnode<T> * n = head.pred;
head.pred = n->pred;
n->pred->succ = (listnode<T> *)&head;
delete n;
}
template <class T>
void list<T>::push_front(const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->pred = (listnode<T> *)&head;
n->succ = head.succ;
head.succ->pred = n;
head.succ = n;
}
template <class T>
void list<T>::push_front(T && t)
{
listnode<T> * n = new listnode<T>(t);
n->pred = (listnode<T> *)&head;
n->succ = head.succ;
head.succ->pred = n;
head.succ = n;
}
template <class T>
void list<T>::push_back(const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = (listnode<T> *)&head;
n->pred = head.pred;
head.pred->succ = n;
head.pred = n;
}
template <class T>
void list<T>::push_back(T && t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = (listnode<T> *)&head;
n->pred = head.pred;
head.pred->succ = n;
head.pred = n;
}
template <class T>
list_iterator<T> list<T>::erase(list_iterator<T> it)
{
listnode<T> * n = it.node;
listnode<T> * s = n->succ;
n->succ->pred = n->pred;
n->pred->succ = n->succ;
delete n;
return list_iterator<T>(s);
}
template <class T>
list_iterator<T> list<T>::erase(list_iterator<T> first, list_iterator<T> last)
{
listnode<T> * n = first.node;
listnode<T> * s = last.node;
n->pred->succ = s;
s->pred = n->pred;
while (n != s)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
return list_iterator<T>(s);
}
template <class T>
list_iterator<T> list<T>::insert(list_iterator<T> it, const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = it.node;
n->pred = it.node->pred;
it.node->pred->succ = n;
it.node->pred = n;
return list_iterator<T>(n);
}
template <class T>
list_iterator<T> list<T>::insert(list_iterator<T> it, T && t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = it.node;
n->pred = it.node->pred;
it.node->pred->succ = n;
it.node->pred = n;
return list_iterator<T>(n);
}
template <class T>
void list<T>::clear(void)
{
listnode<T> * n = head.succ;
while (n != &head)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
head.succ = (listnode<T> *)&head;
head.pred = (listnode<T> *)&head;
}
template <class T>
void list<T>::append(const list<T> & l)
{
listnode<T> * n = l.head.succ;
while (n != &(l.head))
{
push_back(n->data);
n = n->succ;
}
}
}
#endif

View File

@ -1,6 +1,8 @@
#include "ofstream.h" #include "ofstream.h"
#include <c64/kernalio.h> #include <c64/kernalio.h>
namespace opp {
ofstream::ofstream(char fnum, char device, char channel, const string & name) ofstream::ofstream(char fnum, char device, char channel, const string & name)
{ {
this->fnum = fnum; this->fnum = fnum;
@ -27,3 +29,4 @@ void ofstream::bput(char ch)
} }
} }
}

View File

@ -4,6 +4,7 @@
#include "iostream.h" #include "iostream.h"
#include "string.h" #include "string.h"
namespace opp {
class ofstream : public ostream class ofstream : public ostream
{ {
@ -20,7 +21,7 @@ protected:
char fnum; char fnum;
}; };
}
#pragma compile("ofstream.cpp") #pragma compile("ofstream.cpp")

80
include/opp/slab.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef OPP_SLAB_H
#define OPP_SLAB_H
template<class T, int N>
class slabptr
{
public:
char index;
slabptr(void)
: index(N)
{}
slabptr(char i)
: index(i)
{}
slabptr(const slabptr & i)
: index(i.index)
{}
auto operator-> ();
auto & operator* ();
};
template <class T, int N>
class slab
{
protected:
static __striped T buffer[N];
static char head;
static char next[N];
public:
typedef slabptr<T, N> ptr;
static void init(void);
static auto alloc(void);
static void free(ptr p);
};
template<class T, int N>
inline auto slabptr<T, N>::operator-> ()
{
return slab<T, N>::buffer + index;
}
template<class T, int N>
inline auto & slabptr<T, N>::operator* ()
{
return slab<T, N>::buffer[index];
}
template <class T, int N>
void slab<T, N>::init(void)
{
head = 0;
for(char i=0; i<N; i++)
next[i] = i + 1;
}
template <class T, int N>
auto slab<T, N>::alloc(void)
{
char i = head;
head = next[head];
return slabptr<T, N>(i);
}
template <class T, int N>
void slab<T, N>::free(slabptr<T, N> p)
{
next[p.index] = head;
head = p.index;
}
#endif

View File

@ -1,6 +1,8 @@
#include "sstream.h" #include "sstream.h"
#include <stdlib.h> #include <stdlib.h>
namespace opp {
ostringstream::ostringstream(void) ostringstream::ostringstream(void)
{ {
mBuffer = nullptr; mBuffer = nullptr;
@ -18,12 +20,12 @@ void ostringstream::bput(char ch)
{ {
mBSize = 15; mBSize = 15;
mBFill = 0; mBFill = 0;
mBuffer = malloc(15); mBuffer = (char *)malloc(15);
} }
else if (mBFill == mBSize) else if (mBFill == mBSize)
{ {
mBSize *= 2; mBSize *= 2;
char * b = malloc(mBSize); char * b = (char *)malloc(mBSize);
for(char i=0; i<mBFill; i++) for(char i=0; i<mBFill; i++)
b[i] = mBuffer[i]; b[i] = mBuffer[i];
free(mBuffer); free(mBuffer);
@ -44,7 +46,7 @@ void ostringstream::str(const string & str)
{ {
free(mBuffer); free(mBuffer);
mBSize = mBFill; mBSize = mBFill;
mBuffer = malloc(mBSize); mBuffer = (char *)malloc(mBSize);
} }
str.copyseg(mBuffer, 0, mBFill); str.copyseg(mBuffer, 0, mBFill);
} }
@ -80,3 +82,5 @@ void istringstream::refill(void)
mBuffer[mBufferFill++] = mString[mSPos++]; mBuffer[mBufferFill++] = mString[mSPos++];
} }
} }
}

View File

@ -3,6 +3,8 @@
#include "iostream.h" #include "iostream.h"
namespace opp {
class ostringstream : public ostream class ostringstream : public ostream
{ {
public: public:
@ -33,6 +35,7 @@ protected:
char mSPos; char mSPos;
}; };
}
#pragma compile("sstream.cpp") #pragma compile("sstream.cpp")

308
include/opp/static_vector.h Normal file
View File

@ -0,0 +1,308 @@
#ifndef OPP_STATIC_VECTOR_H
#define OPP_STATIC_VECTOR_H
#include <new>
#include <stdlib.h>
#include <opp/utility.h>
#include <oscar.h>
namespace opp {
template <class T, int N>
class static_vector
{
protected:
enum { m = N } _size;
char _space[N * sizeof(T)];
public:
typedef T element_type;
static_vector(void) : _size(0) {}
static_vector(size_t n) : _size(n)
{
#ifdef CAPACITYCHECK
if (n > N) debugcrash();
#endif
T * data = (T*)_space;
for(size_t i=0; i<n; i++)
new (data + i) T();
}
static_vector(const static_vector & v)
: _size(v._size)
{
size_t n = _size;
T * data = (T*)_space, * vdata = (T*)(v._space);
for(size_t i=0; i<n; i++)
new (data + i)T(vdata[i]);
}
~static_vector(void)
{
T * data = (T*)_space;
size_t n = _size;
for(size_t i=0; i<n; i++)
data[i].~T();
}
static_vector & operator=(const static_vector & v)
{
if (this != &v)
{
T * data = (T*)_space, * vdata = (T*)(v._space);
size_t n = _size;
for(size_t i=0; i<n; i++)
data[i].~T();
_size = v._size;
n = _size;
for(size_t i=0; i<n; i++)
new (data + i)T(vdata[i]);
}
return *this;
}
size_t size(void) const
{
return _size;
}
size_t max_size(void) const
{
return N;
}
bool empty(void) const
{
return _size == 0;
}
bool full(void) const
{
return _size == N;
}
size_t capacity(void) const
{
return N;
}
void resize(size_t n);
void clear(void);
T & at(size_t at)
{
return ((T*)_space)[at];
}
const T & at(size_t at) const
{
return ((T*)_space)[at];
}
T & operator[](size_t at)
{
return ((T*)_space)[at];
}
const T & operator[](size_t at) const
{
return ((T*)_space)[at];
}
T * begin(void)
{
return (T*)_space;
}
const T * begin(void) const
{
return (T*)_space;
}
const T * cbegin(void) const
{
return (T*)_space;
}
T * end(void)
{
return (T*)_space + _size;
}
const T * end(void) const
{
return (T*)_space + _size;
}
const T * cend(void) const
{
return (T*)_space + _size;
}
T & front(void)
{
return ((T*)_space)[0];
}
const T & front(void) const
{
return ((T*)_space)[0];
}
T & back(void)
{
return ((T*)_space)[_size - 1];
}
const T & back(void) const
{
return ((T*)_space)[_size - 1];
}
T * data(void)
{
return (T*)_space;
}
const T * at(void) const
{
return (T*)_space;
}
void push_back(const T & t);
void push_back(T && t);
void pop_back(void)
{
_size--;
((T*)_space)[_size].~T();
}
void assign(size_t count, const T & t);
void insert(size_t at, const T & t);
void erase(size_t at, size_t n = 1);
T * insert(T * at, const T & t);
template <typename ...P>
void emplace_back(const P&... p);
};
template <class T, int N>
void static_vector<T, N>::clear(void)
{
T * data = (T*)_space;
for(size_t i=0; i<_size; i++)
data[i].~T();
_size = 0;
}
template <class T, int N>
void static_vector<T, N>::resize(size_t n)
{
#ifdef CAPACITYCHECK
if (n > N) debugcrash();
#endif
T * data = (T*)_space;
if (n < _size)
{
for(size_t i=n; i<_size; i++)
data[i].~T();
}
else if (n > 0)
{
for(size_t i=_size; i<n; i++)
new(data + i)T();
}
_size = n;
}
template <class T, int N>
void static_vector<T, N>::push_back(const T & t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(t);
}
template <class T, int N>
void static_vector<T, N>::push_back(T && t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(t);
}
template <class T, int N>
template <typename ...P>
void static_vector<T, N>::emplace_back(const P&... p)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(p...);
}
template <class T, int N>
void static_vector<T, N>::assign(size_t count, const T & t)
{
T * data = (T*)_space;
for(size_t i=0; i<_size; i++)
data[i].~T();
for(size_t i=0; i<count; i++)
new (data + i)T(t);
_size = count;
}
template <class T, int N>
void static_vector<T, N>::insert(size_t at, const T & t)
{
T * data = (T*)_space;
new (data + _size)T();
for(size_t i=_size; i>at; i--)
data[i] = move(data[i - 1]);
data[at] = t;
_size++;
}
template <class T, int N>
void static_vector<T, N>::erase(size_t at, size_t n)
{
T * data = (T*)_space;
_size -= n;
for(size_t i=at; i<_size; i++)
data[i] = move(data[i + n]);
for(size_t i=0; i<n; i++)
data[_size + i].~T();
}
template <class T, int N>
T * static_vector<T, N>::insert(T * at, const T & t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
T * data = (T*)_space;
T * dp = data + _size;
new (dp)T();
while (dp != at)
{
dp--;
dp[1] = move(dp[0]);
}
dp[0] = t;
_size++;
return dp + 1;
}
}
#endif

View File

@ -1,6 +1,9 @@
#include "string.h" #include "string.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
namespace opp {
static inline void smemcpy(char * dp, const char * sp, char s) static inline void smemcpy(char * dp, const char * sp, char s)
{ {
@ -16,6 +19,11 @@ static inline char sstrlen(const char * sp)
return n; return n;
} }
inline void swap(string & u, string & v)
{
char * p = u.cstr; u.cstr = v.cstr; v.cstr = p;
}
string::string(void) : cstr(nullptr) string::string(void) : cstr(nullptr)
{} {}
@ -24,21 +32,32 @@ string::string(const string & s)
if (s.cstr) if (s.cstr)
{ {
char l = s.cstr[0]; char l = s.cstr[0];
cstr = malloc(char(l + 2)); cstr = (char *)malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2); smemcpy(cstr, s.cstr, l + 2);
} }
else else
cstr = nullptr; cstr = nullptr;
} }
string::string(string && s)
: cstr(s.cstr)
{
s.cstr = nullptr;
}
string::string(const char * s) string::string(const char * s)
{ {
char l = sstrlen(s); if (s)
if (l)
{ {
cstr = malloc(char(l + 2)); char l = sstrlen(s);
cstr[0] = l; if (l)
smemcpy(cstr + 1, s, l + 1); {
cstr = (char *)malloc(char(l + 2));
cstr[0] = l;
smemcpy(cstr + 1, s, l + 1);
}
else
cstr = nullptr;
} }
else else
cstr = nullptr; cstr = nullptr;
@ -48,9 +67,10 @@ string::string(const char * s, char size)
{ {
if (size) if (size)
{ {
cstr = malloc(char(size + 2)); cstr = (char *)malloc(char(size + 2));
cstr[0] = size; cstr[0] = size;
smemcpy(cstr + 1, s, size + 1); smemcpy(cstr + 1, s, size);
cstr[size + 1] = 0;
} }
else else
cstr = nullptr; cstr = nullptr;
@ -58,7 +78,7 @@ string::string(const char * s, char size)
string::string(char c) string::string(char c)
{ {
cstr = malloc(3); cstr = (char *)malloc(3);
cstr[0] = 1; cstr[0] = 1;
cstr[1] = c; cstr[1] = c;
cstr[2] = 0; cstr[2] = 0;
@ -76,6 +96,12 @@ string::~string(void)
free(cstr); free(cstr);
} }
void string::clear(void)
{
free(cstr);
cstr = nullptr;
}
void string::copyseg(char * p, char at, char num) const void string::copyseg(char * p, char at, char num) const
{ {
smemcpy(p, cstr + 1 + at, num); smemcpy(p, cstr + 1 + at, num);
@ -89,7 +115,7 @@ string & string::operator=(const string & s)
if (s.cstr) if (s.cstr)
{ {
char l = s.cstr[0]; char l = s.cstr[0];
cstr = malloc(char(l + 2)); cstr = (char *)malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2); smemcpy(cstr, s.cstr, l + 2);
} }
else else
@ -99,15 +125,32 @@ string & string::operator=(const string & s)
return *this; return *this;
} }
string & string::operator=(string && s)
{
if (cstr != s.cstr)
{
free(cstr);
cstr = s.cstr;
s.cstr = nullptr;
}
return *this;
}
string & string::operator=(const char * s) string & string::operator=(const char * s)
{ {
free(cstr); free(cstr);
char l = sstrlen(s); if (s)
if (l)
{ {
cstr = malloc(char(l + 2)); char l = sstrlen(s);
cstr[0] = l; if (l)
smemcpy(cstr + 1, s, l + 1); {
cstr = (char *)malloc(char(l + 2));
cstr[0] = l;
smemcpy(cstr + 1, s, l + 1);
}
else
cstr = nullptr;
} }
else else
cstr = nullptr; cstr = nullptr;
@ -119,46 +162,46 @@ string & string::operator+=(const string & s)
{ {
if (s.cstr) if (s.cstr)
{ {
char d = 0;
if (cstr) if (cstr)
{ d = cstr[0];
char l = cstr[0] + s.cstr[0];
char * c = malloc(char(l + 2)); char l = s.cstr[0] + d;
c[0] = l; char * c = (char *)malloc(char(l + 2));
smemcpy(c + 1, cstr + 1, cstr[0]); c[0] = l;
smemcpy(c + 1 + cstr[0], s.cstr + 1, s.cstr[0] + 1);
free(cstr); if (d)
cstr = c; smemcpy(c + 1, cstr + 1, d);
} smemcpy(c + 1 + d, s.cstr + 1, s.cstr[0] + 1);
else free(cstr);
{ cstr = c;
char l = s.cstr[0];
cstr = malloc(char(l + 2));
smemcpy(cstr, s.cstr, l + 2);
}
} }
return *this; return *this;
} }
string & string::operator+=(const char * s) string & string::operator+=(const char * s)
{ {
char sl = sstrlen(s); if (s)
if (sl)
{ {
if (cstr) char sl = sstrlen(s);
if (sl)
{ {
char l = sl + cstr[0]; if (cstr)
char * c = malloc(char(l + 2)); {
c[0] = l; char l = sl + cstr[0];
smemcpy(c + 1, cstr + 1, cstr[0]); char * c = (char *)malloc(char(l + 2));
smemcpy(c + 1 + cstr[0], s, sl + 1); c[0] = l;
free(cstr); smemcpy(c + 1, cstr + 1, cstr[0]);
cstr = c; smemcpy(c + 1 + cstr[0], s, sl + 1);
} free(cstr);
else cstr = c;
{ }
cstr = malloc(char(sl + 2)); else
cstr[0] = sl; {
smemcpy(cstr + 1, s, sl + 1); cstr = (char *)malloc(char(sl + 2));
cstr[0] = sl;
smemcpy(cstr + 1, s, sl + 1);
}
} }
} }
return *this; return *this;
@ -169,23 +212,28 @@ string & string::operator+=(char c)
if (cstr) if (cstr)
{ {
char l = cstr[0] + 1; char l = cstr[0] + 1;
char * p = malloc(char(l + 2)); char * p = (char *)malloc(char(l + 2));
p[0] = l; p[0] = l;
smemcpy(p + 1, cstr + 1, cstr[0]); smemcpy(p + 1, cstr + 1, cstr[0]);
p[l] = c; p[l] = c;
p[l + 1] = 0; p[l + 1] = 0;
free(cstr); free(cstr);
cstr = c; cstr = p;
} }
else else
{ {
cstr = malloc(3); cstr = (char *)malloc(3);
cstr[0] = 1; cstr[0] = 1;
cstr[1] = c; cstr[1] = c;
cstr[2] = 0; cstr[2] = 0;
} }
return *this;
} }
inline const char * string::c_str(void) const
{
return this->tocstr();
}
inline const char * string::tocstr(void) const inline const char * string::tocstr(void) const
{ {
@ -210,7 +258,7 @@ string string::operator+(const string & s) const
if (s.cstr) if (s.cstr)
{ {
char l = cstr[0] + s.cstr[0]; char l = cstr[0] + s.cstr[0];
char * p = malloc(char(l + 2)); char * p = (char *)malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]); smemcpy(p + 1, cstr + 1, cstr[0]);
smemcpy(p + 1 + cstr[0], s.cstr + 1, s.cstr[0]); smemcpy(p + 1 + cstr[0], s.cstr + 1, s.cstr[0]);
return string(l, p); return string(l, p);
@ -226,14 +274,19 @@ string string::operator+(const char * s) const
{ {
if (cstr) if (cstr)
{ {
char sl = sstrlen(s); if (s)
if (sl)
{ {
char l = cstr[0] + sl; char sl = sstrlen(s);
char * p = malloc(char(l + 2)); if (sl)
smemcpy(p + 1, cstr + 1, cstr[0]); {
smemcpy(p + 1 + cstr[0], s, sl); char l = cstr[0] + sl;
return string(l, p); char * p = (char *)malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]);
smemcpy(p + 1 + cstr[0], s, sl);
return string(l, p);
}
else
return *this;
} }
else else
return *this; return *this;
@ -247,7 +300,7 @@ string string::operator+(char c) const
if (cstr) if (cstr)
{ {
char l = cstr[0] + 1; char l = cstr[0] + 1;
char * p = malloc(char(l + 2)); char * p = (char *)malloc(char(l + 2));
smemcpy(p + 1, cstr + 1, cstr[0]); smemcpy(p + 1, cstr + 1, cstr[0]);
p[l] = c; p[l] = c;
return string(l, p); return string(l, p);
@ -434,17 +487,48 @@ inline char string::operator[](char t) const
return cstr[t + 1]; return cstr[t + 1];
} }
char * string::begin(void)
{
return cstr ? cstr + 1 : nullptr;
}
const char * string::begin(void) const
{
return cstr ? cstr + 1 : nullptr;
}
const char * string::cbegin(void) const
{
return cstr ? cstr + 1 : nullptr;
}
char * string::end(void)
{
return cstr ? cstr + 1 + cstr[0] : nullptr;
}
const char * string::end(void) const
{
return cstr ? cstr + 1 + cstr[0] : nullptr;
}
const char * string::cend(void) const
{
return cstr ? cstr + 1 + cstr[0] : nullptr;
}
string string::substr(char pos, char len) const string string::substr(char pos, char len) const
{ {
if (!cstr || len == 0 || pos >= cstr[0]) if (!cstr || len == 0 || pos >= cstr[0])
return string; return string();
else else
{ {
char l = cstr[0]; char l = cstr[0];
if (pos + len > l) if (pos + len > l)
len = l - pos; len = l - pos;
char * p = malloc(len + 2); char * p = (char *)malloc(len + 2);
memcpy(p + 1, cstr + 1 + pos, len); memcpy(p + 1, cstr + 1 + pos, len);
return string(len, p); return string(len, p);
} }
@ -532,3 +616,522 @@ int string::find(char c, char pos) const
return -1; return -1;
} }
string to_string(int val)
{
char buffer[10];
bool sign = false;
if (val < 0)
{
val = -val;
sign = true;
}
char i = 10;
while (val)
{
char d = val % 10;
val /= 10;
buffer[--i] = d + '0';
}
if (i == 10)
buffer[--i] = '0';
if (sign)
buffer[--i] = '-';
return string(buffer + i, 10 - i);
}
string to_string(long val)
{
char buffer[12];
bool sign = false;
if (val < 0)
{
val = -val;
sign = true;
}
char i = 12;
while (val)
{
char d = val % 10;
val /= 10;
buffer[--i] = d + '0';
}
if (i == 12)
buffer[--i] = '0';
if (sign)
buffer[--i] = '-';
return string(buffer + i, 12 - i);
}
string to_string(unsigned int val)
{
char buffer[10];
char i = 10;
while (val)
{
char d = val % 10;
val /= 10;
buffer[--i] = d + '0';
}
if (i == 10)
buffer[--i] = '0';
return string(buffer + i, 10 - i);
}
string to_string(unsigned long val)
{
char buffer[12];
char i = 12;
while (val)
{
char d = val % 10;
val /= 10;
buffer[--i] = d + '0';
}
if (i == 12)
buffer[--i] = '0';
return string(buffer + i, 12 - i);
}
static float fround5[] = {
0.5e-0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6
};
string to_string(float val)
{
char buffer[20];
char d = 0;
float f = val;
if (f < 0.0)
{
f = -f;
buffer[d++] = '-';
}
char prefix = d;
if (isinf(f))
{
buffer[d++] = 'I';
buffer[d++] = 'N';
buffer[d++] = 'F';
}
else
{
int exp = 0;
char fdigits = 6;
if (f != 0.0)
{
while (f >= 1000.0)
{
f /= 1000;
exp += 3;
}
while (f < 1.0)
{
f *= 1000;
exp -= 3;
}
while (f >= 10.0)
{
f /= 10;
exp ++;
}
}
char digits = fdigits + 1;
while (exp < 0)
{
f /= 10.0;
exp++;
}
digits = fdigits + exp + 1;
if (digits < 7)
f += fround5[digits - 1];
else
f += fround5[6];
if (f >= 10.0)
{
f /= 10.0;
fdigits--;
}
char pdigits = digits - fdigits;
if (digits > 20)
digits = 20;
if (pdigits == 0)
buffer[d++] = '0';
for(char i=0; i<digits; i++)
{
if (i == pdigits)
buffer[d++] = '.';
if (i > 6)
buffer[d++] = '0';
else
{
int c = (int)f;
f -= (float)c;
f *= 10.0;
buffer[d++] = c + '0';
}
}
}
return string(buffer, d);
}
int string::to_int(char * idx, char base) const
{
char i = 1;
unsigned n = 0;
bool sign = false;
if (cstr)
{
const char * cp = cstr;
char ch = cp[i];
if (ch == '-')
{
sign = true;
ch = cp[++i];
}
else if (ch == '+')
ch = cp[++i];
if (ch == '0' && base == 0)
{
ch = cp[++i];
if (ch == 'x' || ch == 'X')
{
base = 16;
ch = cp[++i];
}
else if (ch == 'b' || ch == 'B')
{
base = 2;
ch = cp[++i];
}
}
for(;;)
{
char d;
if (ch >= '0' && ch <= '9')
d = (ch - '0');
else if (base > 10 && ch >= 'A' && ch <= 'F')
d = (ch - 'A' + 10);
else if (base > 10 && ch >= 'a' && ch <= 'f')
d = (ch - 'a' + 10);
else
break;
n = n * base + d;
ch = cp[++i];
}
}
if (idx)
*idx = i - 1;
if (sign)
return -(int)n;
else
return n;
}
long string::to_long(char * idx, char base) const
{
char i = 1;
unsigned long n = 0;
bool sign = false;
if (cstr)
{
const char * cp = cstr;
char ch = cp[i++];
if (ch == '-')
{
sign = true;
ch = cp[i++];
}
else if (ch == '+')
ch = cp[i++];
if (ch == '0' && base == 0)
{
ch = cp[i++];
if (ch == 'x' || ch == 'X')
{
base = 16;
ch = cp[i++];
}
else if (ch == 'b' || ch == 'B')
{
base = 2;
ch = cp[i++];
}
}
for(;;)
{
char d;
if (ch >= '0' && ch <= '9')
d = (ch - '0');
else if (base > 10 && ch >= 'A' && ch <= 'F')
d = (ch - 'A' + 10);
else if (base > 10 && ch >= 'a' && ch <= 'f')
d = (ch - 'a' + 10);
else
break;
n = n * base + d;
ch = cp[i++];
}
i--;
}
if (idx)
*idx = i - 1;
if (sign)
return -(long)n;
else
return n;
}
unsigned string::to_uint(char * idx, char base) const
{
char i = 1;
unsigned n = 0;
if (cstr)
{
const char * cp = cstr;
char ch = cp[i];
if (ch == '0' && base == 0)
{
ch = cp[++i];
if (ch == 'x' || ch == 'X')
{
base = 16;
ch = cp[++i];
}
else if (ch == 'b' || ch == 'B')
{
base = 2;
ch = cp[++i];
}
}
for(;;)
{
char d;
if (ch >= '0' && ch <= '9')
d = (ch - '0');
else if (base > 10 && ch >= 'A' && ch <= 'F')
d = (ch - 'A' + 10);
else if (base > 10 && ch >= 'a' && ch <= 'f')
d = (ch - 'a' + 10);
else
break;
n = n * base + d;
ch = cp[++i];
}
}
if (idx)
*idx = i - 1;
return n;
}
unsigned long string::to_ulong(char * idx, char base) const
{
char i = 1;
unsigned long n = 0;
if (cstr)
{
const char * cp = cstr;
char ch = cp[i++];
if (ch == '0' && base == 0)
{
ch = cp[i++];
if (ch == 'x' || ch == 'X')
{
base = 16;
ch = cp[i++];
}
else if (ch == 'b' || ch == 'B')
{
base = 2;
ch = cp[i++];
}
}
for(;;)
{
char d;
if (ch >= '0' && ch <= '9')
d = (ch - '0');
else if (base > 10 && ch >= 'A' && ch <= 'F')
d = (ch - 'A' + 10);
else if (base > 10 && ch >= 'a' && ch <= 'f')
d = (ch - 'a' + 10);
else
break;
n = n * base + d;
ch = cp[i++];
}
i--;
}
if (idx)
*idx = i - 1;
return n;
}
float string::to_float(char * idx) const
{
char i = 1;
float vf = 0;
bool sign = false;
if (cstr)
{
const char * cp = cstr;
char ch = cp[i++];
if (ch == '-')
{
sign = true;
ch = cp[i++];
}
else if (ch == '+')
ch = cp[i++];
if (ch >= '0' && ch <= '9' || ch == '.')
{
while (ch >= '0' && ch <= '9')
{
vf = vf * 10 + (int)(ch - '0');
ch = cp[i++];
}
if (ch == '.')
{
float digits = 1.0;
ch = cp[i++];
while (ch >= '0' && ch <= '9')
{
vf = vf * 10 + (int)(ch - '0');
digits *= 10;
ch = cp[i++];
}
vf /= digits;
}
char e = 0;
bool eneg = false;
if (ch == 'e' || ch == 'E')
{
ch = cp[i++];
if (ch == '-')
{
eneg = true;
ch = cp[i++];
}
else if (ch == '+')
{
ch = cp[i++];
}
while (ch >= '0' && ch <= '9')
{
e = e * 10 + ch - '0';
ch = cp[i++];
}
}
if (e)
{
if (eneg)
{
while (e > 6)
{
vf /= 1000000.0;
e -= 6;
}
vf /= tpow10[e];
}
else
{
while (e > 6)
{
vf *= 1000000.0;
e -= 6;
}
vf *= tpow10[e];
}
}
}
i--;
}
if (idx)
*idx = i - 1;
if (sign)
return -vf;
else
return vf;
}
}

View File

@ -1,14 +1,19 @@
#ifndef OPP_STRING_H #ifndef OPP_STRING_H
#define OPP_STRING_H #define OPP_STRING_H
namespace opp {
class string class string
{ {
private: private:
char * cstr; char * cstr;
friend void swap(string & u, string & v);
public: public:
string(void); string(void);
string(const string & s); string(const string & s);
string(string && s);
string(const char * s); string(const char * s);
string(const char * s, char size); string(const char * s, char size);
string(char c); string(char c);
@ -16,7 +21,10 @@ public:
unsigned size(void) const; unsigned size(void) const;
void clear(void);
string & operator=(const string & s); string & operator=(const string & s);
string & operator=(string && s);
string & operator=(const char * s); string & operator=(const char * s);
string & operator+=(const string & s); string & operator+=(const string & s);
@ -51,6 +59,15 @@ public:
char & operator[](char t); char & operator[](char t);
char operator[](char t) const; char operator[](char t) const;
char * begin(void);
const char * begin(void) const;
const char * cbegin(void) const;
char * end(void);
const char * end(void) const;
const char * cend(void) const;
const char * c_str(void) const;
const char * tocstr(void) const; const char * tocstr(void) const;
string substr(char pos, char len) const; string substr(char pos, char len) const;
@ -64,10 +81,30 @@ public:
int find(char c, char pos) const; int find(char c, char pos) const;
void copyseg(char * p, char at, char num) const; void copyseg(char * p, char at, char num) const;
int to_int(char * idx = nullptr, char base = 10) const;
long to_long(char * idx = nullptr, char base = 10) const;
unsigned to_uint(char * idx = nullptr, char base = 10) const;
unsigned long to_ulong(char * idx = nullptr, char base = 10) const;
float to_float(char * idx = nullptr) const;
protected: protected:
string(char l, char * b); string(char l, char * b);
}; };
void swap(string & u, string & v);
string to_string(int val);
string to_string(long val);
string to_string(unsigned int val);
string to_string(unsigned long val);
string to_string(float val);
}
#pragma compile("string.cpp") #pragma compile("string.cpp")
#endif #endif

40
include/opp/utility.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef OPP_UTILITY_H
#define OPP_UTILITY_H
namespace opp {
template <class T>
inline T && move(T & m)
{
return (T &&)m;
}
template <class T>
inline void swap(T & x, T & y)
{
T t(x); x = y; y = move(t);
}
template<class T1, class T2>
struct pair
{
T1 first;
T2 second;
pair(T1 && t1, T2 && t2)
: first(t1), second(t2)
{}
};
template<class T1, class T2>
constexpr pair<T1, T2> make_pair(T1 && t1, T2 && t2)
{
return pair<T1, T2>(t1, t2);
}
}
#endif

363
include/opp/vector.h Normal file
View File

@ -0,0 +1,363 @@
#ifndef OPP_VECTOR_H
#define OPP_VECTOR_H
#include <new>
#include <stdlib.h>
#include <opp/utility.h>
namespace opp {
template <class T>
class vector
{
protected:
T * _data;
size_t _size, _capacity;
public:
typedef T element_type;
vector(void) : _data(nullptr), _size(0), _capacity(0) {}
vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{
for(size_t i=0; i<n; i++)
new (_data + i) T();
}
vector(const vector & v)
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
new (_data + i)T(v._data[i]);
}
vector(vector && v)
: _data(v._data), _size(v._size), _capacity(v._capacity)
{
v._data = nullptr;
v._size = 0;
v._capacity = 0;
}
~vector(void)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
free(_data);
}
vector & operator=(const vector & v)
{
if (this != &v)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
_data[i].~T();
free(_data);
_data = (T*)malloc(v._size * sizeof(T));
_size = v._size;
_capacity = v._size;
n = _size;
for(size_t i=0; i<n; i++)
new (_data + i)T(v._data[i]);
}
return *this;
}
vector & operator=(vector && v)
{
if (this != &v)
{
swap(_data, v._data);
swap(_size, v._size);
swap(_capacity, v._capacity);
}
return *this;
}
int size(void) const
{
return _size;
}
int max_size(void) const
{
return 32767;
}
bool empty(void) const
{
return _size == 0;
}
int capacity(void) const
{
return _capacity;
}
void clear(void);
void resize(size_t n);
void reserve(size_t n);
void shrink_to_fit(void);
T & at(size_t at)
{
return _data[at];
}
const T & at(size_t at) const
{
return _data[at];
}
T & operator[](size_t at)
{
return _data[at];
}
const T & operator[](size_t at) const
{
return _data[at];
}
T * begin(void)
{
return _data;
}
const T * begin(void) const
{
return _data;
}
const T * cbegin(void) const
{
return _data;
}
T * end(void)
{
return _data + _size;
}
const T * end(void) const
{
return _data + _size;
}
const T * cend(void) const
{
return _data + _size;
}
T & front(void)
{
return _data[0];
}
const T & front(void) const
{
return _data[0];
}
T & back(void)
{
return _data[_size - 1];
}
const T & back(void) const
{
return _data[_size - 1];
}
T * data(void)
{
return _data;
}
const T * at(void) const
{
return _data;
}
void push_back(const T & t);
void push_back(T && t);
void pop_back(void)
{
_size--;
_data[_size].~T();
}
void assign(size_t count, const T & t);
void insert(size_t at, const T & t);
void erase(size_t at, size_t n = 1);
T * insert(T * at, const T & t);
template <typename ...P>
void emplace_back(const P&... p);
protected:
T * add_back(void);
};
template <class T>
__noinline void vector<T>::reserve(size_t n)
{
if (n > _capacity)
{
_capacity = n;
T * d = (T *)malloc(_capacity * sizeof(T));
for(size_t i=0; i<_size; i++)
{
new (d + i)T(move(_data[i]));
_data[i].~T();
}
free(_data);
_data = d;
}
}
template <class T>
void vector<T>::clear(void)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
_size = 0;
}
template <class T>
__noinline void vector<T>::resize(size_t n)
{
if (n < _size)
{
for(size_t i=n; i<_size; i++)
_data[i].~T();
_size = n;
}
else if (n < _capacity)
{
for(size_t i=_size; i<n; i++)
new(_data + i)T();
_size = n;
}
else
{
reserve(n);
_size = n;
}
}
template <class T>
void vector<T>::shrink_to_fit(void)
{
if (_size < _capacity)
{
_capacity = _size;
T * d = (T *)malloc(_capacity * sizeof(T));
for(size_t i=0; i<_size; i++)
{
new (d + i)T(move(_data[i]));
_data[i].~T();
}
free(_data);
_data = d;
}
}
template <class T>
T * vector<T>::add_back(void)
{
if (_size == _capacity)
reserve(_size + 1 + (_size >> 1));
return _data + _size++;
}
template <class T>
void vector<T>::push_back(const T & t)
{
new (add_back())T(t);
}
template <class T>
void vector<T>::push_back(T && t)
{
new (add_back())T(t);
}
template <class T>
template <typename ...P>
void vector<T>::emplace_back(const P&... p)
{
new (add_back())T(p...);
}
template <class T>
void vector<T>::assign(size_t count, const T & t)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
if (count > _capacity)
{
_size = 0;
reserve(count);
}
for(size_t i=0; i<count; i++)
new (_data + i)T(t);
_size = count;
}
template <class T>
void vector<T>::insert(size_t at, const T & t)
{
if (_size == _capacity)
reserve(_size + 1 + (_size >> 1));
new (_data + _size)T();
for(size_t i=_size; i>at; i--)
_data[i] = move(_data[i - 1]);
_data[at] = t;
_size++;
}
template <class T>
void vector<T>::erase(size_t at, size_t n)
{
_size -= n;
for(size_t i=at; i<_size; i++)
_data[i] = move(_data[i + n]);
for(size_t i=0; i<n; i++)
_data[_size + i].~T();
}
template <class T>
T * vector<T>::insert(T * at, const T & t)
{
if (_size == _capacity)
{
unsigned f = unsigned(at) - unsigned(_data);
reserve(_size + 1 + (_size >> 1));
at = (T *)(f + unsigned(_data));
}
T * dp = _data + _size;
new (dp)T();
while (dp != at)
{
dp--;
dp[1] = move(dp[0]);
}
dp[0] = t;
_size++;
return dp + 1;
}
}
#endif

View File

@ -86,3 +86,53 @@ const char * oscar_expand_rle(char * dp, const char * sp)
return sp + 1; return sp + 1;
} }
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
{
char buf[256];
char b = 0;
char cmd = sp[0];
do
{
if (cmd & 0x80)
{
char i = b - sp[1];
cmd &= 0x7f;
sp += 2;
char n = 0;
do {
buf[b] = dp[n] = buf[i];
b++;
i++;
n++;
} while (n != cmd);
}
else
{
sp += 1;
char n = 0;
do {
buf[b] = dp[n] = sp[n];
b++;
n++;
} while (n != cmd);
sp += cmd;
}
dp += cmd;
cmd = sp[0];
} while (cmd);
return sp + 1;
}
void debugcrash(void)
{
__asm volatile {
byt $02
}
}

View File

@ -6,6 +6,19 @@ __native const char * oscar_expand_lzo(char * dp, const char * sp);
__native const char * oscar_expand_rle(char * dp, const char * sp); __native const char * oscar_expand_rle(char * dp, const char * sp);
// Same as oscar_expand_lzo, but does not need read access to the
// target memory area. On the downside, it uses 256 bytes of stack
// memory as buffer
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp);
// Write a breakpoint instruction into the .lbl file for vice. This
// intrinsic function will change the behaviour of the optimizer to ensure
// that the breakpoint is not move around into wild places.
void breakpoint(void);
#pragma intrinsic(breakpoint)
void debugcrash(void);
#pragma compile("oscar.c") #pragma compile("oscar.c")

View File

@ -2,237 +2,50 @@
#include "conio.h" #include "conio.h"
#include "stdlib.h" #include "stdlib.h"
#if defined(__C128__)
#pragma code(lowcode)
__asm bsout
{
ldx #0
stx 0xff00
jsr 0xffd2
sta 0xff01
}
__asm bsplot
{
lda #0
sta 0xff00
jsr 0xfff0
sta 0xff01
}
__asm bsin
{
lda #0
sta 0xff00
jsr 0xffcf
sta 0xff01
}
#pragma code(code)
#elif defined(__PLUS4__)
#pragma code(lowcode)
__asm bsout
{
sta 0xff3e
jsr 0xffd2
sta 0xff3f
}
__asm bsin
{
sta 0xff3e
jsr 0xffe4
sta 0xff3f
}
__asm bsplot
{
sta 0xff3e
jsr 0xfff0
sta 0xff3f
}
#pragma code(code)
#elif defined(__ATARI__)
__asm bsout
{
tax
lda 0xe407
pha
lda 0xe406
pha
txa
}
__asm bsin
{
lda 0xe405
pha
lda 0xe404
pha
}
__asm bsplot
{
}
#else
#define bsout 0xffd2
#define bsplot 0xfff0
#define bsin 0xffcf
#endif
__asm putpch
{
#if defined(__ATARI__)
cmp #10
bne w1
lda #0x9b
w1:
jmp bsout
#else
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
cmp #10
bne w1
lda #13
w1:
cmp #9
beq t1
cpx #IOCHM_PETSCII_1
bcc w3
cmp #65
bcc w3
cmp #123
bcs w3
#if defined(__CBMPET__)
cmp #97
bcs w4
cmp #91
bcs w3
w2:
eor #$a0
w4:
eor #$20
#else
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
#endif
cpx #IOCHM_PETSCII_2
beq w3
and #$df
w3:
jmp bsout
t1:
sec
jsr bsplot
tya
and #3
eor #3
tax
lda #$20
l1:
jsr bsout
dex
bpl l1
#endif
}
__asm getpch
{
jsr bsin
#if !defined(__ATARI__)
ldx giocharmap
cpx #IOCHM_ASCII
bcc w3
cmp #13
bne w1
lda #10
w1:
cpx #IOCHM_PETSCII_1
bcc w3
cmp #219
bcs w3
cmp #65
bcc w3
cmp #193
bcc w4
eor #$a0
w4:
cmp #123
bcs w3
cmp #97
bcs w2
cmp #91
bcs w3
w2:
eor #$20
w3:
#endif
}
void putchar(char c) void putchar(char c)
{ {
__asm { putpch(c);
lda c
jmp putpch
}
} }
char getchar(void) char getchar(void)
{ {
__asm { return getpch();
jsr getpch
sta accu
lda #0
sta accu + 1
}
} }
void puts(const char * str) void puts(const char * str)
{ {
__asm { while (char ch = *str++)
ploop: putpch(ch);
ldy #0
lda (str), y
beq pdone
jsr putpch
inc str
bne ploop
inc str + 1
bne ploop
pdone:
}
} }
char * gets(char * str) char * gets(char * str)
{ {
__asm { char i = 0;
gloop: while ((char ch = getpch()) != '\n')
jsr getpch str[i++] = ch;
ldy #0 str[i] = 0;
cmp #10 return str;
beq gdone }
sta (str), y
inc str
bne gloop
inc str + 1
bne gloop
gdone:
lda #0
sta (str), y
}
char * gets_s(char * str, size_t n)
{
if (str == NULL)
return NULL;
if (n < 2)
return NULL;
char i = 0, t = n - 1;
while ((char ch = getpch()) != '\n')
{
if (i < t)
str[i] = ch;
++i;
}
str[(i < t) ? i : t] = '\0';
if (i > t)
return NULL;
return str; return str;
} }
@ -279,10 +92,7 @@ int nformi(const sinfo * si, char * str, int v, bool s)
while (u > 0) while (u > 0)
{ {
int c = u % si->base; int c = u % si->base;
if (c >= 10) c += c >= 10 ? 'A' - 10 : '0';
c += 'A' - 10;
else
c += '0';
buffer[--i] = c; buffer[--i] = c;
u /= si->base; u /= si->base;
} }
@ -340,10 +150,7 @@ int nforml(const sinfo * si, char * str, long v, bool s)
while (u > 0) while (u > 0)
{ {
int c = u % si->base; int c = u % si->base;
if (c >= 10) c += c >= 10 ? 'A' - 10 : '0';
c += 'A' - 10;
else
c += '0';
buffer[--i] = c; buffer[--i] = c;
u /= si->base; u /= si->base;
} }
@ -589,7 +396,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
if (c >= '0' && c <='9') if (c >= '0' && c <='9')
{ {
int i = 0; char i = 0;
while (c >= '0' && c <='9') while (c >= '0' && c <='9')
{ {
i = i * 10 + c - '0'; i = i * 10 + c - '0';
@ -600,7 +407,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
if (c == '.') if (c == '.')
{ {
int i = 0; char i = 0;
c = *p++; c = *p++;
while (c >= '0' && c <='9') while (c >= '0' && c <='9')
{ {
@ -610,36 +417,36 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
si.precision = i; si.precision = i;
} }
if (c == 'd') if (c == 'd' || c == p'd' || c == 'i' || c == p'i')
{ {
bi = nformi(&si, bp, *fps++, true); bi = nformi(&si, bp, *fps++, true);
} }
else if (c == 'u') else if (c == 'u' || c == p'u')
{ {
bi = nformi(&si, bp, *fps++, false); bi = nformi(&si, bp, *fps++, false);
} }
else if (c == 'x') else if (c == 'x' || c == p'x')
{ {
si.base = 16; si.base = 16;
bi = nformi(&si, bp, *fps++, false); bi = nformi(&si, bp, *fps++, false);
} }
#ifndef NOLONG #ifndef NOLONG
else if (c == 'l') else if (c == 'l' || c == p'l')
{ {
long l = *(long *)fps; long l = *(long *)fps;
fps ++; fps ++;
fps ++; fps ++;
c = *p++; c = *p++;
if (c == 'd') if (c == 'd' || c == p'd')
{ {
bi = nforml(&si, bp, l, true); bi = nforml(&si, bp, l, true);
} }
else if (c == 'u') else if (c == 'u' || c == p'u')
{ {
bi = nforml(&si, bp, l, false); bi = nforml(&si, bp, l, false);
} }
else if (c == 'x') else if (c == 'x' || c == p'x')
{ {
si.base = 16; si.base = 16;
bi = nforml(&si, bp, l, false); bi = nforml(&si, bp, l, false);
@ -647,14 +454,14 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
} }
#endif #endif
#ifndef NOFLOAT #ifndef NOFLOAT
else if (c == 'f' || c == 'g' || c == 'e') else if (c == 'f' || c == 'g' || c == 'e' || c == p'f' || c == p'g' || c == p'e')
{ {
bi = nformf(&si, bp, *(float *)fps, c); bi = nformf(&si, bp, *(float *)fps, c);
fps ++; fps ++;
fps ++; fps ++;
} }
#endif #endif
else if (c == 's') else if (c == 's' || c == p's')
{ {
char * sp = (char *)*fps++; char * sp = (char *)*fps++;
@ -700,7 +507,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
} }
} }
} }
else if (c == 'c') else if (c == 'c' || c == p'c')
{ {
bp[bi++] = *fps++; bp[bi++] = *fps++;
} }
@ -749,6 +556,17 @@ int sprintf(char * str, const char * fmt, ...)
return d - str; return d - str;
} }
void vprintf(const char * fmt, va_list vlist)
{
char buff[50];
sformat(buff, fmt, (int *)vlist, true);
}
int vsprintf(char * str, const char * fmt, va_list vlist)
{
char * d = sformat(str, fmt, (int *)vlist, false);
return d - str;
}
static inline bool isspace(char c) static inline bool isspace(char c)
{ {
@ -862,7 +680,7 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
} }
} }
if (fc == 'l') if (fc == 'l' || fc == p'l')
{ {
islong = true; islong = true;
fc = *fmt++; fc = *fmt++;
@ -877,11 +695,15 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
break; break;
case 'x': case 'x':
case p'x':
base = 16; base = 16;
case 'u': case 'u':
case p'u':
issigned = false; issigned = false;
case 'i': case 'i':
case 'd': case 'd':
case p'i':
case p'd':
{ {
bool sign = false; bool sign = false;
if (cs == '-') if (cs == '-')
@ -962,6 +784,9 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
case 'f': case 'f':
case 'e': case 'e':
case 'g': case 'g':
case p'f':
case p'e':
case p'g':
{ {
bool sign = false; bool sign = false;
if (cs == '-') if (cs == '-')
@ -1068,6 +893,7 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
} break; } break;
#endif #endif
case 's': case 's':
case p's':
{ {
char * pch = (char *)*params; char * pch = (char *)*params;
while (width > 0 && cs > 0 && !isspace(cs)) while (width > 0 && cs > 0 && !isspace(cs))
@ -1110,6 +936,7 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
} break; } break;
case 'c': case 'c':
case p'c':
{ {
char * pch = (char *)*params; char * pch = (char *)*params;
if (!ignore) if (!ignore)

View File

@ -2,7 +2,8 @@
#define STDIO_H #define STDIO_H
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
void putchar(char c); void putchar(char c);
@ -12,10 +13,16 @@ void puts(const char * str);
char * gets(char * str); char * gets(char * str);
char * gets_s(char * str, size_t n);
void printf(const char * fmt, ...); void printf(const char * fmt, ...);
int sprintf(char * str, const char * fmt, ...); int sprintf(char * str, const char * fmt, ...);
void vprintf(const char * fmt, va_list vlist);
int vsprintf(char * str, const char * fmt, va_list vlist);
int scanf(const char * fmt, ...); int scanf(const char * fmt, ...);
int sscanf(const char * str, const char * fmt, ...); int sscanf(const char * str, const char * fmt, ...);

View File

@ -7,20 +7,17 @@
void itoa(int n, char * s, unsigned radix) void itoa(int n, char * s, unsigned radix)
{ {
bool neg = n < 0; bool neg = n < 0;
if (neg) unsigned un = neg ? -n : n;
{
n = - n;
}
char i = 0; char i = 0;
do { do {
int d = n % radix; unsigned d = un % radix;
if (d < 10) if (d < 10)
d += '0'; d += '0';
else else
d += 'A' - 10; d += 'A' - 10;
s[i++] = d; s[i++] = d;
} while ((n /= radix) > 0); } while ((un /= radix) > 0);
if (neg) if (neg)
{ {
@ -524,6 +521,12 @@ void exit(int status)
} }
} }
void abort(void)
{
exit(-1);
}
extern struct Heap { extern struct Heap {
Heap * next, * end; Heap * next, * end;
} HeapNode; } HeapNode;
@ -541,7 +544,7 @@ unsigned heapfree(void)
} }
#if 0 #if 0
struct Heap { struct Heap {q
unsigned int size; unsigned int size;
Heap * next; Heap * next;
} * freeHeap; } * freeHeap;
@ -664,6 +667,97 @@ void * calloc(int num, int size)
return p; return p;
} }
void * realloc(void * ptr, unsigned size)
{
if (ptr)
{
#ifdef HEAPCHECK
Heap * pheap = (Heap *)((char *)ptr - 6);
Heap * eheap = pheap->next;
unsigned psize = (char *)eheap - (char *)pheap;
void * nptr = malloc(size);
memcpy(nptr, ptr, psize - 6);
free(ptr);
return nptr;
#else
unsigned nsize = (size + 5) & ~3;
// Get heap info
Heap * pheap = (Heap *)((char *)ptr - 2);
Heap * eheap = pheap->next;
unsigned psize = (char *)eheap - (char *)pheap;
Heap * h = HeapNode.next;
Heap * hp = &HeapNode;
while (h && h < pheap)
{
hp = h;
h = h->next;
}
if (nsize <= psize)
{
// check if we should free some memory
if (nsize + sizeof(HeapNode) < psize)
{
Heap * nheap = (Heap *)((char *)pheap + nsize);
pheap->next = nheap;
if (h == eheap)
{
nheap->end = h->end;
nheap->next = h->next;
}
else
{
nheap->end = eheap;
nheap->next = h;
}
hp->next = nheap;
}
return ptr;
}
else if (h == eheap)
{
// Free space after this
// Check if enough space if extending
unsigned xsize = (char *)h->end - (char *)pheap;
if (xsize >= nsize)
{
if (xsize > nsize + sizeof(HeapNode))
{
Heap * nheap = (Heap *)((char *)pheap + nsize);
pheap->next = nheap;
nheap->end = h->end;
nheap->next = h->next;
hp->next = nheap;
}
else
{
pheap->next = h->end;
hp->next = h->next;
}
return ptr;
}
}
void * nptr = malloc(size);
memcpy(nptr, ptr, psize - 2);
free(ptr);
return nptr;
#endif
}
else
return malloc(size);
}
static unsigned seed = 31232; static unsigned seed = 31232;
unsigned int rand(void) unsigned int rand(void)

View File

@ -37,12 +37,16 @@ long labs(long n);
void exit(int status); void exit(int status);
void abort(void);
void * malloc(unsigned int size); void * malloc(unsigned int size);
void free(void * ptr); void free(void * ptr);
void * calloc(int num, int size); void * calloc(int num, int size);
void * realloc(void * ptr, unsigned size);
unsigned heapfree(void); unsigned heapfree(void);
unsigned int rand(void); unsigned int rand(void);

View File

@ -130,13 +130,28 @@ char * strcat(char * dst, const char * src)
char * cpycat(char * dst, const char * src) char * cpycat(char * dst, const char * src)
{ {
do {} while (*dst++ = *src++); while (*dst = *src++)
dst++;
return dst; return dst;
} }
#pragma native(cpycat) #pragma native(cpycat)
char* strchr( const char* str, int ch )
{
char * p = (char *)str;
while (*p != (char)ch)
{
if (!*p)
return nullptr;
p++;
}
return p;
}
void * memset(void * dst, int value, int size) void * memset(void * dst, int value, int size)
{ {
__asm __asm
@ -222,8 +237,8 @@ void * memmove(void * dst, const void * src, int size)
int sz = size; int sz = size;
if (sz > 0) if (sz > 0)
{ {
char * d = dst; char * d = (char *)dst;
const char * s = src; const char * s = (const char *)src;
if (d < s) if (d < s)
{ {
do { do {
@ -244,7 +259,7 @@ void * memmove(void * dst, const void * src, int size)
int memcmp(const void * ptr1, const void * ptr2, int size) int memcmp(const void * ptr1, const void * ptr2, int size)
{ {
const char * p = ptr1, * q = ptr2; const char * p = (const char *)ptr1, * q = (const char *)ptr2;
char c, d; char c, d;
while (size--) while (size--)

View File

@ -21,10 +21,16 @@ int memcmp(const void * ptr1, const void * ptr2, int size);
void * memmove(void * dst, const void * src, int size); void * memmove(void * dst, const void * src, int size);
char* strchr( const char* str, int ch );
#pragma intrinsic(strcpy) #pragma intrinsic(strcpy)
#pragma intrinsic(memcpy) #pragma intrinsic(memcpy)
#pragma intrinsic(memset)
#pragma intrinsic(memclr)
#pragma compile("string.c") #pragma compile("string.c")
#endif #endif

Some files were not shown because too many files have changed in this diff Show More