From a378e831e23e9764e0018d6d0dc7cc005fdfd4fb Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 11 Apr 2020 21:15:34 +0200 Subject: [PATCH] Added support for header-files found in include-folders and C-files found in library-folders. The compiler auto-searches for the C-file in the defined lib search path whenever a H-file is included. Closes #387 --- .gitlab-ci.yml | 3 +- src/main/assembly/assembly.xml | 12 +- .../java/dk/camelot64/kickc/Compiler.java | 20 +- src/main/java/dk/camelot64/kickc/KickC.java | 13 +- .../java/dk/camelot64/kickc/SourceLoader.java | 30 +- .../dk/camelot64/kickc/model/Program.java | 32 +- .../dk/camelot64/kickc/parser/CParser.java | 54 ++-- .../Pass0GenerateStatementSequence.java | 50 +-- src/main/kc/include/atan2.h | 12 + src/main/kc/include/basic-floats.h | 128 ++++++++ src/main/kc/include/bitmap-draw.h | 13 + src/main/kc/include/bitmap2.h | 23 ++ src/main/kc/include/c64.h | 224 ++++++++++++++ .../kc/{stdlib/c64dtv.c => include/c64dtv.h} | 17 +- src/main/kc/include/division.h | 66 ++++ src/main/kc/include/fastmultiply.h | 34 +++ src/main/kc/include/keyboard.h | 136 +++++++++ src/main/kc/include/multiplexer.h | 66 ++++ src/main/kc/include/multiply.h | 19 ++ src/main/kc/include/print.h | 76 +++++ src/main/kc/include/sinus.h | 52 ++++ src/main/kc/include/sqr.h | 14 + .../kc/{stdlib/stdint.c => include/stdint.h} | 0 src/main/kc/include/stdlib.h | 41 +++ src/main/kc/include/string.h | 21 ++ src/main/kc/{stdlib/time.c => include/time.h} | 15 +- src/main/kc/{stdlib => lib}/atan2.c | 2 + src/main/kc/{stdlib => lib}/basic-floats.c | 2 + src/main/kc/{stdlib => lib}/bitmap-draw.c | 2 + src/main/kc/{stdlib => lib}/bitmap2.c | 3 +- src/main/kc/lib/c64.c | 27 ++ src/main/kc/lib/c64dtv.c | 24 ++ src/main/kc/{stdlib => lib}/division.c | 2 + src/main/kc/{stdlib => lib}/fastmultiply.c | 2 + src/main/kc/{stdlib => lib}/keyboard.c | 71 +---- src/main/kc/{stdlib => lib}/limits.c | 0 src/main/kc/{stdlib => lib}/multiplexer.c | 3 +- src/main/kc/{stdlib => lib}/multiply.c | 2 + src/main/kc/{stdlib => lib}/print.c | 4 +- src/main/kc/{stdlib => lib}/sinus.c | 5 +- src/main/kc/{stdlib => lib}/sqr.c | 3 +- src/main/kc/{stdlib => lib}/stdlib.c | 5 +- src/main/kc/{stdlib => lib}/string.c | 3 +- src/main/kc/lib/time.c | 21 ++ src/main/kc/stdlib/c64.c | 233 -------------- src/main/script/kickc.bat | 7 +- src/main/script/kickc.sh | 10 +- .../dk/camelot64/kickc/test/TestPrograms.java | 13 +- src/test/kc/bitmap-circle-2.c | 2 +- src/test/kc/bitmap-circle.c | 2 +- src/test/kc/bitmap-line-anim-1.c | 4 +- src/test/kc/bitmap-line-anim-2.c | 4 +- src/test/kc/bitmap-plot-0.c | 4 +- src/test/kc/bitmap-plot-1.c | 8 +- src/test/kc/bitmap-plot-2.c | 8 +- src/test/kc/bitmap-plot-3.c | 6 +- src/test/kc/c-types.c | 2 +- src/test/kc/c64dtv-8bppcharstretch.c | 2 +- src/test/kc/c64dtv-8bppchunkystretch.c | 2 +- src/test/kc/c64dtv-blitter-box.c | 2 +- src/test/kc/c64dtv-blittermin.c | 2 +- src/test/kc/c64dtv-color.c | 2 +- src/test/kc/c64dtv-gfxexplorer.c | 8 +- src/test/kc/c64dtv-gfxmodes.c | 8 +- src/test/kc/cia-timer-cyclecount.c | 6 +- src/test/kc/cia-timer-simple.c | 6 +- src/test/kc/complex/clearscreen/clearscreen.c | 10 +- src/test/kc/complex/includes/includes-1.c | 2 +- src/test/kc/complex/includes/includes-3.c | 14 + src/test/kc/complex/includes/lib.c | 6 + src/test/kc/complex/includes/lib.h | 4 + src/test/kc/complex/medusa/medusa.c | 4 +- src/test/kc/complex/prebob/grid-bobs.c | 12 +- src/test/kc/complex/prebob/vogel-bobs.c | 12 +- src/test/kc/complex/prebob/vogel-sprites.c | 10 +- .../kc/complex/splines/truetype-splines.c | 10 +- .../complex/spritescroller/spritescroller.c | 4 +- src/test/kc/complex/tetris/tetris-sprites.c | 2 +- src/test/kc/complex/tetris/tetris.c | 4 +- src/test/kc/complex/travis/game-orig.c | 4 +- src/test/kc/complex/xmega65/xmega65.c | 2 +- src/test/kc/constants.c | 2 +- src/test/kc/cordic-atan2-16-ref.c | 6 +- src/test/kc/cordic-atan2-16.c | 4 +- src/test/kc/cordic-atan2-clear.c | 4 +- src/test/kc/cordic-atan2.c | 4 +- src/test/kc/cstyle-decl-var-missing.c | 2 +- src/test/kc/danny-joystick-problem.c | 2 +- src/test/kc/default-font.c | 2 +- src/test/kc/euclid-3.c | 2 +- src/test/kc/examples/3d/3d.c | 4 +- src/test/kc/examples/3d/perspective.c | 4 +- .../kc/examples/bresenham/bitmap-bresenham.c | 4 +- .../kc/examples/chargen/chargen-analysis.c | 4 +- .../kc/examples/fastmultiply/fastmultiply8.c | 2 +- src/test/kc/examples/fire/fire.c | 2 +- src/test/kc/examples/font-2x2/font-2x2.c | 4 +- src/test/kc/examples/helloworld/helloworld.c | 3 +- src/test/kc/examples/irq/irq-hyperscreen.c | 2 +- src/test/kc/examples/kernalload/kernalload.c | 4 +- .../examples/multiplexer/simple-multiplexer.c | 4 +- src/test/kc/examples/music/music.c | 2 +- src/test/kc/examples/music/music_irq.c | 2 +- src/test/kc/examples/nmisamples/nmisamples.c | 2 +- src/test/kc/examples/plasma/plasma-unroll.c | 4 +- src/test/kc/examples/plasma/plasma.c | 4 +- src/test/kc/examples/rasterbars/raster-bars.c | 2 +- src/test/kc/examples/rotate/rotate.c | 8 +- src/test/kc/examples/scrolllogo/scrolllogo.c | 6 +- src/test/kc/examples/showlogo/showlogo.c | 4 +- .../kc/examples/sinplotter/sine-plotter.c | 8 +- .../kc/examples/sinsprites/sinus-sprites.c | 6 +- src/test/kc/fastmultiply-127.c | 2 +- src/test/kc/font-hex-show.c | 4 +- src/test/kc/gfxbank.c | 2 +- src/test/kc/incrementinarray.c | 2 +- src/test/kc/irq-hardware-clobber-jsr.c | 2 +- src/test/kc/irq-idx-problem.c | 2 +- src/test/kc/irq-kernel-minimal.c | 2 +- src/test/kc/keyboard-glitch.c | 4 +- src/test/kc/line-anim.c | 4 +- src/test/kc/linegen.c | 4 +- src/test/kc/logarithm.c | 2 +- src/test/kc/loophead-problem-3.c | 4 +- src/test/kc/malloc-0.c | 2 +- src/test/kc/malloc-1.c | 2 +- src/test/kc/memcpy-0.c | 4 +- src/test/kc/memcpy-1.c | 2 +- src/test/kc/memory-heap.c | 2 +- src/test/kc/millfork-benchmarks/benchcommon.c | 4 +- src/test/kc/millfork-benchmarks/plasma-kc.c | 2 +- src/test/kc/millfork-benchmarks/romsum-kc.c | 2 +- src/test/kc/millfork-benchmarks/sieve-kc.c | 2 +- src/test/kc/min-fmul-16.c | 2 +- src/test/kc/mul8u-min.c | 2 +- .../multiplexer-irq/simple-multiplexer-irq.c | 4 +- src/test/kc/number-ternary-fail-2.c | 2 +- src/test/kc/plasma-center.c | 12 +- src/test/kc/printmsg.c | 2 +- .../kc/processor-port-test-writethrough.c | 4 +- src/test/kc/processor-port-test.c | 4 +- src/test/kc/robozzle64-label-problem.c | 2 +- src/test/kc/roll-sprite-msb.c | 2 +- src/test/kc/sandbox.c | 2 +- src/test/kc/scan-desire-problem.c | 8 +- src/test/kc/screen-center-angle.c | 10 +- src/test/kc/screen-center-distance.c | 10 +- src/test/kc/screen-show-spiral-buckets.c | 8 +- src/test/kc/screen-show-spiral.c | 6 +- src/test/kc/semi-struct-1.c | 2 +- src/test/kc/semi-struct-2.c | 6 +- src/test/kc/sieve-min.c | 10 +- src/test/kc/sieve.c | 12 +- src/test/kc/signed-indexed-subtract.c | 2 +- src/test/kc/signed-words.c | 2 +- src/test/kc/sinus-basic.c | 4 +- src/test/kc/sinusb.c | 2 +- src/test/kc/sinusgen16.c | 4 +- src/test/kc/sinusgen16b.c | 4 +- src/test/kc/sinusgen8.c | 4 +- src/test/kc/sinusgen8b.c | 4 +- src/test/kc/sinusgenscale8.c | 6 +- src/test/kc/sprite-font.c | 4 +- src/test/kc/struct-ptr-22.c | 2 +- src/test/kc/struct-ptr-26.c | 2 +- src/test/kc/test-comparisons-sword.c | 4 +- src/test/kc/test-comparisons-word.c | 4 +- src/test/kc/test-comparisons.c | 2 +- src/test/kc/test-division.c | 4 +- src/test/kc/test-keyboard-space.c | 2 +- src/test/kc/test-keyboard.c | 2 +- src/test/kc/test-lowhigh.c | 2 +- src/test/kc/test-multiply-16bit.c | 6 +- src/test/kc/test-multiply-8bit.c | 6 +- src/test/kc/test-signed-word-minus-byte.c | 2 +- src/test/kc/test-utoa.c | 4 +- src/test/kc/textbox.c | 2 +- src/test/kc/travis1.c | 2 +- src/test/kc/type-signed.c | 2 +- src/test/kc/wfragment1.c | 2 +- src/test/kc/zeropage-sinus.c | 2 +- src/test/ref/c64dtv-8bppcharstretch.log | 2 +- src/test/ref/c64dtv-8bppchunkystretch.log | 2 +- src/test/ref/c64dtv-blitter-box.log | 2 +- src/test/ref/c64dtv-blittermin.log | 2 +- src/test/ref/c64dtv-color.log | 2 +- src/test/ref/c64dtv-gfxexplorer.log | 2 +- src/test/ref/c64dtv-gfxmodes.log | 2 +- .../ref/complex/clearscreen/clearscreen.log | 8 +- src/test/ref/complex/includes/includes-3.asm | 14 + src/test/ref/complex/includes/includes-3.cfg | 18 ++ src/test/ref/complex/includes/includes-3.log | 284 ++++++++++++++++++ src/test/ref/complex/includes/includes-3.sym | 9 + src/test/ref/complex/tetris/test-sprites.log | 2 +- src/test/ref/complex/tetris/tetris.log | 2 +- src/test/ref/cstyle-decl-var.log | 58 ++-- src/test/ref/keyboard-glitch.asm | 8 +- src/test/ref/keyboard-glitch.log | 24 +- src/test/ref/malloc-0.log | 4 +- src/test/ref/malloc-1.log | 4 +- src/test/ref/memory-heap.log | 4 +- .../procedure-callingconvention-stack-10.log | 6 +- .../procedure-callingconvention-stack-11.log | 18 +- src/test/ref/screen-center-distance.log | 4 +- src/test/ref/semi-struct-2.asm | 2 +- src/test/ref/semi-struct-2.log | 6 +- src/test/ref/sieve-min.log | 50 ++- src/test/ref/sieve.asm | 18 +- src/test/ref/sieve.log | 54 ++-- src/test/ref/test-keyboard-space.asm | 2 +- src/test/ref/test-keyboard-space.log | 6 +- src/test/ref/test-keyboard.asm | 18 +- src/test/ref/test-keyboard.log | 54 ++-- 213 files changed, 1974 insertions(+), 877 deletions(-) create mode 100644 src/main/kc/include/atan2.h create mode 100644 src/main/kc/include/basic-floats.h create mode 100644 src/main/kc/include/bitmap-draw.h create mode 100644 src/main/kc/include/bitmap2.h create mode 100644 src/main/kc/include/c64.h rename src/main/kc/{stdlib/c64dtv.c => include/c64dtv.h} (94%) create mode 100644 src/main/kc/include/division.h create mode 100644 src/main/kc/include/fastmultiply.h create mode 100644 src/main/kc/include/keyboard.h create mode 100644 src/main/kc/include/multiplexer.h create mode 100644 src/main/kc/include/multiply.h create mode 100644 src/main/kc/include/print.h create mode 100644 src/main/kc/include/sinus.h create mode 100644 src/main/kc/include/sqr.h rename src/main/kc/{stdlib/stdint.c => include/stdint.h} (100%) create mode 100644 src/main/kc/include/stdlib.h create mode 100644 src/main/kc/include/string.h rename src/main/kc/{stdlib/time.c => include/time.h} (62%) rename src/main/kc/{stdlib => lib}/atan2.c (99%) rename src/main/kc/{stdlib => lib}/basic-floats.c (99%) rename src/main/kc/{stdlib => lib}/bitmap-draw.c (99%) rename src/main/kc/{stdlib => lib}/bitmap2.c (98%) create mode 100644 src/main/kc/lib/c64.c create mode 100644 src/main/kc/lib/c64dtv.c rename src/main/kc/{stdlib => lib}/division.c (99%) rename src/main/kc/{stdlib => lib}/fastmultiply.c (99%) rename src/main/kc/{stdlib => lib}/keyboard.c (79%) rename src/main/kc/{stdlib => lib}/limits.c (100%) rename src/main/kc/{stdlib => lib}/multiplexer.c (99%) rename src/main/kc/{stdlib => lib}/multiply.c (98%) rename src/main/kc/{stdlib => lib}/print.c (99%) rename src/main/kc/{stdlib => lib}/sinus.c (98%) rename src/main/kc/{stdlib => lib}/sqr.c (96%) rename src/main/kc/{stdlib => lib}/stdlib.c (98%) rename src/main/kc/{stdlib => lib}/string.c (98%) create mode 100644 src/main/kc/lib/time.c delete mode 100644 src/main/kc/stdlib/c64.c create mode 100644 src/test/kc/complex/includes/includes-3.c create mode 100644 src/test/kc/complex/includes/lib.c create mode 100644 src/test/kc/complex/includes/lib.h create mode 100644 src/test/ref/complex/includes/includes-3.asm create mode 100644 src/test/ref/complex/includes/includes-3.cfg create mode 100644 src/test/ref/complex/includes/includes-3.log create mode 100644 src/test/ref/complex/includes/includes-3.sym diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 987aee949..a09145bf0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,7 +15,8 @@ release: paths: - ./kickc/bin - ./kickc/lib - - ./kickc/stdlib + - ./kickc/include + - ./kickc/lib - ./kickc/fragment - ./kickc/examples - ./kickc/LICENSE* diff --git a/src/main/assembly/assembly.xml b/src/main/assembly/assembly.xml index f737c53e2..f98e555af 100644 --- a/src/main/assembly/assembly.xml +++ b/src/main/assembly/assembly.xml @@ -12,8 +12,16 @@ - src/main/kc/stdlib - stdlib + src/main/kc/include + include + + *.c + *.h + + + + src/main/kc/lib + lib *.c *.h diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 4c2f40e92..19926f137 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -8,12 +8,12 @@ import dk.camelot64.kickc.model.statements.StatementSource; import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.values.SymbolRef; import dk.camelot64.kickc.parser.CParser; -import dk.camelot64.kickc.parser.KickCLexer; import dk.camelot64.kickc.parser.KickCParser; import dk.camelot64.kickc.passes.*; import dk.camelot64.kickc.preprocessor.CPreprocessor; import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenSource; import java.io.File; import java.nio.file.Path; @@ -140,16 +140,20 @@ public class Compiler { return program.getLog(); } - public void addImportPath(String path) { - program.getImportPaths().add(path); + public void addIncludePath(String path) { + program.getIncludePaths().add(path); + } + + public void addLibraryPath(String path) { + program.getLibraryPaths().add(path); } public void preprocess(List cFiles) { Path currentPath = new File(".").toPath(); CParser cParser = new CParser(program); for(Path cFile : cFiles) { - final KickCLexer fileLexer = cParser.loadCFile(cFile.toString(), currentPath); - cParser.addSourceLast(fileLexer); + final TokenSource cFileTokens = cParser.loadCFile(cFile.toString(), currentPath, program.getIncludePaths(), false); + cParser.addSourceLast(cFileTokens); } final CPreprocessor preprocessor = cParser.getPreprocessor(); Token token = preprocessor.nextToken(); @@ -175,9 +179,9 @@ public class Compiler { } program.setStatementSequence(new StatementSequence()); CParser cParser = new CParser(program); - for(Path file : cFiles) { - final KickCLexer fileLexer = cParser.loadCFile(file.toString(), currentPath); - cParser.addSourceLast(fileLexer); + for(Path cFile : cFiles) { + final TokenSource cFileTokens = cParser.loadCFile(cFile.toString(), currentPath, program.getIncludePaths(), false); + cParser.addSourceLast(cFileTokens); } // Parse the files diff --git a/src/main/java/dk/camelot64/kickc/KickC.java b/src/main/java/dk/camelot64/kickc/KickC.java index a88b8090f..268185adb 100644 --- a/src/main/java/dk/camelot64/kickc/KickC.java +++ b/src/main/java/dk/camelot64/kickc/KickC.java @@ -40,7 +40,10 @@ public class KickC implements Callable { @CommandLine.Parameters(index = "0", arity = "0..n", description = "The C source files to compile.") private List cFiles = null; - @CommandLine.Option(names = {"-I", "-libdir"}, description = "Path to a library folder, where the compiler looks for included files. This option can be repeated to add multiple library folders.") + @CommandLine.Option(names = {"-I", "-includedir"}, description = "Path to an include folder, where the compiler looks for included files. This option can be repeated to add multiple include folders.") + private List includeDir = null; + + @CommandLine.Option(names = {"-L", "-libdir"}, description = "Path to a library folder, where the compiler looks for library files. This option can be repeated to add multiple library folders.") private List libDir = null; @CommandLine.Option(names = {"-F", "-fragmentdir"}, description = "Path to the ASM fragment folder, where the compiler looks for ASM fragments.") @@ -205,9 +208,15 @@ public class KickC implements Callable { compiler.setTargetCpu(targetCpu); } + if(includeDir != null) { + for(Path includePath : includeDir) { + compiler.addIncludePath(includePath.toString()); + } + } + if(libDir != null) { for(Path libPath : libDir) { - compiler.addImportPath(libPath.toString()); + compiler.addLibraryPath(libPath.toString()); } } diff --git a/src/main/java/dk/camelot64/kickc/SourceLoader.java b/src/main/java/dk/camelot64/kickc/SourceLoader.java index 96dfcb90b..1af052c04 100644 --- a/src/main/java/dk/camelot64/kickc/SourceLoader.java +++ b/src/main/java/dk/camelot64/kickc/SourceLoader.java @@ -16,16 +16,23 @@ import java.util.List; */ public class SourceLoader { - public static File loadFile(String fileName, Path currentPath, Program program) { - List searchPaths = new ArrayList<>(); + /** + * Locate a file and load it. Looks through the current path and a set of search folder. + * @param fileName The file to look for. + * @param currentPath The current path. May be null. + * @param searchPaths The search paths to look through if the file is not found in the current path. + * @return The file if found. null if not. + */ + public static File loadFile(String fileName, Path currentPath, List searchPaths) { + List allSearchPaths = new ArrayList<>(); if(currentPath != null) - searchPaths.add(currentPath.toString()); - searchPaths.addAll(program.getImportPaths()); - for(String importPath : searchPaths) { - if(!importPath.endsWith("/")) { - importPath += "/"; + allSearchPaths.add(currentPath.toString()); + allSearchPaths.addAll(searchPaths); + for(String searchPath : allSearchPaths) { + if(!searchPath.endsWith("/")) { + searchPath += "/"; } - String filePath = importPath + fileName; + String filePath = searchPath + fileName; //System.out.println("Looking for file "+filePath); File file = new File(filePath); if(file.exists()) { @@ -33,12 +40,15 @@ public class SourceLoader { return file; } } - throw new CompileError("File not found " + fileName); + // Not found + return null; } public static void loadLinkScriptFile(String fileName, Path currentPath, Program program) { try { - File file = loadFile(fileName, currentPath, program); + File file = loadFile(fileName, currentPath, program.getIncludePaths()); + if(file==null) + throw new CompileError("File not found " + fileName); Path filePath = file.toPath(); String linkScript = new String(Files.readAllBytes(filePath)); program.setLinkScript(filePath, linkScript); diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index 792ad559d..5550fc0da 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -21,10 +21,12 @@ public class Program { /** The name of the primary file being compiled. PASS 0-5 (STATIC) */ private String primaryFileName; - /** Paths used for importing files. PASS 0 (STATIC) */ - private List importPaths; - /** Imported files. PASS 0 (STATIC) */ - private List imported; + /** Paths used for including files. PASS 0 (STATIC) */ + private List includePaths; + /** Paths used for library files. PASS 0 (STATIC) */ + private List libraryPaths; + /** All loaded H/C-files. PASS 0 (STATIC) */ + private List loadedFiles; /** The target platform that the program is being build for. PASS 0-5 (STATIC) */ private TargetPlatform targetPlatform = TargetPlatform.DEFAULT; @@ -106,8 +108,9 @@ public class Program { public Program() { this.scope = new ProgramScope(); this.log = new CompileLog(); - this.importPaths = new ArrayList<>(); - this.imported = new ArrayList<>(); + this.includePaths = new ArrayList<>(); + this.libraryPaths = new ArrayList<>(); + this.loadedFiles = new ArrayList<>(); this.asmResourceFiles = new ArrayList<>(); this.reservedZps = new ArrayList<>(); } @@ -116,8 +119,9 @@ public class Program { * Clears all data that is only used in PASS 1 */ public void endPass1() { - this.importPaths = null; - this.imported = null; + this.includePaths = null; + this.libraryPaths = null; + this.loadedFiles = null; this.statementSequence = null; this.procedureModifiedVars = null; this.structVariableMemberUnwinding = null; @@ -249,12 +253,16 @@ public class Program { this.fileComments = fileComments; } - public List getImportPaths() { - return importPaths; + public List getIncludePaths() { + return includePaths; } - public List getImported() { - return imported; + public List getLibraryPaths() { + return libraryPaths; + } + + public List getLoadedFiles() { + return loadedFiles; } public List getAsmResourceFiles() { diff --git a/src/main/java/dk/camelot64/kickc/parser/CParser.java b/src/main/java/dk/camelot64/kickc/parser/CParser.java index 4e2b500af..2e5d6c644 100644 --- a/src/main/java/dk/camelot64/kickc/parser/CParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/CParser.java @@ -1,5 +1,6 @@ package dk.camelot64.kickc.parser; +import dk.camelot64.kickc.Compiler; import dk.camelot64.kickc.SourceLoader; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.Program; @@ -93,6 +94,7 @@ public class CParser { /** * Get the preprocessor (usable for getting all preprocessed tokens). + * * @return The preprocessor */ public CPreprocessor getPreprocessor() { @@ -147,15 +149,24 @@ public class CParser { /** * Loads a C-file (if it has not already been loaded). - * + *

* The C-file is inserted into the C token stream at the current parse-point - so the parser will parse the entire content of the file before moving on. * * @param fileName The file name of the file */ public void includeCFile(String fileName, boolean isSystem) { + if(fileName.startsWith("\"") || fileName.startsWith("<")) { + fileName = fileName.substring(1, fileName.length() - 1); + } final Path currentSourceFolderPath = isSystem ? null : getCurrentSourceFolderPath(); - final KickCLexer lexer = loadCFile(fileName, currentSourceFolderPath); - addSourceFirst(lexer); + final TokenSource fileTokens = loadCFile(fileName, currentSourceFolderPath, program.getIncludePaths(), false); + if(fileName.endsWith(".h")) { + // The included file was a H-file - attempt to find the matching library C-file + String libFileName = Compiler.removeFileNameExtension(fileName) + ".c"; + final TokenSource cLibFileTokens = loadCFile(libFileName, currentSourceFolderPath, program.getLibraryPaths(), true); + addSourceFirst(cLibFileTokens); + } + addSourceFirst(fileTokens); } /** @@ -163,20 +174,23 @@ public class CParser { * * @param fileName The file name of the file * @param currentPath The path of the current folder (searched before the search path). - * @return The lexer to be inserted into the source-list using one of the {@link #addSourceFirst(KickCLexer)} / {@link #addSourceLast(KickCLexer)} methods. + * @param searchPaths The folders to look in if the files is not found in current path + * @return The lexer tokens to be inserted into the source-list using one of the {@link #addSourceFirst(TokenSource)} / {@link #addSourceLast(TokenSource)} methods. */ - public KickCLexer loadCFile(String fileName, Path currentPath) { + public TokenSource loadCFile(String fileName, Path currentPath, List searchPaths, boolean acceptFileNotFound) { try { - if(fileName.startsWith("\"") || fileName.startsWith("<")) { - fileName = fileName.substring(1, fileName.length() - 1); - } - File file = SourceLoader.loadFile(fileName, currentPath, program); - List imported = program.getImported(); - if(imported.contains(file.getAbsolutePath())) { + File file = SourceLoader.loadFile(fileName, currentPath, searchPaths); + if(file == null) + if(acceptFileNotFound) + return null; + else + throw new CompileError("File not found " + fileName); + List included = program.getLoadedFiles(); + if(included.contains(file.getAbsolutePath())) { return null; } final CharStream fileStream = CharStreams.fromPath(file.toPath().toAbsolutePath()); - imported.add(file.getAbsolutePath()); + included.add(file.getAbsolutePath()); if(program.getLog().isVerboseParse()) { program.getLog().append("PARSING " + file.getPath().replace("\\", "/")); program.getLog().append(fileStream.toString()); @@ -217,21 +231,21 @@ public class CParser { /** * Add source code at the start of the token stream being parsed. * - * @param lexer The lexer for reading the source tokens + * @param tokenSource The lexer for reading the source tokens */ - public void addSourceFirst(KickCLexer lexer) { - if(lexer != null) - cTokenSource.addSourceFirst(lexer); + public void addSourceFirst(TokenSource tokenSource) { + if(tokenSource != null) + cTokenSource.addSourceFirst(tokenSource); } /** * Add source code at the end of the token stream being parsed. * - * @param lexer The lexer for reading the source tokens + * @param tokenSource The lexer for reading the source tokens */ - public void addSourceLast(KickCLexer lexer) { - if(lexer != null) - cTokenSource.addSourceLast(lexer); + public void addSourceLast(TokenSource tokenSource) { + if(tokenSource != null) + cTokenSource.addSourceLast(tokenSource); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 380227f9c..f71521d3c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -255,7 +255,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor()); + if(resourceFile==null) + throw new CompileError("File not found " + resourceName); program.addAsmResourceFile(resourceFile.toPath()); if(program.getLog().isVerboseParse()) { program.getLog().append("Added resource " + resourceFile.getPath().replace('\\', '/')); @@ -873,28 +875,34 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor effectiveDirectives = varDecl.getEffectiveDirectives(); final List declComments = varDecl.getDeclComments(); varDecl.exitVar(); - - if(isStructMember && (initializer != null)) - throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource); - if(initializer != null) - PrePostModifierHandler.addPreModifiers(this, initializer, statementSource); - RValue initValue = (initializer == null) ? null : (RValue) visit(initializer); - initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(effectiveType, effectiveArraySpec), program, statementSource); VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, effectiveType, effectiveArraySpec, effectiveDirectives, currentDataSegment, variableBuilderConfig); Variable variable = varBuilder.build(); - boolean isPermanent = ScopeRef.ROOT.equals(variable.getScope().getRef()) || variable.isPermanent(); - if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !isStructMember && variable.getRegister() == null)) { - // Set initial value - ConstantValue constInitValue = getConstInitValue(initValue, initializer, statementSource); - variable.setInitValue(constInitValue); - // Add comments to constant - variable.setComments(ensureUnusedComments(declComments)); - } else if(!variable.isKindConstant() && !isStructMember) { - Statement initStmt = new StatementAssignment(variable.getVariableRef(), initValue, true, statementSource, ensureUnusedComments(declComments)); - sequence.addStatement(initStmt); + if(isStructMember && (initializer != null)) + throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource); + if(variable.isDeclarationOnly()) { + if(initializer != null) { + throw new CompileError("Initializer not allowed for extern variables " + varName, statementSource); + } + } else { + // Create a proper initializer + if(initializer != null) + PrePostModifierHandler.addPreModifiers(this, initializer, statementSource); + RValue initValue = (initializer == null) ? null : (RValue) visit(initializer); + initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(effectiveType, effectiveArraySpec), program, statementSource); + boolean isPermanent = ScopeRef.ROOT.equals(variable.getScope().getRef()) || variable.isPermanent(); + if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !isStructMember && variable.getRegister() == null)) { + // Set initial value + ConstantValue constInitValue = getConstInitValue(initValue, initializer, statementSource); + variable.setInitValue(constInitValue); + // Add comments to constant + variable.setComments(ensureUnusedComments(declComments)); + } else if(!variable.isKindConstant() && !isStructMember) { + Statement initStmt = new StatementAssignment(variable.getVariableRef(), initValue, true, statementSource, ensureUnusedComments(declComments)); + sequence.addStatement(initStmt); + } + if(initializer != null) + PrePostModifierHandler.addPostModifiers(this, initializer, statementSource); } - if(initializer != null) - PrePostModifierHandler.addPostModifiers(this, initializer, statementSource); } catch(CompileError e) { throw new CompileError(e.getMessage(), declSource); } diff --git a/src/main/kc/include/atan2.h b/src/main/kc/include/atan2.h new file mode 100644 index 000000000..42d86eb18 --- /dev/null +++ b/src/main/kc/include/atan2.h @@ -0,0 +1,12 @@ +// Find atan2(x, y) using the CORDIC method +// See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf + +// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y) +// Finding the angle requires a binary search using CORDIC_ITERATIONS_16 +// Returns the angle in hex-degrees (0=0, 0x8000=PI, 0x10000=2*PI) +word atan2_16(signed word x, signed word y); + +// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y) +// Finding the angle requires a binary search using CORDIC_ITERATIONS_8 +// Returns the angle in hex-degrees (0=0, 0x80=PI, 0x100=2*PI) +byte atan2_8(signed byte x, signed byte y); \ No newline at end of file diff --git a/src/main/kc/include/basic-floats.h b/src/main/kc/include/basic-floats.h new file mode 100644 index 000000000..1e5bb689b --- /dev/null +++ b/src/main/kc/include/basic-floats.h @@ -0,0 +1,128 @@ +// Library wrapping the BASIC floating point functions +// See https://www.c64-wiki.com/wiki/Floating_point_arithmetic +// See http://www.pagetable.com/c64rom/c64rom_sc.html + +// Prepare MEM pointers for operations using MEM +inline void prepareMEM(unsigned int mem); + +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word +void setFAC(unsigned int w); + +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process +unsigned int getFAC(); + +// ARG = FAC +// Set the ARG (floating point argument) to the value of the FAC (floating point accumulator) +void setARGtoFAC(); + +// FAC = ARG +// Set the FAC (floating point accumulator) to the value of the ARG (floating point argument) +void setFACtoARG(); + +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) +void setMEMtoFAC(char* mem); + +// FAC = MEM +// Set the FAC to value from MEM (float saved in memory) +// Reads 5 bytes +void setFACtoMEM(char* mem); + +// FAC = PI/2 +// Set the FAC to PI/2 +// Reads 5 bytes from the BASIC ROM +void setFACtoPIhalf(); + +// FAC = 2*PI +// Set the FAC to 2*PI +// Reads 5 bytes from the BASIC ROM +void setFACto2PI(); + +// ARG = MEM +// Load the ARG from memory +// Reads 5 bytes +void setARGtoMEM(char* mem); + +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory +void addMEMtoFAC(char* mem); + +// FAC = ARG+FAC +// Add ARG (floating point argument) to FAC (floating point accumulator) +void addARGtoFAC(); + +// FAC = MEM-FAC +// Set FAC to MEM (float saved in memory) minus FAC (float accumulator) +// Reads 5 bytes from memory +void subFACfromMEM(char* mem); + +// FAC = ARG-FAC +// Set FAC to ARG minus FAC +void subFACfromARG(); + +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory +void divMEMbyFAC(char* mem); + +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory +void mulFACbyMEM(char* mem); + +// FAC = MEM^FAC +// Set FAC to MEM (float saved in memory) raised to power of FAC (float accumulator) +// Reads 5 bytes from memory +void pwrMEMbyFAC(char* mem); + +// FAC = int(FAC) +// Set FAC to integer part of the FAC - int(FAC) +// The integer part is defined as the next lower integer - like java floor() +void intFAC(); + +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) +void sinFAC(); + +// FAC = cos(FAC) +// Set FAC to cosinus of the FAC - cos(FAC) +// Cosinus is calculated on radians (0-2*PI) +void cosFAC(); + +// FAC = tan(FAC) +// Set FAC to the tangens of FAC - tan(FAC) +// Tangens is calculated on radians (0-2*PI) +void tanFAC(); + +// FAC = atn(FAC) +// Set FAC to the arc tangens of FAC - atn(FAC) +// Arc Tangens is calculated on radians (0-2*PI) +void atnFAC(); + +// FAC = sqr(FAC) +// Set FAC to the square root of FAC - sqr(FAC) +void sqrFAC(); + +// FAC = exp(FAC) +// Set FAC to the exponential function of FAC - exp(FAC) +// Exp is based on the natural logarithm e=2.71828183 +void expFAC(); + +// FAC = log(FAC) +// Set FAC to the logarithm of FAC - log(FAC) +// Log is based on the natural logarithm e=2.71828183 +void logFAC(); + +// FAC = FAC/10 +// Set FAC to FAC divided by 10 +void divFACby10(); + +// FAC = FAC*10 +// Set FAC to FAC multiplied by 10 +void mulFACby10(); \ No newline at end of file diff --git a/src/main/kc/include/bitmap-draw.h b/src/main/kc/include/bitmap-draw.h new file mode 100644 index 000000000..9c107f705 --- /dev/null +++ b/src/main/kc/include/bitmap-draw.h @@ -0,0 +1,13 @@ +// Plot and line drawing routines for HIRES bitmaps +// Currently it can only plot on the first 256 x-positions. + +// Initialize the bitmap plotter tables for a specific bitmap +void bitmap_init(byte* bitmap); + +// Clear all graphics on the bitmap +void bitmap_clear(); + +void bitmap_plot(byte x, byte y); + +// Draw a line on the bitmap +void bitmap_line(byte x0, byte x1, byte y0, byte y1); \ No newline at end of file diff --git a/src/main/kc/include/bitmap2.h b/src/main/kc/include/bitmap2.h new file mode 100644 index 000000000..00ecd3a65 --- /dev/null +++ b/src/main/kc/include/bitmap2.h @@ -0,0 +1,23 @@ +// Simple single-color (320x200) bitmap routines +#include + +// Initialize bitmap plotting tables +void bitmap_init(byte* gfx, byte* screen); + +// Clear all graphics on the bitmap +// bgcol - the background color to fill the screen with +// fgcol - the foreground color to fill the screen with +void bitmap_clear(byte bgcol, byte fgcol); + +// Plot a single dot in the bitmap +void bitmap_plot(word x, byte y); + +// Draw a line on the bitmap using bresenhams algorithm +void bitmap_line(word x1, word y1, word x2, word y2); + +// Get the absolute value of a 16-bit unsigned number treated as a signed number. +word abs_u16(word w); + +// Get the sign of a 16-bit unsigned number treated as a signed number. +// Returns unsigned -1 if the number is +word sgn_u16(word w); diff --git a/src/main/kc/include/c64.h b/src/main/kc/include/c64.h new file mode 100644 index 000000000..1e3fdf4b4 --- /dev/null +++ b/src/main/kc/include/c64.h @@ -0,0 +1,224 @@ +// Commodore 64 Registers and Constants + +// Processor port data direction register +char* const PROCPORT_DDR = $00; +// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written +const char PROCPORT_DDR_MEMORY_MASK = %00000111; + +// Processor Port Register controlling RAM/ROM configuration and the datasette +char* const PROCPORT = $01; +// RAM in all three areas $A000, $D000, $E000 +const char PROCPORT_RAM_ALL = %00000000; +// RAM in $A000, $E000 I/O in $D000 +const char PROCPORT_RAM_IO = %00000101; +// RAM in $A000, $E000 CHAR ROM in $D000 +const char PROCPORT_RAM_CHARROM = %00000001; +// RAM in $A000, I/O in $D000, KERNEL in $E000 +const char PROCPORT_KERNEL_IO = %00000110; +// BASIC in $A000, I/O in $D000, KERNEL in $E000 +const char PROCPORT_BASIC_KERNEL_IO = %00000111; + +// The address of the CHARGEN character set +char* const CHARGEN = $d000; + +// Positions of the border (in sprite positions) +const char BORDER_XPOS_LEFT=24; +const unsigned int BORDER_XPOS_RIGHT=344; +const char BORDER_YPOS_TOP=50; +const char BORDER_YPOS_BOTTOM=250; + +// The offset of the sprite pointers from the screen start address +const unsigned int SPRITE_PTRS = $3f8; + +char* const SPRITES_XPOS = $d000; +char* const SPRITES_YPOS = $d001; +char* const SPRITES_XMSB = $d010; +char* const RASTER = $d012; +char* const SPRITES_ENABLE = $d015; +char* const SPRITES_EXPAND_Y = $d017; +char* const SPRITES_PRIORITY = $d01b; +char* const SPRITES_MC = $d01c; +char* const SPRITES_EXPAND_X = $d01d; +char* const BORDERCOL = $d020; +char* const BGCOL = $d021; +char* const BGCOL1 = $d021; +char* const BGCOL2 = $d022; +char* const BGCOL3 = $d023; +char* const BGCOL4 = $d024; +char* const SPRITES_MC1 = $d025; +char* const SPRITES_MC2 = $d026; +char* const SPRITES_COLS = $d027; + +char* const VIC_CONTROL = $d011; +char* const D011 = $d011; +const char VIC_RST8 = %10000000; +const char VIC_ECM = %01000000; +const char VIC_BMM = %00100000; +const char VIC_DEN = %00010000; +const char VIC_RSEL = %00001000; + +char* const VIC_CONTROL2 = $d016; +char* const D016 = $d016; +const char VIC_MCM = %00010000; +const char VIC_CSEL = %00001000; + +char* const D018 = $d018; +char* const VIC_MEMORY = $d018; + +char* const LIGHTPEN_X = $d013; +char* const LIGHTPEN_Y = $d014; + +// VIC II IRQ Status Register +char* const IRQ_STATUS = $d019; +// VIC II IRQ Enable Register +char* const IRQ_ENABLE = $d01a; +// Bits for the IRQ Status/Enable Registers +const char IRQ_RASTER = %00000001; +const char IRQ_COLLISION_BG = %00000010; +const char IRQ_COLLISION_SPRITE = %00000100; +const char IRQ_LIGHTPEN = %00001000; + +// Color Ram +char* const COLS = $d800; + +// CIA#1 Port A: keyboard matrix columns and joystick #2 +char* const CIA1_PORT_A = $dc00; +// CIA#1 Port B: keyboard matrix rows and joystick #1. +char* const CIA1_PORT_B = $dc01; +// CIA #1 Port A data direction register. +char* const CIA1_PORT_A_DDR = $dc02; +// CIA #1 Port B data direction register. +char* const CIA1_PORT_B_DDR = $dc03; +// CIA #1 Timer A Value +unsigned int* const CIA1_TIMER_A = $dc04; +// CIA #1 Timer B Value +unsigned int* const CIA1_TIMER_B = $dc06; +// CIA #1 Time-of-day real-time-clock tenth seconds (BCD) +char* const CIA1_TOD_10THS = $dc08; +// CIA #1 Time-of-day real-time-clock seconds (BCD) +char* const CIA1_TOD_SEC = $dc09; +// CIA #1 Time-of-day real-time-clock minutes (BCD) +char* const CIA1_TOD_MIN = $dc0a; +// CIA #1 Time-of-day real-time-clock hours (BCD) +char* const CIA1_TOD_HOURS = $dc0b; +// CIA #1 Serial Shift Register +char* const CIA1_SERIAL_SHIFT_OUT = $dc0c; +// CIA#1 Interrupt Status & Control Register +char* const CIA1_INTERRUPT = $dc0d; +// CIA#1 Timer A Control Register +char* const CIA1_TIMER_A_CONTROL = $dc0e; +// CIA#1 Timer B Control Register +char* const CIA1_TIMER_B_CONTROL = $dc0f; + +// CIA#2 Port A: Serial bus, RS-232, VIC memory bank +char* const CIA2_PORT_A = $dd00; +// CIA#2 Port B: RS-232 +char* const CIA2_PORT_B = $dd01; +// CIA #2 Port A data direction register. +char* const CIA2_PORT_A_DDR = $dd02; +// CIA #2 Port B data direction register. +char* const CIA2_PORT_B_DDR = $dd03; +// CIA #2 Timer A+B Value (32-bit) +unsigned long* const CIA2_TIMER_AB = $dd04; +// CIA #2 Timer A Value (16-bit) +unsigned int* const CIA2_TIMER_A = $dd04; +// CIA #2 Timer B Value (16-bit) +unsigned int* const CIA2_TIMER_B = $dd06; +// CIA #2 Time-of-day real-time-clock tenth seconds (BCD) +char* const CIA2_TOD_10THS = $dd08; +// CIA #2 Time-of-day real-time-clock seconds (BCD) +char* const CIA2_TOD_SEC = $dd09; +// CIA #2 Time-of-day real-time-clock minutes (BCD) +char* const CIA2_TOD_MIN = $dd0a; +// CIA #2 Time-of-day real-time-clock hours (BCD) +char* const CIA2_TOD_HOURS = $dd0b; +// CIA #2 Serial Shift Register +char* const CIA2_SERIAL_SHIFT_OUT = $dd0c; +// CIA #2 Interrupt Status & Control Register +char* const CIA2_INTERRUPT = $dd0d; +// CIA #2 Timer A Control Register +char* const CIA2_TIMER_A_CONTROL = $dd0e; +// CIA #2 Timer B Control Register +char* const CIA2_TIMER_B_CONTROL = $dd0f; + +// Value that disables all CIA interrupts when stored to the CIA Interrupt registers +const char CIA_INTERRUPT_CLEAR = $7f; + +// Timer Control - Start/stop timer (0:stop, 1: start) +const char CIA_TIMER_CONTROL_STOP = 0b00000000; +// Timer Control - Start/stop timer (0:stop, 1: start) +const char CIA_TIMER_CONTROL_START = 0b00000001; +// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT) +const char CIA_TIMER_CONTROL_CONTINUOUS = 0b00000000; +// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT) +const char CIA_TIMER_CONTROL_ONESHOT = 0b00001000; +// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses) +const char CIA_TIMER_CONTROL_A_COUNT_CYCLES = 0b00000000; +// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses) +const char CIA_TIMER_CONTROL_A_COUNT_CNT = 0b00100000; +// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output) +const char CIA_TIMER_CONTROL_A_SERIAL_IN = 0b00000000; +// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output) +const char CIA_TIMER_CONTROL_A_SERIAL_OUT = 0b01000000; +// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz) +const char CIA_TIMER_CONTROL_A_TOD_60HZ = 0b00000000; +// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz) +const char CIA_TIMER_CONTROL_A_TOD_50HZ = 0b10000000; +// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) +const char CIA_TIMER_CONTROL_B_COUNT_CYCLES = 0b00000000; +// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) +const char CIA_TIMER_CONTROL_B_COUNT_CNT = 0b00100000; +// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) +const char CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = 0b01000000; +// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) +const char CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A_CNT = 0b01100000; +// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm) +const char CIA_TIMER_CONTROL_B_TOD_CLOCK_SET = 0b00000000; +// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm) +const char CIA_TIMER_CONTROL_B_TOD_ALARM_SET = 0b10000000; + +// The vector used when the KERNAL serves IRQ interrupts +void()** const KERNEL_IRQ = $0314; +// The vector used when the KERNAL serves NMI interrupts +void()** const KERNEL_NMI = $0318; + +// The vector used when the HARDWARE serves IRQ interrupts +void()** const HARDWARE_IRQ = $fffe; + +// The SID volume +char* const SID_VOLUME = $d418; + + +// The colors of the C64 +const char BLACK = $0; +const char WHITE = $1; +const char RED = $2; +const char CYAN = $3; +const char PURPLE = $4; +const char GREEN = $5; +const char BLUE = $6; +const char YELLOW = $7; +const char ORANGE = $8; +const char BROWN = $9; +const char PINK = $a; +const char DARK_GREY= $b; +const char GREY = $c; +const char LIGHT_GREEN = $d; +const char LIGHT_BLUE = $e; +const char LIGHT_GREY = $f; + +// Get the value to store into D018 to display a specific screen and charset/bitmap +// Optimized for ASM from (char)((((unsigned int)screen&0x3fff)/$40)|(((unsigned int)charset&$3fff)/$400)); +inline char toD018(char* screen, char* gfx); + +// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank +// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/$4000) +inline char toDd00(char* gfx); + +// Get the sprite pointer for a sprite. +// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64) +// The sprite pointers are stored SCREEN+$3f8+sprite_id to set the pointer of each sprite +inline char toSpritePtr(char* sprite); + +// Select a specific VIC graphics bank by setting the CIA 2 port A ($dd00) as needed +inline void vicSelectGfxBank(char* gfx); diff --git a/src/main/kc/stdlib/c64dtv.c b/src/main/kc/include/c64dtv.h similarity index 94% rename from src/main/kc/stdlib/c64dtv.c rename to src/main/kc/include/c64dtv.h index 3d0ffb78c..cdfa86ec9 100644 --- a/src/main/kc/stdlib/c64dtv.c +++ b/src/main/kc/include/c64dtv.h @@ -4,7 +4,8 @@ // (J) https://www.c64-wiki.com/wiki/C64DTV_Programming_Guide // (H) http://dtvhacking.cbm8bit.com/dtv_wiki/images/d/d9/Dtv_registers_full.txt -#include +#include +#include // Feature enables or disables the extra C64 DTV features byte* const DTV_FEATURE = $d03f; @@ -63,19 +64,7 @@ byte* const DTV_GRAPHICS_HICOL_BANK = $d03e; // Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) // This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff // The actual memory addressed will be $4000*cpuSegmentIdx -void dtvSetCpuBankSegment1(byte cpuBankIdx) { - // Move CPU BANK 1 SEGMENT ($4000-$7fff) - byte* cpuBank = $ff; - *cpuBank = cpuBankIdx; - asm { - // SAC $dd - A register points to 13 BANK 1 segment - .byte $32, $dd - // LDA $ff - Set CPU BANK 1 SEGMENT ($4000-$7fff) to ($ff)*$4000 - lda $ff - // SAC $00 - A register points to 0 ACCUMULATOR - .byte $32, $00 - } -} +void dtvSetCpuBankSegment1(byte cpuBankIdx); // Blitter Source A Start byte* const DTV_BLITTER_SRCA_LO = $d320; diff --git a/src/main/kc/include/division.h b/src/main/kc/include/division.h new file mode 100644 index 000000000..5e9e1aad4 --- /dev/null +++ b/src/main/kc/include/division.h @@ -0,0 +1,66 @@ +// Simple binary division implementation +// Follows the C99 standard by truncating toward zero on negative results. +// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 + +// Remainder after signed 8 bit division +extern char rem8u; + +// Performs division on two 8 bit unsigned bytes +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8u +// Implemented using simple binary division +char div8u(char dividend, char divisor); + +// Performs division on two 8 bit unsigned bytes and an initial remainder +// Returns dividend/divisor. +// The final remainder will be set into the global variable rem8u +// Implemented using simple binary division +char divr8u(char dividend, char divisor, char rem); + +// Remainder after unsigned 16-bit division +extern unsigned int rem16u; + +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division +unsigned int divr16u(unsigned int dividend, unsigned int divisor, unsigned int rem); + +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division +unsigned int div16u(unsigned int dividend, unsigned int divisor); + +// Divide unsigned 32-bit dword dividend with a 16-bit word divisor +// The 16-bit word remainder can be found in rem16u after the division +unsigned long div32u16u(unsigned long dividend, unsigned int divisor); + +// Remainder after signed 8 bit division +extern signed char rem8s; + +// Perform division on two signed 8-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8s. +// Implemented using simple binary division +// Follows the C99 standard by truncating toward zero on negative results. +// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 +signed char div8s(signed char dividend, signed char divisor); + +// Remainder after signed 16 bit division +extern int rem16s; + +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// Implemented using simple binary division +// Follows the C99 standard by truncating toward zero on negative results. +// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 +int divr16s(int dividend, int divisor, int rem); + +// Perform division on two signed 16-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem16s. +// Implemented using simple binary division +// Follows the C99 standard by truncating toward zero on negative results. +// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 +int div16s(int dividend, int divisor); diff --git a/src/main/kc/include/fastmultiply.h b/src/main/kc/include/fastmultiply.h new file mode 100644 index 000000000..6320e9607 --- /dev/null +++ b/src/main/kc/include/fastmultiply.h @@ -0,0 +1,34 @@ +// Library Implementation of the Seriously Fast Multiplication +// See http://codebase64.org/doku.php?id=base:seriously_fast_multiplication +// Utilizes the fact that a*b = ((a+b)/2)^2 - ((a-b)/2)^2 + +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) +void mulf_init(); + +// Prepare for fast multiply with an unsigned byte to a word result +void mulf8u_prepare(byte a); + +// Calculate fast multiply with a prepared unsigned byte to a word result +// The prepared number is set by calling mulf8u_prepare(byte a) +word mulf8u_prepared(byte b); + +// Fast multiply two unsigned bytes to a word result +word mulf8u(byte a, byte b); + +// Prepare for fast multiply with an signed byte to a word result +inline void mulf8s_prepare(signed byte a); + +// Calculate fast multiply with a prepared unsigned byte to a word result +// The prepared number is set by calling mulf8s_prepare(byte a) +signed word mulf8s_prepared(signed byte b); + +// Fast multiply two signed bytes to a word result +signed word mulf8s(signed byte a, signed byte b); + +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X +dword mulf16u(word a, word b); + +// Fast multiply two signed words to a signed double word result +// Fixes offsets introduced by using unsigned multiplication +signed dword mulf16s(signed word a, signed word b); \ No newline at end of file diff --git a/src/main/kc/include/keyboard.h b/src/main/kc/include/keyboard.h new file mode 100644 index 000000000..312d4700a --- /dev/null +++ b/src/main/kc/include/keyboard.h @@ -0,0 +1,136 @@ +// Simple Keyboard Input Library +// C64 Keyboard Matrix Reference - from http://codebase64.org/doku.php?id=base:reading_the_keyboard +// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// +----+----------------------+-------------------------------------------------------------------------------------------------------+ +// | | Write | Read $dc01 (C64 screen code in parenthesis): | +// |row:| $dc00: row bits +------------+------------+------------+------------+------------+------------+------------+------------+ +// | | | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 | +// +----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+ +// |0. | #%11111110 (254/$fe) | DOWN ($ )| F5 ($ )| F3 ($ )| F1 ($ )| F7 ($ )| RIGHT ($ )| RETURN($ )|DELETE ($ )| +// |1. | #%11111101 (253/$fd) |LEFT-SH($ )| e ($05)| s ($13)| z ($1a)| 4 ($34)| a ($01)| w ($17)| 3 ($33)| +// |2. | #%11111011 (251/$fb) | x ($18)| t ($14)| f ($06)| c ($03)| 6 ($36)| d ($04)| r ($12)| 5 ($35)| +// |3. | #%11110111 (247/$f7) | v ($16)| u ($15)| h ($08)| b ($02)| 8 ($38)| g ($07)| y ($19)| 7 ($37)| +// |4. | #%11101111 (239/$ef) | n ($0e)| o ($0f)| k ($0b)| m ($0d)| 0 ($30)| j ($0a)| i ($09)| 9 ($39)| +// |5. | #%11011111 (223/$df) | , ($2c)| @ ($00)| : ($3a)| . ($2e)| - ($2d)| l ($0c)| p ($10)| + ($2b)| +// |6. | #%10111111 (191/$bf) | / ($2f)| ^ ($1e)| = ($3d)|RGHT-SH($ )| HOME ($ )| ; ($3b)| * ($2a)| £ ($1c)| +// |7. | #%01111111 (127/$7f) | STOP ($ )| q ($11)|COMMODR($ )| SPACE ($20)| 2 ($32)|CONTROL($ )| <- ($1f)| 1 ($31)| +// +----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+ + +// Keyboard Codes for all 63 keys. +// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7). +// See C64 Keyboard Matrix Reference http://codebase64.org/doku.php?id=base:reading_the_keyboard +const byte KEY_DEL = $00; +const byte KEY_RETURN = $01; +const byte KEY_CRSR_RIGHT = $02; +const byte KEY_F7 = $03; +const byte KEY_F1 = $04; +const byte KEY_F3 = $05; +const byte KEY_F5 = $06; +const byte KEY_CRSR_DOWN = $07; +const byte KEY_3 = $08; +const byte KEY_W = $09; +const byte KEY_A = $0a; +const byte KEY_4 = $0b; +const byte KEY_Z = $0c; +const byte KEY_S = $0d; +const byte KEY_E = $0e; +const byte KEY_LSHIFT = $0f; +const byte KEY_5 = $10; +const byte KEY_R = $11; +const byte KEY_D = $12; +const byte KEY_6 = $13; +const byte KEY_C = $14; +const byte KEY_F = $15; +const byte KEY_T = $16; +const byte KEY_X = $17; +const byte KEY_7 = $18; +const byte KEY_Y = $19; +const byte KEY_G = $1a; +const byte KEY_8 = $1b; +const byte KEY_B = $1c; +const byte KEY_H = $1d; +const byte KEY_U = $1e; +const byte KEY_V = $1f; +const byte KEY_9 = $20; +const byte KEY_I = $21; +const byte KEY_J = $22; +const byte KEY_0 = $23; +const byte KEY_M = $24; +const byte KEY_K = $25; +const byte KEY_O = $26; +const byte KEY_N = $27; +const byte KEY_PLUS = $28; +const byte KEY_P = $29; +const byte KEY_L = $2a; +const byte KEY_MINUS = $2b; +const byte KEY_DOT = $2c; +const byte KEY_COLON = $2d; +const byte KEY_AT = $2e; +const byte KEY_COMMA = $2f; +const byte KEY_POUND = $30; +const byte KEY_ASTERISK = $31; +const byte KEY_SEMICOLON = $32; +const byte KEY_HOME = $33; +const byte KEY_RSHIFT = $34; +const byte KEY_EQUALS = $35; +const byte KEY_ARROW_UP = $36; +const byte KEY_SLASH = $37; +const byte KEY_1 = $38; +const byte KEY_ARROW_LEFT = $39; +const byte KEY_CTRL = $3a; +const byte KEY_2 = $3b; +const byte KEY_SPACE = $3c; +const byte KEY_COMMODORE = $3d; +const byte KEY_Q = $3e; +const byte KEY_RUNSTOP = $3f; + +// Initialize keyboard reading by setting CIA#$ Data Direction Registers +void keyboard_init(); + +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. +byte keyboard_matrix_read(byte rowid); + +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed +byte keyboard_key_pressed(byte key); + +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . +byte keyboard_get_keycode(byte ch); + +// Current keyboard modifiers (left shift, right shift, ctrl, commodore) +extern byte keyboard_modifiers; +// Left shift is pressed +extern const byte KEY_MODIFIER_LSHIFT; +// Right shift is pressed +extern const byte KEY_MODIFIER_RSHIFT; +// CTRL is pressed +extern const byte KEY_MODIFIER_CTRL; +// Commodore is pressed +extern const byte KEY_MODIFIER_COMMODORE; +// Any shift is pressed +extern const byte KEY_MODIFIER_SHIFT; + +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. +void keyboard_event_scan(); + +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed +byte keyboard_event_pressed(byte keycode); + +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() +byte keyboard_event_get(); + diff --git a/src/main/kc/include/multiplexer.h b/src/main/kc/include/multiplexer.h new file mode 100644 index 000000000..75b3d00d7 --- /dev/null +++ b/src/main/kc/include/multiplexer.h @@ -0,0 +1,66 @@ +// A flexible sprite multiplexer routine for 32 sprites. +// Usage: +// - Once: +// - plexInit(screen): Initialize the data structures and set the screen address +// Each frame: +// - Set x-pos, y-pos and pointer in PLEX_XPOS[id], PLEX_YPOS[id], PLEX_PTR[id] +// - plexSort() Sorts the sprites according to y-positions and prepares for showing them. This uses an insertion sort that is quite fast when the relative order of the sprites does not change very much. +// - plexShowSprite() Shows the next sprite by copying values from PLEX_XXX[] to an actual sprite. Actual sprites are used round-robin. This should be called once for each of the 24 virtual sprites. +// - plexFreeNextYpos() Returns the Y-position where the next sprite is available to be shown (ie. the next pos where the next sprite is no longer in use showing something else). +// - plexShowNextYpos() Returns the Y-position of the next sprite to show. +// +// In practice a good method is to wait until the raster is beyond plexFreeNextYpos() and then call plexShowSprite(). Repeat until all 32 sprites have been shown. +// TODO: Let the caller specify the number of sprites to use (or add PLEX_ENABLE[PLEX_COUNT]) + +#include + +// The number of sprites in the multiplexer +extern const char PLEX_COUNT; + +// The x-positions of the multiplexer sprites (0x000-0x1ff) +extern unsigned int PLEX_XPOS[PLEX_COUNT]; + +// The y-positions of the multiplexer sprites. +extern char PLEX_YPOS[PLEX_COUNT]; + +// The sprite pointers for the multiplexed sprites +extern char PLEX_PTR[PLEX_COUNT]; + +// The address of the sprite pointers on the current screen (screen+0x3f8). +extern char* PLEX_SCREEN_PTR; + +// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it. +extern char PLEX_SORTED_IDX[PLEX_COUNT]; + +// Initialize the multiplexer data structures +void plexInit(char* screen); + +// Set the address of the current screen used for setting sprite pointers (at screen+0x3f8) +inline void plexSetScreen(char* screen); + +// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS +// Assumes that the positions are nearly sorted already (as each sprite just moves a bit) +// Uses an insertion sort: +// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly. +// 2a. If the next element after the marker is larger that the current element +// the marker can be moved forwards (as the sorting is correct). +// 2b. If the next element after the marker is smaller than the current element: +// elements before the marker are shifted right one at a time until encountering one smaller than the current one. +// It is then inserted at the spot. Now the marker can move forward. +void plexSort(); + +// Show the next sprite. +// plexSort() prepares showing the sprites +void plexShowSprite(); + +// Get the y-position of the next sprite to show +inline char plexShowNextYpos(); + +// Prepare for a new frame. Initialize free to zero for all sprites. +inline void plexFreePrepare(); + +// Get the Y-position where the next sprite to be shown is free to use. +inline char plexFreeNextYpos(); + +// Update the data structure to reflect that a sprite has been shown. This sprite will be free again after 21 lines. +inline void plexFreeAdd(char ypos); \ No newline at end of file diff --git a/src/main/kc/include/multiply.h b/src/main/kc/include/multiply.h new file mode 100644 index 000000000..7a5658299 --- /dev/null +++ b/src/main/kc/include/multiply.h @@ -0,0 +1,19 @@ +// Simple binary multiplication implementation + +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word +unsigned int mul8u(char a, char b); + +// Multiply of two signed bytes to a signed word +// Fixes offsets introduced by using unsigned multiplication +int mul8s(signed char a, signed char b); + +// Multiply a signed byte and an unsigned byte (into a signed word) +// Fixes offsets introduced by using unsigned multiplication +int mul8su(signed char a, char b); + +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word +unsigned long mul16u(unsigned int a, unsigned int b); + +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication +signed long mul16s(int a, int b); \ No newline at end of file diff --git a/src/main/kc/include/print.h b/src/main/kc/include/print.h new file mode 100644 index 000000000..72cbe0964 --- /dev/null +++ b/src/main/kc/include/print.h @@ -0,0 +1,76 @@ +#include + +// Print a number of zero-terminated strings, each followed by a newline. +// The sequence of lines is terminated by another zero. +void print_str_lines(byte* str); + +// Print a zero-terminated string followed by a newline +void print_str_ln(byte* str); + +// Print a zero-terminated string +void print_str(byte* str); + +// Print a string at a specific screen position +void print_str_at(byte* str, byte* at); + +// Print a newline +void print_ln(); + +// Print a int as HEX +void print_sword(signed word w); + +// Print a signed byte as HEX +void print_sbyte(signed byte b); + +// Prints a signed byte as HEX at a specific position on the screen +// row and col are 0-based indices +inline void print_sbyte_pos(signed byte sb, byte row, byte col); + +// Print a signed byte as hex at a specific screen position +void print_sbyte_at(signed byte b, byte* at); + +// Print a word as HEX +void print_word(word w); + +// Print a byte as DECIMAL +void print_byte_decimal(byte b); + +// Print a word as DECIMAL +void print_word_decimal(word w); + +// Print a word as HEX at a specific position +void print_word_at(word w, byte* at); + +// Print a dword as HEX +void print_dword(unsigned dword dw); + +// Print a unsigned long as DECIMAL +void print_dword_decimal(unsigned dword w); + +// Print a unsigned long as HEX at a specific position +void print_dword_at(unsigned dword dw, byte* at); + +// Print a signed long as HEX +void print_sdword(signed dword dw); + +// Print a byte as HEX +void print_byte(byte b); + +// Prints a byte as HEX at a specific position on the screen +// row and col are 0-based indices +void print_byte_pos(byte b, byte row, byte col); + +// Print a byte as HEX at a specific position +void print_byte_at(byte b, byte* at); + +// Print a single char +void print_char(byte ch); + +// Print a single char +void print_char_at(byte ch, byte* at); + +// Clear the screen. Also resets current line/char cursor. +void print_cls(); + +// Set the screen to print on. Also resets current line/char cursor. +void print_set_screen(byte* screen); \ No newline at end of file diff --git a/src/main/kc/include/sinus.h b/src/main/kc/include/sinus.h new file mode 100644 index 000000000..b6d03fc67 --- /dev/null +++ b/src/main/kc/include/sinus.h @@ -0,0 +1,52 @@ +// Sinus Generator functions using only multiplication, addition and bit shifting +// Uses a single division for converting the wavelength to a reciprocal. +// Generates sinus using the series sin(x) = x - x^/3! + x^-5! - x^7/7! ... +// Uses the approximation sin(x) = x - x^/6 + x^/128 +// Optimization possibility: Use symmetries when generating sinustables. wavelength%2==0 -> mirror symmetry over PI, wavelength%4==0 -> mirror symmetry over PI/2. + +// PI*2 in u[4.28] format +extern const unsigned long PI2_u4f28; +// PI in u[4.28] format +extern const unsigned long PI_u4f28; +// PI/2 in u[4.28] format +extern const unsigned long PI_HALF_u4f28; + +// PI*2 in u[4.12] format +extern const unsigned int PI2_u4f12; +// PI in u[4.12] format +extern const unsigned int PI_u4f12; +// PI/2 in u[4.12] format +extern const unsigned int PI_HALF_u4f12; + +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) +void sin16s_gen(int* sintab, unsigned int wavelength); + +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) +void sin16s_gen2(int* sintab, unsigned int wavelength, int min, int max); + +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) +void sin8s_gen(signed char* sintab, unsigned int wavelength); + +// Calculate signed word sinus sin(x) +// x: unsigned dword input u[4.28] in the interval $00000000 - PI2_u4f28 +// result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff +int sin16s(unsigned long x); + +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f +signed char sin8s(unsigned int x); + +// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result. +// The select parameter indicates how many of the highest bits of the 32-bit result to skip +unsigned int mulu16_sel(unsigned int v1, unsigned int v2, char select); + +// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result. +// The select parameter indicates how many of the highest bits of the 16-bit result to skip +char mulu8_sel(char v1, char v2, char select); \ No newline at end of file diff --git a/src/main/kc/include/sqr.h b/src/main/kc/include/sqr.h new file mode 100644 index 000000000..2bb696b2c --- /dev/null +++ b/src/main/kc/include/sqr.h @@ -0,0 +1,14 @@ +// Table-based implementation of integer square sqr() and square root sqrt() + +// Initialize squares table +// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1 +void init_squares(); + +// Find the square of a byte value +// Uses a table of squares that must be initialized by calling init_squares() +word sqr(byte val); + +// Find the (integer) square root of a word value +// If the square is not an integer then it returns the largest integer N where N*N <= val +// Uses a table of squares that must be initialized by calling init_squares() +byte sqrt(word val); diff --git a/src/main/kc/stdlib/stdint.c b/src/main/kc/include/stdint.h similarity index 100% rename from src/main/kc/stdlib/stdint.c rename to src/main/kc/include/stdint.h diff --git a/src/main/kc/include/stdlib.h b/src/main/kc/include/stdlib.h new file mode 100644 index 000000000..42eb2d392 --- /dev/null +++ b/src/main/kc/include/stdlib.h @@ -0,0 +1,41 @@ +// C standard library stdlib.h +// Implementation of functions found int C stdlib.h / stdlib.c +#include + +// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. +// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values. +void* malloc(unsigned int size); + +// A block of memory previously allocated by a call to malloc is deallocated, making it available again for further allocations. +// If ptr is a null pointer, the function does nothing. +void free(void* ptr); + +// Allocates memory and returns a pointer to it. Sets allocated memory to zero. +// - nitems − This is the number of elements to be allocated. +// - size − This is the size of elements. +void *calloc(size_t nitems, size_t size); + +// Searches an array of nitems unsigned words, the initial member of which is pointed to by base, for a member that matches the value key. +// - key - The value to look for +// - items - Pointer to the start of the array to search in +// - num - The number of items in the array +// Returns pointer to an entry in the array that matches the search key +unsigned int* bsearch16u(unsigned int key, unsigned int* items, char num); + +// The different supported radix +enum RADIX { BINARY=2, OCTAL=8, DECIMAL=10, HEXADECIMAL=16 }; + +// Converts unsigned number value to a string representing it in RADIX format. +// If the leading digits are zero they are not included in the string. +// - value : The number to be converted to RADIX +// - buffer : receives the string representing the number and zero-termination. +// - radix : The radix to convert the number to (from the enum RADIX) +void utoa(unsigned int value, char* buffer, enum RADIX radix); + +// Converts unsigned number value to a string representing it in RADIX format. +// If the leading digits are zero they are not included in the string. +// - value : The number to be converted to RADIX +// - buffer : receives the string representing the number and zero-termination. +// - radix : The radix to convert the number to (from the enum RADIX) +void ultoa(unsigned long value, char* buffer, enum RADIX radix); + diff --git a/src/main/kc/include/string.h b/src/main/kc/include/string.h new file mode 100644 index 000000000..97022bd4e --- /dev/null +++ b/src/main/kc/include/string.h @@ -0,0 +1,21 @@ +// C standard library string.h +// Functions to manipulate C strings and arrays. + +typedef unsigned int size_t ; + +// Copy block of memory (forwards) +// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. +void* memcpy( void* destination, void* source, size_t num ); + +// Move block of memory +// Copies the values of num bytes from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap. +void* memmove( void* destination, void* source, size_t num ); + +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +void *memset(void *str, char c, size_t num); + +// Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point). +char* strcpy( char* destination, char* source ); + +// Computes the length of the string str up to but not including the terminating null character. +size_t strlen(char *str); \ No newline at end of file diff --git a/src/main/kc/stdlib/time.c b/src/main/kc/include/time.h similarity index 62% rename from src/main/kc/stdlib/time.c rename to src/main/kc/include/time.h index b56ea9816..818b881a2 100644 --- a/src/main/kc/stdlib/time.c +++ b/src/main/kc/include/time.h @@ -1,8 +1,6 @@ // C standard library time.h // Functions to get and manipulate date and time information. -#include - // Type suitable for storing the processor time. typedef unsigned long clock_t; @@ -21,17 +19,8 @@ const unsigned long CLOCKS_PER_INIT = 0x12; // Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program). // This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start() -clock_t clock(void) { - return 0xffffffff - *CIA2_TIMER_AB; -} +clock_t clock(void); // Reset & start the processor clock time. The value can be read using clock(). // This uses CIA #2 Timer A+B on the C64 -void clock_start(void) { - // Setup CIA#2 timer A to count (down) CPU cycles - *CIA2_TIMER_A_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES; - *CIA2_TIMER_B_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A; - *CIA2_TIMER_AB = 0xffffffff; - *CIA2_TIMER_B_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A; - *CIA2_TIMER_A_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES; -} +void clock_start(void); diff --git a/src/main/kc/stdlib/atan2.c b/src/main/kc/lib/atan2.c similarity index 99% rename from src/main/kc/stdlib/atan2.c rename to src/main/kc/lib/atan2.c index 75f5af872..0d586dbf7 100644 --- a/src/main/kc/stdlib/atan2.c +++ b/src/main/kc/lib/atan2.c @@ -1,6 +1,8 @@ // Find atan2(x, y) using the CORDIC method // See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf +#include + // The number of iterations performed during 16-bit CORDIC atan2 calculation const byte CORDIC_ITERATIONS_16 = 15; diff --git a/src/main/kc/stdlib/basic-floats.c b/src/main/kc/lib/basic-floats.c similarity index 99% rename from src/main/kc/stdlib/basic-floats.c rename to src/main/kc/lib/basic-floats.c index 6165ea8ff..4aee3bd98 100644 --- a/src/main/kc/stdlib/basic-floats.c +++ b/src/main/kc/lib/basic-floats.c @@ -2,6 +2,8 @@ // See https://www.c64-wiki.com/wiki/Floating_point_arithmetic // See http://www.pagetable.com/c64rom/c64rom_sc.html +#include + // Zeropage addresses used to hold lo/hi-bytes of addresses of float numbers in MEM char* const memLo = 0xfe; char* const memHi = 0xff; diff --git a/src/main/kc/stdlib/bitmap-draw.c b/src/main/kc/lib/bitmap-draw.c similarity index 99% rename from src/main/kc/stdlib/bitmap-draw.c rename to src/main/kc/lib/bitmap-draw.c index 2941130a8..b2bf5377c 100644 --- a/src/main/kc/stdlib/bitmap-draw.c +++ b/src/main/kc/lib/bitmap-draw.c @@ -1,6 +1,8 @@ // Plot and line drawing routines for HIRES bitmaps // Currently it can only plot on the first 256 x-positions. +#include + // Tables for the plotter - initialized by calling bitmap_draw_init(); const byte bitmap_plot_xlo[256]; const byte bitmap_plot_xhi[256]; diff --git a/src/main/kc/stdlib/bitmap2.c b/src/main/kc/lib/bitmap2.c similarity index 98% rename from src/main/kc/stdlib/bitmap2.c rename to src/main/kc/lib/bitmap2.c index 59a5df268..62c71794c 100644 --- a/src/main/kc/stdlib/bitmap2.c +++ b/src/main/kc/lib/bitmap2.c @@ -1,5 +1,6 @@ // Simple single-color (320x200) bitmap routines -#include +#include +#include // The adddress of the bitmap screen (used for colors) byte* bitmap_screen; diff --git a/src/main/kc/lib/c64.c b/src/main/kc/lib/c64.c new file mode 100644 index 000000000..a84f75946 --- /dev/null +++ b/src/main/kc/lib/c64.c @@ -0,0 +1,27 @@ +// Commodore 64 Registers and Constants +#include + +// Get the value to store into D018 to display a specific screen and charset/bitmap +// Optimized for ASM from (byte)((((word)screen&$3fff)/$40)|(((word)charset&$3fff)/$400)); +inline char toD018(char* screen, char* gfx) { + return (>((((unsigned int)screen&$3fff)*4)))|(((>((unsigned int)gfx))/4)&$f); +} + +// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank +// Optimized for ASM from %00000011 ^ (byte)((word)gfx/$4000) +inline char toDd00(char* gfx) { + return %00000011 ^ (>((unsigned int)gfx))/$40; +} + +// Get the sprite pointer for a sprite. +// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (byte)(sprite_addr/64) +// The sprite pointers are stored SCREEN+$3f8+sprite_id to set the pointer of each sprite +inline char toSpritePtr(char* sprite) { + return (char)(((unsigned int)sprite)/$40); +} + +// Select a specific VIC graphics bank by setting the CIA 2 port A ($dd00) as needed +inline void vicSelectGfxBank(char* gfx) { + *CIA2_PORT_A_DDR = %00000011; + *CIA2_PORT_A = toDd00(gfx); +} diff --git a/src/main/kc/lib/c64dtv.c b/src/main/kc/lib/c64dtv.c new file mode 100644 index 000000000..ad8667c0c --- /dev/null +++ b/src/main/kc/lib/c64dtv.c @@ -0,0 +1,24 @@ +// C64 DTV version 2 Registers and Constants +// +// Sources +// (J) https://www.c64-wiki.com/wiki/C64DTV_Programming_Guide +// (H) http://dtvhacking.cbm8bit.com/dtv_wiki/images/d/d9/Dtv_registers_full.txt + +#include + +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx +void dtvSetCpuBankSegment1(byte cpuBankIdx) { + // Move CPU BANK 1 SEGMENT ($4000-$7fff) + byte* cpuBank = $ff; + *cpuBank = cpuBankIdx; + asm { + // SAC $dd - A register points to 13 BANK 1 segment + .byte $32, $dd + // LDA $ff - Set CPU BANK 1 SEGMENT ($4000-$7fff) to ($ff)*$4000 + lda $ff + // SAC $00 - A register points to 0 ACCUMULATOR + .byte $32, $00 + } +} diff --git a/src/main/kc/stdlib/division.c b/src/main/kc/lib/division.c similarity index 99% rename from src/main/kc/stdlib/division.c rename to src/main/kc/lib/division.c index 90a25362a..dddea7d8d 100644 --- a/src/main/kc/stdlib/division.c +++ b/src/main/kc/lib/division.c @@ -2,6 +2,8 @@ // Follows the C99 standard by truncating toward zero on negative results. // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 +#include + // Remainder after signed 8 bit division byte rem8u =0; diff --git a/src/main/kc/stdlib/fastmultiply.c b/src/main/kc/lib/fastmultiply.c similarity index 99% rename from src/main/kc/stdlib/fastmultiply.c rename to src/main/kc/lib/fastmultiply.c index 940209d8a..ddf3e4f77 100644 --- a/src/main/kc/stdlib/fastmultiply.c +++ b/src/main/kc/lib/fastmultiply.c @@ -2,6 +2,8 @@ // See http://codebase64.org/doku.php?id=base:seriously_fast_multiplication // Utilizes the fact that a*b = ((a+b)/2)^2 - ((a-b)/2)^2 +#include + // mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255). // - -// Keyboard Codes for all 63 keys. -// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7). -// See C64 Keyboard Matrix Reference http://codebase64.org/doku.php?id=base:reading_the_keyboard -const byte KEY_DEL = $00; -const byte KEY_RETURN = $01; -const byte KEY_CRSR_RIGHT = $02; -const byte KEY_F7 = $03; -const byte KEY_F1 = $04; -const byte KEY_F3 = $05; -const byte KEY_F5 = $06; -const byte KEY_CRSR_DOWN = $07; -const byte KEY_3 = $08; -const byte KEY_W = $09; -const byte KEY_A = $0a; -const byte KEY_4 = $0b; -const byte KEY_Z = $0c; -const byte KEY_S = $0d; -const byte KEY_E = $0e; -const byte KEY_LSHIFT = $0f; -const byte KEY_5 = $10; -const byte KEY_R = $11; -const byte KEY_D = $12; -const byte KEY_6 = $13; -const byte KEY_C = $14; -const byte KEY_F = $15; -const byte KEY_T = $16; -const byte KEY_X = $17; -const byte KEY_7 = $18; -const byte KEY_Y = $19; -const byte KEY_G = $1a; -const byte KEY_8 = $1b; -const byte KEY_B = $1c; -const byte KEY_H = $1d; -const byte KEY_U = $1e; -const byte KEY_V = $1f; -const byte KEY_9 = $20; -const byte KEY_I = $21; -const byte KEY_J = $22; -const byte KEY_0 = $23; -const byte KEY_M = $24; -const byte KEY_K = $25; -const byte KEY_O = $26; -const byte KEY_N = $27; -const byte KEY_PLUS = $28; -const byte KEY_P = $29; -const byte KEY_L = $2a; -const byte KEY_MINUS = $2b; -const byte KEY_DOT = $2c; -const byte KEY_COLON = $2d; -const byte KEY_AT = $2e; -const byte KEY_COMMA = $2f; -const byte KEY_POUND = $30; -const byte KEY_ASTERISK = $31; -const byte KEY_SEMICOLON = $32; -const byte KEY_HOME = $33; -const byte KEY_RSHIFT = $34; -const byte KEY_EQUALS = $35; -const byte KEY_ARROW_UP = $36; -const byte KEY_SLASH = $37; -const byte KEY_1 = $38; -const byte KEY_ARROW_LEFT = $39; -const byte KEY_CTRL = $3a; -const byte KEY_2 = $3b; -const byte KEY_SPACE = $3c; -const byte KEY_COMMODORE = $3d; -const byte KEY_Q = $3e; -const byte KEY_RUNSTOP = $3f; +#include +#include // Keycodes for each screen code character from $00-$3f. // Chars that do not have an unmodified keycode return $3f (representing RUN/STOP). diff --git a/src/main/kc/stdlib/limits.c b/src/main/kc/lib/limits.c similarity index 100% rename from src/main/kc/stdlib/limits.c rename to src/main/kc/lib/limits.c diff --git a/src/main/kc/stdlib/multiplexer.c b/src/main/kc/lib/multiplexer.c similarity index 99% rename from src/main/kc/stdlib/multiplexer.c rename to src/main/kc/lib/multiplexer.c index def002063..f19f7d641 100644 --- a/src/main/kc/stdlib/multiplexer.c +++ b/src/main/kc/lib/multiplexer.c @@ -12,7 +12,8 @@ // In practice a good method is to wait until the raster is beyond plexFreeNextYpos() and then call plexShowSprite(). Repeat until all 32 sprites have been shown. // TODO: Let the caller specify the number of sprites to use (or add PLEX_ENABLE[PLEX_COUNT]) -#include +#include +#include // The number of sprites in the multiplexer const char PLEX_COUNT = 32; diff --git a/src/main/kc/stdlib/multiply.c b/src/main/kc/lib/multiply.c similarity index 98% rename from src/main/kc/stdlib/multiply.c rename to src/main/kc/lib/multiply.c index 14445b25e..d6f989515 100644 --- a/src/main/kc/stdlib/multiply.c +++ b/src/main/kc/lib/multiply.c @@ -1,5 +1,7 @@ // Simple binary multiplication implementation +#include + // Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word word mul8u(byte a, byte b) { word res = 0; diff --git a/src/main/kc/stdlib/print.c b/src/main/kc/lib/print.c similarity index 99% rename from src/main/kc/stdlib/print.c rename to src/main/kc/lib/print.c index 03a52fed3..e704259ad 100644 --- a/src/main/kc/stdlib/print.c +++ b/src/main/kc/lib/print.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include byte* print_screen = $0400; byte* print_line_cursor = print_screen; diff --git a/src/main/kc/stdlib/sinus.c b/src/main/kc/lib/sinus.c similarity index 98% rename from src/main/kc/stdlib/sinus.c rename to src/main/kc/lib/sinus.c index 1fd409d71..5b2458e3a 100644 --- a/src/main/kc/stdlib/sinus.c +++ b/src/main/kc/lib/sinus.c @@ -4,8 +4,9 @@ // Uses the approximation sin(x) = x - x^/6 + x^/128 // Optimization possibility: Use symmetries when generating sinustables. wavelength%2==0 -> mirror symmetry over PI, wavelength%4==0 -> mirror symmetry over PI/2. -#include -#include +#include +#include +#include // PI*2 in u[4.28] format const dword PI2_u4f28 = $6487ed51; diff --git a/src/main/kc/stdlib/sqr.c b/src/main/kc/lib/sqr.c similarity index 96% rename from src/main/kc/stdlib/sqr.c rename to src/main/kc/lib/sqr.c index 179ec9e95..bc1f1f805 100644 --- a/src/main/kc/stdlib/sqr.c +++ b/src/main/kc/lib/sqr.c @@ -1,6 +1,7 @@ // Table-based implementation of integer square sqr() and square root sqrt() -#include +#include +#include // The number of squares to pre-calculate. Limits what values sqr() can calculate and the result of sqrt() byte NUM_SQUARES = 0xff; diff --git a/src/main/kc/stdlib/stdlib.c b/src/main/kc/lib/stdlib.c similarity index 98% rename from src/main/kc/stdlib/stdlib.c rename to src/main/kc/lib/stdlib.c index de59ea68d..fc2aab9a4 100644 --- a/src/main/kc/stdlib/stdlib.c +++ b/src/main/kc/lib/stdlib.c @@ -1,6 +1,7 @@ // C standard library stdlib.h // Implementation of functions found int C stdlib.h / stdlib.c -#include +#include +#include // Top of the heap used by malloc() unsigned char* HEAP_TOP = 0xa000; @@ -52,8 +53,6 @@ unsigned int* bsearch16u(unsigned int key, unsigned int* items, char num) { return *items<=key?items:items-1; } -// The different supported radix -enum RADIX { BINARY=2, OCTAL=8, DECIMAL=10, HEXADECIMAL=16 }; // The digits used for numbers char DIGITS[] = "0123456789abcdef"z; diff --git a/src/main/kc/stdlib/string.c b/src/main/kc/lib/string.c similarity index 98% rename from src/main/kc/stdlib/string.c rename to src/main/kc/lib/string.c index 8401ddf99..55f142742 100644 --- a/src/main/kc/stdlib/string.c +++ b/src/main/kc/lib/string.c @@ -1,7 +1,6 @@ // C standard library string.h // Functions to manipulate C strings and arrays. - -typedef word size_t ; +#include // Copy block of memory (forwards) // Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination. diff --git a/src/main/kc/lib/time.c b/src/main/kc/lib/time.c new file mode 100644 index 000000000..408035420 --- /dev/null +++ b/src/main/kc/lib/time.c @@ -0,0 +1,21 @@ +// C standard library time.h +// Functions to get and manipulate date and time information. +#include +#include + +// Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program). +// This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start() +clock_t clock(void) { + return 0xffffffff - *CIA2_TIMER_AB; +} + +// Reset & start the processor clock time. The value can be read using clock(). +// This uses CIA #2 Timer A+B on the C64 +void clock_start(void) { + // Setup CIA#2 timer A to count (down) CPU cycles + *CIA2_TIMER_A_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES; + *CIA2_TIMER_B_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A; + *CIA2_TIMER_AB = 0xffffffff; + *CIA2_TIMER_B_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A; + *CIA2_TIMER_A_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES; +} diff --git a/src/main/kc/stdlib/c64.c b/src/main/kc/stdlib/c64.c deleted file mode 100644 index 57711d62e..000000000 --- a/src/main/kc/stdlib/c64.c +++ /dev/null @@ -1,233 +0,0 @@ -// Commodore 64 Registers and Constants - -// Processor port data direction register -byte* const PROCPORT_DDR = $00; -// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written -const byte PROCPORT_DDR_MEMORY_MASK = %00000111; - -// Processor Port Register controlling RAM/ROM configuration and the datasette -byte* const PROCPORT = $01; -// RAM in all three areas $A000, $D000, $E000 -const byte PROCPORT_RAM_ALL = %00000000; -// RAM in $A000, $E000 I/O in $D000 -const byte PROCPORT_RAM_IO = %00000101; -// RAM in $A000, $E000 CHAR ROM in $D000 -const byte PROCPORT_RAM_CHARROM = %00000001; -// RAM in $A000, I/O in $D000, KERNEL in $E000 -const byte PROCPORT_KERNEL_IO = %00000110; -// BASIC in $A000, I/O in $D000, KERNEL in $E000 -const byte PROCPORT_BASIC_KERNEL_IO = %00000111; - -// The address of the CHARGEN character set -byte* const CHARGEN = $d000; - -// Positions of the border (in sprite positions) -const byte BORDER_XPOS_LEFT=24; -const word BORDER_XPOS_RIGHT=344; -const byte BORDER_YPOS_TOP=50; -const byte BORDER_YPOS_BOTTOM=250; - -// The offset of the sprite pointers from the screen start address -const word SPRITE_PTRS = $3f8; - -byte* const SPRITES_XPOS = $d000; -byte* const SPRITES_YPOS = $d001; -byte* const SPRITES_XMSB = $d010; -byte* const RASTER = $d012; -byte* const SPRITES_ENABLE = $d015; -byte* const SPRITES_EXPAND_Y = $d017; -byte* const SPRITES_PRIORITY = $d01b; -byte* const SPRITES_MC = $d01c; -byte* const SPRITES_EXPAND_X = $d01d; -byte* const BORDERCOL = $d020; -byte* const BGCOL = $d021; -byte* const BGCOL1 = $d021; -byte* const BGCOL2 = $d022; -byte* const BGCOL3 = $d023; -byte* const BGCOL4 = $d024; -byte* const SPRITES_MC1 = $d025; -byte* const SPRITES_MC2 = $d026; -byte* const SPRITES_COLS = $d027; - -byte* const VIC_CONTROL = $d011; -byte* const D011 = $d011; -const byte VIC_RST8 = %10000000; -const byte VIC_ECM = %01000000; -const byte VIC_BMM = %00100000; -const byte VIC_DEN = %00010000; -const byte VIC_RSEL = %00001000; - -byte* const VIC_CONTROL2 = $d016; -byte* const D016 = $d016; -const byte VIC_MCM = %00010000; -const byte VIC_CSEL = %00001000; - -byte* const D018 = $d018; -byte* const VIC_MEMORY = $d018; - -byte* const LIGHTPEN_X = $d013; -byte* const LIGHTPEN_Y = $d014; - -// VIC II IRQ Status Register -byte* const IRQ_STATUS = $d019; -// VIC II IRQ Enable Register -byte* const IRQ_ENABLE = $d01a; -// Bits for the IRQ Status/Enable Registers -const byte IRQ_RASTER = %00000001; -const byte IRQ_COLLISION_BG = %00000010; -const byte IRQ_COLLISION_SPRITE = %00000100; -const byte IRQ_LIGHTPEN = %00001000; - -// Color Ram -byte* const COLS = $d800; - -// CIA#1 Port A: keyboard matrix columns and joystick #2 -byte* const CIA1_PORT_A = $dc00; -// CIA#1 Port B: keyboard matrix rows and joystick #1. -byte* const CIA1_PORT_B = $dc01; -// CIA #1 Port A data direction register. -byte* const CIA1_PORT_A_DDR = $dc02; -// CIA #1 Port B data direction register. -byte* const CIA1_PORT_B_DDR = $dc03; -// CIA #1 Timer A Value -word* const CIA1_TIMER_A = $dc04; -// CIA #1 Timer B Value -word* const CIA1_TIMER_B = $dc06; -// CIA #1 Time-of-day real-time-clock tenth seconds (BCD) -byte* const CIA1_TOD_10THS = $dc08; -// CIA #1 Time-of-day real-time-clock seconds (BCD) -byte* const CIA1_TOD_SEC = $dc09; -// CIA #1 Time-of-day real-time-clock minutes (BCD) -byte* const CIA1_TOD_MIN = $dc0a; -// CIA #1 Time-of-day real-time-clock hours (BCD) -byte* const CIA1_TOD_HOURS = $dc0b; -// CIA #1 Serial Shift Register -byte* const CIA1_SERIAL_SHIFT_OUT = $dc0c; -// CIA#1 Interrupt Status & Control Register -byte* const CIA1_INTERRUPT = $dc0d; -// CIA#1 Timer A Control Register -byte* const CIA1_TIMER_A_CONTROL = $dc0e; -// CIA#1 Timer B Control Register -byte* const CIA1_TIMER_B_CONTROL = $dc0f; - -// CIA#2 Port A: Serial bus, RS-232, VIC memory bank -byte* const CIA2_PORT_A = $dd00; -// CIA#2 Port B: RS-232 -byte* const CIA2_PORT_B = $dd01; -// CIA #2 Port A data direction register. -byte* const CIA2_PORT_A_DDR = $dd02; -// CIA #2 Port B data direction register. -byte* const CIA2_PORT_B_DDR = $dd03; -// CIA #2 Timer A+B Value (32-bit) -dword* const CIA2_TIMER_AB = $dd04; -// CIA #2 Timer A Value (16-bit) -word* const CIA2_TIMER_A = $dd04; -// CIA #2 Timer B Value (16-bit) -word* const CIA2_TIMER_B = $dd06; -// CIA #2 Time-of-day real-time-clock tenth seconds (BCD) -byte* const CIA2_TOD_10THS = $dd08; -// CIA #2 Time-of-day real-time-clock seconds (BCD) -byte* const CIA2_TOD_SEC = $dd09; -// CIA #2 Time-of-day real-time-clock minutes (BCD) -byte* const CIA2_TOD_MIN = $dd0a; -// CIA #2 Time-of-day real-time-clock hours (BCD) -byte* const CIA2_TOD_HOURS = $dd0b; -// CIA #2 Serial Shift Register -byte* const CIA2_SERIAL_SHIFT_OUT = $dd0c; -// CIA #2 Interrupt Status & Control Register -byte* const CIA2_INTERRUPT = $dd0d; -// CIA #2 Timer A Control Register -byte* const CIA2_TIMER_A_CONTROL = $dd0e; -// CIA #2 Timer B Control Register -byte* const CIA2_TIMER_B_CONTROL = $dd0f; - -// Value that disables all CIA interrupts when stored to the CIA Interrupt registers -const byte CIA_INTERRUPT_CLEAR = $7f; - -// Timer Control - Start/stop timer (0:stop, 1: start) -const byte CIA_TIMER_CONTROL_STOP = 0b00000000; -// Timer Control - Start/stop timer (0:stop, 1: start) -const byte CIA_TIMER_CONTROL_START = 0b00000001; -// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT) -const byte CIA_TIMER_CONTROL_CONTINUOUS = 0b00000000; -// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT) -const byte CIA_TIMER_CONTROL_ONESHOT = 0b00001000; -// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses) -const byte CIA_TIMER_CONTROL_A_COUNT_CYCLES = 0b00000000; -// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses) -const byte CIA_TIMER_CONTROL_A_COUNT_CNT = 0b00100000; -// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output) -const byte CIA_TIMER_CONTROL_A_SERIAL_IN = 0b00000000; -// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output) -const byte CIA_TIMER_CONTROL_A_SERIAL_OUT = 0b01000000; -// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz) -const byte CIA_TIMER_CONTROL_A_TOD_60HZ = 0b00000000; -// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz) -const byte CIA_TIMER_CONTROL_A_TOD_50HZ = 0b10000000; -// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) -const byte CIA_TIMER_CONTROL_B_COUNT_CYCLES = 0b00000000; -// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) -const byte CIA_TIMER_CONTROL_B_COUNT_CNT = 0b00100000; -// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) -const byte CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = 0b01000000; -// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) -const byte CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A_CNT = 0b01100000; -// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm) -const byte CIA_TIMER_CONTROL_B_TOD_CLOCK_SET = 0b00000000; -// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm) -const byte CIA_TIMER_CONTROL_B_TOD_ALARM_SET = 0b10000000; - -// The vector used when the KERNAL serves IRQ interrupts -void()** const KERNEL_IRQ = $0314; -// The vector used when the KERNAL serves NMI interrupts -void()** const KERNEL_NMI = $0318; - -// The vector used when the HARDWARE serves IRQ interrupts -void()** const HARDWARE_IRQ = $fffe; - -// The SID volume -byte* const SID_VOLUME = $d418; - - -// The colors of the C64 -const byte BLACK = $0; -const byte WHITE = $1; -const byte RED = $2; -const byte CYAN = $3; -const byte PURPLE = $4; -const byte GREEN = $5; -const byte BLUE = $6; -const byte YELLOW = $7; -const byte ORANGE = $8; -const byte BROWN = $9; -const byte PINK = $a; -const byte DARK_GREY= $b; -const byte GREY = $c; -const byte LIGHT_GREEN = $d; -const byte LIGHT_BLUE = $e; -const byte LIGHT_GREY = $f; - -// Get the value to store into D018 to display a specific screen and charset/bitmap -// Optimized for ASM from (byte)((((word)screen&$3fff)/$40)|(((word)charset&$3fff)/$400)); -inline byte toD018(byte* screen, byte* gfx) { - return (>((((word)screen&$3fff)*4)))|(((>((word)gfx))/4)&$f); -} - -// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank -// Optimized for ASM from %00000011 ^ (byte)((word)gfx/$4000) -inline byte toDd00(byte* gfx) { - return %00000011 ^ (>((word)gfx))/$40; -} - -// Get the sprite pointer for a sprite. -// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (byte)(sprite_addr/64) -// The sprite pointers are stored SCREEN+$3f8+sprite_id to set the pointer of each sprite -inline byte toSpritePtr(byte* sprite) { - return (byte)(((word)sprite)/$40); -} - -// Select a specific VIC graphics bank by setting the CIA 2 port A ($dd00) as needed -inline void vicSelectGfxBank(byte* gfx) { - *CIA2_PORT_A_DDR = %00000011; - *CIA2_PORT_A = toDd00(gfx); -} diff --git a/src/main/script/kickc.bat b/src/main/script/kickc.bat index fae05dde0..d56ea1112 100644 --- a/src/main/script/kickc.bat +++ b/src/main/script/kickc.bat @@ -4,7 +4,8 @@ REM KICKC HOME set KICKC_HOME=%~dp0.. echo KICKC_HOME=%KICKC_HOME% REM KCLIB HOME -set KICKCLIB_HOME=%KICKC_HOME%\stdlib +set KICKC_STDLIB=%KICKC_HOME%\lib +set KICKC_STDINCLUDE=%KICKC_HOME%\include echo KICKCLIB_HOME=%KICKCLIB_HOME% set KICKC_FRAGMENT_HOME=%KICKC_HOME%\fragment echo KICKC_FRAGMENT_HOME=%KICKC_FRAGMENT_HOME% @@ -14,5 +15,5 @@ REM KICKC_JAR for %%I in ( %KICKC_HOME%\lib\kickc-*.jar ) do set KICKC_JAR=%%I echo KICKC_JAR=%KICKC_JAR% -echo java -jar %KICKC_JAR% -I %KICKCLIB_HOME% -F %KICKC_FRAGMENT_HOME% %* -java -jar %KICKC_JAR% -I %KICKCLIB_HOME% -F %KICKC_FRAGMENT_HOME% %* \ No newline at end of file +echo java -jar %KICKC_JAR% -I %KICKC_STDINCLUDE% -L %KICKC_STDLIB% -F %KICKC_FRAGMENT_HOME% %* +java -jar %KICKC_JAR% -I %KICKC_STDINCLUDE% -L %KICKC_STDLIB% -F %KICKC_FRAGMENT_HOME% %* \ No newline at end of file diff --git a/src/main/script/kickc.sh b/src/main/script/kickc.sh index 2a92082f8..7ffc05fca 100755 --- a/src/main/script/kickc.sh +++ b/src/main/script/kickc.sh @@ -3,8 +3,10 @@ # JAVA HOME # KICKC HOME export KICKC_HOME="$(dirname $0)/.." -# KCLIB HOME -export KICKC_STDLIB_HOME="$KICKC_HOME/stdlib" +# STANDARD INCLUDE +export KICKC_STD_INCLUDE="$KICKC_HOME/include" +# STANDARD LIBRARY +export KICKC_STD_LIB="$KICKC_HOME/lib" # FRAGMENTS HOME export KICKC_FRAGMENT_HOME="$KICKC_HOME/fragment" # KICKASSEMBLER HOME @@ -19,5 +21,5 @@ while [[ "$#" -gt 0 ]]; do case $1 in *) export PARAM="$PARAM $1"; shift;; esac; done -echo java -jar $KICKC_JAR -F $KICKC_FRAGMENT_HOME $PARAM -I $KICKC_STDLIB_HOME -java -jar $KICKC_JAR -F $KICKC_FRAGMENT_HOME $PARAM -I $KICKC_STDLIB_HOME \ No newline at end of file +echo java -jar $KICKC_JAR -F $KICKC_FRAGMENT_HOME $PARAM -I $KICKC_STD_INCLUDE -L $KICKC_STD_LIB +java -jar $KICKC_JAR -F $KICKC_FRAGMENT_HOME $PARAM -I $KICKC_STD_INCLUDE -L $KICKC_STD_LIB \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 107d9c712..c5aadfac9 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -32,13 +32,19 @@ import static org.junit.Assert.assertTrue; */ public class TestPrograms { - final String stdlibPath = "src/main/kc/stdlib"; + final String stdIncludePath = "src/main/kc/include"; + final String stdLibPath = "src/main/kc/lib"; final String testPath = "src/test/kc"; final String refPath = "src/test/ref/"; public TestPrograms() { } + @Test + public void testIncludes3() throws IOException, URISyntaxException { + compileAndCompare("complex/includes/includes-3.c"); + } + @Test public void testIncludes2() throws IOException, URISyntaxException { compileAndCompare("complex/includes/includes-2.c"); @@ -4023,8 +4029,9 @@ public class TestPrograms { if(compileLog != null) { compiler.setLog(compileLog); } - compiler.addImportPath(stdlibPath); - compiler.addImportPath(testPath); + compiler.addIncludePath(stdIncludePath); + compiler.addIncludePath(testPath); + compiler.addLibraryPath(stdLibPath); compiler.initAsmFragmentSynthesizer(asmFragmentSynthesizer); if(upliftCombinations != null) { compiler.setUpliftCombinations(upliftCombinations); diff --git a/src/test/kc/bitmap-circle-2.c b/src/test/kc/bitmap-circle-2.c index 40431cecc..7ef437abd 100644 --- a/src/test/kc/bitmap-circle-2.c +++ b/src/test/kc/bitmap-circle-2.c @@ -1,4 +1,4 @@ -#include +#include byte* const SCREEN = $400; byte* const BITMAP = $2000; diff --git a/src/test/kc/bitmap-circle.c b/src/test/kc/bitmap-circle.c index 6dde3ea92..30a60b95c 100644 --- a/src/test/kc/bitmap-circle.c +++ b/src/test/kc/bitmap-circle.c @@ -2,7 +2,7 @@ // Coded by Richard-William Loerakker // Original Source https://bcaorganizer.blogspot.com/p/c-program-for_21.html?fbclid=IwAR0iL8pYcCqhCPa6LmtQ9qej-YonYVepY2cBegYRIWO0l8RPeOnTVniMAac -#include +#include byte* const SCREEN = $400; byte* const BITMAP = $2000; diff --git a/src/test/kc/bitmap-line-anim-1.c b/src/test/kc/bitmap-line-anim-1.c index 3e9bc09f3..2f71457bb 100644 --- a/src/test/kc/bitmap-line-anim-1.c +++ b/src/test/kc/bitmap-line-anim-1.c @@ -1,8 +1,8 @@ // Illustrates problem with bitmap-draw.kc line() // Reported by Janne Johansson -#include -#include +#include +#include byte* const SCREEN = $400; byte* const BITMAP = $2000; diff --git a/src/test/kc/bitmap-line-anim-2.c b/src/test/kc/bitmap-line-anim-2.c index bfb35ef73..007fb71ef 100644 --- a/src/test/kc/bitmap-line-anim-2.c +++ b/src/test/kc/bitmap-line-anim-2.c @@ -1,8 +1,8 @@ // Shows that bitmap2.kc line() does not have the same problem as bitmap-draw.kc // See bitmap-line-anim-1.kc -#include -#include +#include +#include byte* const SCREEN = $400; byte* const BITMAP = $2000; diff --git a/src/test/kc/bitmap-plot-0.c b/src/test/kc/bitmap-plot-0.c index 7c5b11d97..373842c0b 100644 --- a/src/test/kc/bitmap-plot-0.c +++ b/src/test/kc/bitmap-plot-0.c @@ -1,7 +1,7 @@ // Tests the simple bitmap plotter - and counts plots per frame in an IRQ // Plots simple plots -#include -#include +#include +#include byte* BITMAP = 0x2000; byte* SCREEN = 0x0400; diff --git a/src/test/kc/bitmap-plot-1.c b/src/test/kc/bitmap-plot-1.c index bca257b4a..4b514a047 100644 --- a/src/test/kc/bitmap-plot-1.c +++ b/src/test/kc/bitmap-plot-1.c @@ -1,9 +1,9 @@ // Tests the simple bitmap plotter - and counts plots per frame in an IRQ // Plots a fullscreen elipsis -#include -#include -#include -#include +#include +#include +#include +#include byte* BITMAP = 0x2000; byte* SCREEN = 0x0400; diff --git a/src/test/kc/bitmap-plot-2.c b/src/test/kc/bitmap-plot-2.c index 40630d1fa..af037d068 100644 --- a/src/test/kc/bitmap-plot-2.c +++ b/src/test/kc/bitmap-plot-2.c @@ -1,9 +1,9 @@ // Tests the simple bitmap plotter - and counts plots per frame in an IRQ // Plots a spiral -#include -#include -#include -#include +#include +#include +#include +#include byte* BITMAP = 0x2000; byte* SCREEN = 0x0400; diff --git a/src/test/kc/bitmap-plot-3.c b/src/test/kc/bitmap-plot-3.c index 9241187de..06549a91d 100644 --- a/src/test/kc/bitmap-plot-3.c +++ b/src/test/kc/bitmap-plot-3.c @@ -1,8 +1,8 @@ // Tests the simple bitmap plotter // Plots a few lines using the bresenham line algorithm -#include -#include -#include +#include +#include +#include byte* BITMAP = 0x2000; byte* SCREEN = 0x0400; diff --git a/src/test/kc/c-types.c b/src/test/kc/c-types.c index 28b48e793..be7b94126 100644 --- a/src/test/kc/c-types.c +++ b/src/test/kc/c-types.c @@ -1,6 +1,6 @@ // Tests the different standard C types -#include +#include void main() { print_cls(); diff --git a/src/test/kc/c64dtv-8bppcharstretch.c b/src/test/kc/c64dtv-8bppcharstretch.c index 2d1521bf8..009d3aa23 100644 --- a/src/test/kc/c64dtv-8bppcharstretch.c +++ b/src/test/kc/c64dtv-8bppcharstretch.c @@ -1,5 +1,5 @@ // C64DTV 8bpp charmode stretcher -#include +#include // Plane with the screen byte* const SCREEN = $7c00; diff --git a/src/test/kc/c64dtv-8bppchunkystretch.c b/src/test/kc/c64dtv-8bppchunkystretch.c index eda585af1..8d13989b1 100644 --- a/src/test/kc/c64dtv-8bppchunkystretch.c +++ b/src/test/kc/c64dtv-8bppchunkystretch.c @@ -1,5 +1,5 @@ // C64DTV 8bpp charmode stretcher -#include +#include // Plane with all pixels byte* const CHUNKY = $8000; diff --git a/src/test/kc/c64dtv-blitter-box.c b/src/test/kc/c64dtv-blitter-box.c index 991c0145f..ca3c4486a 100644 --- a/src/test/kc/c64dtv-blitter-box.c +++ b/src/test/kc/c64dtv-blitter-box.c @@ -1,6 +1,6 @@ // Fill a box on the screen using the blitter -#include +#include byte* const SCREEN = $400; const byte SRCA[] = "camelot rules!"; diff --git a/src/test/kc/c64dtv-blittermin.c b/src/test/kc/c64dtv-blittermin.c index 04b281275..fae896716 100644 --- a/src/test/kc/c64dtv-blittermin.c +++ b/src/test/kc/c64dtv-blittermin.c @@ -1,4 +1,4 @@ -#include +#include byte* const SCREEN = $400; const byte SRCA[] = { 'c', 'a', 'm', 'e', 'l', 'o', 't', '!', ' '}; diff --git a/src/test/kc/c64dtv-color.c b/src/test/kc/c64dtv-color.c index 68d1e14fc..d9d46fadf 100644 --- a/src/test/kc/c64dtv-color.c +++ b/src/test/kc/c64dtv-color.c @@ -1,6 +1,6 @@ // Test C64DTV v2 256-colors and the 16-color redefinable palette -#include +#include void main() { asm { sei } diff --git a/src/test/kc/c64dtv-gfxexplorer.c b/src/test/kc/c64dtv-gfxexplorer.c index 1e5844f4a..b771629c7 100644 --- a/src/test/kc/c64dtv-gfxexplorer.c +++ b/src/test/kc/c64dtv-gfxexplorer.c @@ -1,8 +1,8 @@ // Interactive Explorer for C64DTV Screen Modes -#include -#include -#include -#include +#include +#include +#include +#include void main() { asm { sei } // Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal) diff --git a/src/test/kc/c64dtv-gfxmodes.c b/src/test/kc/c64dtv-gfxmodes.c index cac760227..37d6ba012 100644 --- a/src/test/kc/c64dtv-gfxmodes.c +++ b/src/test/kc/c64dtv-gfxmodes.c @@ -1,8 +1,8 @@ // Exploring C64DTV Screen Modes -#include -#include -#include -#include +#include +#include +#include +#include void main() { asm { sei } // Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal) diff --git a/src/test/kc/cia-timer-cyclecount.c b/src/test/kc/cia-timer-cyclecount.c index 648e7b479..9773a40a9 100644 --- a/src/test/kc/cia-timer-cyclecount.c +++ b/src/test/kc/cia-timer-cyclecount.c @@ -1,8 +1,8 @@ // Counting cycles using a CIA timer -#include -#include -#include +#include +#include +#include byte* const SCREEN = 0x0400; diff --git a/src/test/kc/cia-timer-simple.c b/src/test/kc/cia-timer-simple.c index bf847c8c9..30b62c339 100644 --- a/src/test/kc/cia-timer-simple.c +++ b/src/test/kc/cia-timer-simple.c @@ -1,8 +1,8 @@ // Setup and run a simple CIA-timer -#include -#include -#include +#include +#include +#include byte* const SCREEN = 0x0400; diff --git a/src/test/kc/complex/clearscreen/clearscreen.c b/src/test/kc/complex/clearscreen/clearscreen.c index e59b203db..b97af5680 100644 --- a/src/test/kc/complex/clearscreen/clearscreen.c +++ b/src/test/kc/complex/clearscreen/clearscreen.c @@ -1,9 +1,9 @@ // Clears start screen throwing around the letters (by turning them into sprites) -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include // Generate debug code (raster time usage etc.) const bool DEBUG = false; diff --git a/src/test/kc/complex/includes/includes-1.c b/src/test/kc/complex/includes/includes-1.c index 22aa2e3b6..3aa939fec 100644 --- a/src/test/kc/complex/includes/includes-1.c +++ b/src/test/kc/complex/includes/includes-1.c @@ -1,6 +1,6 @@ // Includes a system library - ignores the local file with the same name -#include +#include char* STR = "camelot!"; diff --git a/src/test/kc/complex/includes/includes-3.c b/src/test/kc/complex/includes/includes-3.c new file mode 100644 index 000000000..94c5cc336 --- /dev/null +++ b/src/test/kc/complex/includes/includes-3.c @@ -0,0 +1,14 @@ +// A file using a library + +#include "lib.h" + +const char* SCREEN = 0x0400; + +void main() { + + char i = 0; + SCREEN[i++] = value; + value = 'x'; + SCREEN[i++] = value; + +} \ No newline at end of file diff --git a/src/test/kc/complex/includes/lib.c b/src/test/kc/complex/includes/lib.c new file mode 100644 index 000000000..00bc67397 --- /dev/null +++ b/src/test/kc/complex/includes/lib.c @@ -0,0 +1,6 @@ +// The library containing the char value definition + +#include "lib.h" + +// The char value +char value = 'a'; diff --git a/src/test/kc/complex/includes/lib.h b/src/test/kc/complex/includes/lib.h new file mode 100644 index 000000000..00a24e5c4 --- /dev/null +++ b/src/test/kc/complex/includes/lib.h @@ -0,0 +1,4 @@ +// Library declaring a char value + +// The char value +extern char value; diff --git a/src/test/kc/complex/medusa/medusa.c b/src/test/kc/complex/medusa/medusa.c index 507795f53..3341bf65c 100644 --- a/src/test/kc/complex/medusa/medusa.c +++ b/src/test/kc/complex/medusa/medusa.c @@ -1,8 +1,8 @@ // Display MEDUSA PETSCII by Buzz_clik // https://csdb.dk/release/?id=178673 -#include -#include +#include +#include char MEDUSA_SCREEN[1000] = kickasm(resource "medusas.prg" ) {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) diff --git a/src/test/kc/complex/prebob/grid-bobs.c b/src/test/kc/complex/prebob/grid-bobs.c index 4a4f3ba6e..0f69a3ba8 100644 --- a/src/test/kc/complex/prebob/grid-bobs.c +++ b/src/test/kc/complex/prebob/grid-bobs.c @@ -1,10 +1,10 @@ // Pre-calculated bobs inside a charset (pre-moved to all x/y-combinations) -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include // The prototype BOB (a 3x3 char image with a bob image in the upper 2x2 chars) // The chars are layout as follows with data in chars 0, 1, 3, 4 initially diff --git a/src/test/kc/complex/prebob/vogel-bobs.c b/src/test/kc/complex/prebob/vogel-bobs.c index 4ae5beca8..7b79f8a04 100644 --- a/src/test/kc/complex/prebob/vogel-bobs.c +++ b/src/test/kc/complex/prebob/vogel-bobs.c @@ -1,10 +1,10 @@ // Pre-calculated bobs inside a charset (pre-moved to all x/y-combinations) -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include // The prototype BOB (a 3x3 char image with a bob image in the upper 2x2 chars) // The chars are layout as follows with data in chars 0, 1, 3, 4 initially diff --git a/src/test/kc/complex/prebob/vogel-sprites.c b/src/test/kc/complex/prebob/vogel-sprites.c index 82cfb0843..63177ab89 100644 --- a/src/test/kc/complex/prebob/vogel-sprites.c +++ b/src/test/kc/complex/prebob/vogel-sprites.c @@ -1,9 +1,9 @@ // Same animation using a multiplexer -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include // The BOB sprite align(0x1000) char SPRITE[] = kickasm(resource "smiley.png") {{ diff --git a/src/test/kc/complex/splines/truetype-splines.c b/src/test/kc/complex/splines/truetype-splines.c index d2ee2dfe9..46e3d232a 100644 --- a/src/test/kc/complex/splines/truetype-splines.c +++ b/src/test/kc/complex/splines/truetype-splines.c @@ -1,11 +1,11 @@ // Show a few simple splines using the splines library #include "splines.c" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include char* const PRINT_SCREEN = 0x0400; char* const BITMAP_SCREEN = 0x5c00; diff --git a/src/test/kc/complex/spritescroller/spritescroller.c b/src/test/kc/complex/spritescroller/spritescroller.c index 1c7932d71..5cdb9472d 100644 --- a/src/test/kc/complex/spritescroller/spritescroller.c +++ b/src/test/kc/complex/spritescroller/spritescroller.c @@ -1,6 +1,6 @@ // Put a 2x2 font into sprites and show it on screen -#include -#include +#include +#include char * const CHARSET_DEFAULT = 0x1000; char * const SPRITES = 0x3000; diff --git a/src/test/kc/complex/tetris/tetris-sprites.c b/src/test/kc/complex/tetris/tetris-sprites.c index bd10a327b..5873c91ea 100644 --- a/src/test/kc/complex/tetris/tetris-sprites.c +++ b/src/test/kc/complex/tetris/tetris-sprites.c @@ -1,6 +1,6 @@ // Tetris Game for the Commodore 64 // A sprite multiplexer covering the playfield with a black layer to allow for 3 single-pixel colors -#include +#include #include "tetris-data.c" kickasm(pc PLAYFIELD_SPRITES, resource "playfield-sprites.png") {{ diff --git a/src/test/kc/complex/tetris/tetris.c b/src/test/kc/complex/tetris/tetris.c index 7bb50c89e..394b5883f 100644 --- a/src/test/kc/complex/tetris/tetris.c +++ b/src/test/kc/complex/tetris/tetris.c @@ -2,8 +2,8 @@ // The tetris game tries to match NES tetris gameplay pretty closely // Source: https://meatfighter.com/nintendotetrisai/ -#include -#include +#include +#include #include "sid.c" #include "tetris-data.c" #include "tetris-render.c" diff --git a/src/test/kc/complex/travis/game-orig.c b/src/test/kc/complex/travis/game-orig.c index ca71dad4a..0e6cb3aca 100644 --- a/src/test/kc/complex/travis/game-orig.c +++ b/src/test/kc/complex/travis/game-orig.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include byte* SCREEN = $0400; diff --git a/src/test/kc/complex/xmega65/xmega65.c b/src/test/kc/complex/xmega65/xmega65.c index 2a881dcd0..31fc9aa7e 100644 --- a/src/test/kc/complex/xmega65/xmega65.c +++ b/src/test/kc/complex/xmega65/xmega65.c @@ -2,7 +2,7 @@ // Each function of the kernal is a no-args function // The functions are placed in the SYSCALLS table surrounded by JMP and NOP -#include +#include #pragma link("xmega65.ld") diff --git a/src/test/kc/constants.c b/src/test/kc/constants.c index fefbf9a2d..5713bf0c9 100644 --- a/src/test/kc/constants.c +++ b/src/test/kc/constants.c @@ -1,4 +1,4 @@ -#include +#include byte* const BGCOL = $d021; const byte GREEN = 5; const byte RED = 2 ; diff --git a/src/test/kc/cordic-atan2-16-ref.c b/src/test/kc/cordic-atan2-16-ref.c index 3fc1fa3d5..eacbec8bd 100644 --- a/src/test/kc/cordic-atan2-16-ref.c +++ b/src/test/kc/cordic-atan2-16-ref.c @@ -2,9 +2,9 @@ // See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf #include "font-hex.c" -#include -#include -#include +#include +#include +#include byte* const CHARSET = 0x2000; byte* const SCREEN = 0x2800; diff --git a/src/test/kc/cordic-atan2-16.c b/src/test/kc/cordic-atan2-16.c index 84df819d8..4e2185fc3 100644 --- a/src/test/kc/cordic-atan2-16.c +++ b/src/test/kc/cordic-atan2-16.c @@ -2,8 +2,8 @@ // See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf #include "font-hex.c" -#include -#include +#include +#include byte* const CHARSET = 0x2000; byte* const SCREEN = 0x2800; diff --git a/src/test/kc/cordic-atan2-clear.c b/src/test/kc/cordic-atan2-clear.c index 4717f4e7c..893fdc653 100644 --- a/src/test/kc/cordic-atan2-clear.c +++ b/src/test/kc/cordic-atan2-clear.c @@ -1,8 +1,8 @@ // Find atan2(x, y) using the CORDIC method // See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf #include "font-hex.c" -#include -#include +#include +#include byte* const CHARSET = 0x2000; byte* const SCREEN = 0x2800; diff --git a/src/test/kc/cordic-atan2.c b/src/test/kc/cordic-atan2.c index a54266a8f..91b4d8092 100644 --- a/src/test/kc/cordic-atan2.c +++ b/src/test/kc/cordic-atan2.c @@ -2,8 +2,8 @@ // See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf #include "font-hex.c" -#include -#include +#include +#include byte* const CHARSET = 0x2000; diff --git a/src/test/kc/cstyle-decl-var-missing.c b/src/test/kc/cstyle-decl-var-missing.c index 489a37b14..06bc598dc 100644 --- a/src/test/kc/cstyle-decl-var-missing.c +++ b/src/test/kc/cstyle-decl-var-missing.c @@ -2,7 +2,7 @@ // Missing definition // The definition -extern char * const SCREEN = 0x0400; +extern char * const SCREEN; //Second definition char idx; diff --git a/src/test/kc/danny-joystick-problem.c b/src/test/kc/danny-joystick-problem.c index e5cd0b81c..ecbd1271f 100644 --- a/src/test/kc/danny-joystick-problem.c +++ b/src/test/kc/danny-joystick-problem.c @@ -1,7 +1,7 @@ // Tests problem writing/reading joystick encountered by Danny Spijksma // https://www.protovision.games/hardw/build4player.php?language=en&fbclid=IwAR1MJLgQjOU0zVa0ax2aNeGa-xVbE9IGY9zC6b6eInTV4HQzoUAoCPoXu14 -#include +#include char* const SCREEN = 0x0400; void main() { (*CIA2_PORT_B) &= 0x7f; diff --git a/src/test/kc/default-font.c b/src/test/kc/default-font.c index a6d3a4200..3323868a1 100644 --- a/src/test/kc/default-font.c +++ b/src/test/kc/default-font.c @@ -1,6 +1,6 @@ // Show default font on screen -#include +#include byte* SCREEN = 0x0400; diff --git a/src/test/kc/euclid-3.c b/src/test/kc/euclid-3.c index 196e9f080..11d15239d 100644 --- a/src/test/kc/euclid-3.c +++ b/src/test/kc/euclid-3.c @@ -4,7 +4,7 @@ * Based on facebook post from */ -#include +#include void main () { print_cls(); diff --git a/src/test/kc/examples/3d/3d.c b/src/test/kc/examples/3d/3d.c index da885fbd4..a5d761dd2 100644 --- a/src/test/kc/examples/3d/3d.c +++ b/src/test/kc/examples/3d/3d.c @@ -2,8 +2,8 @@ // Based on: // - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt // - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation -#include -#include +#include +#include // The rotated point - updated by calling rotate_matrix() signed char* xr = $f0; diff --git a/src/test/kc/examples/3d/perspective.c b/src/test/kc/examples/3d/perspective.c index cc9ffe71e..074209eaf 100644 --- a/src/test/kc/examples/3d/perspective.c +++ b/src/test/kc/examples/3d/perspective.c @@ -2,8 +2,8 @@ // Based on: // - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt // - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation -#include -#include +#include +#include // The rotated point - updated by calling rotate() signed char* xr = $f0; diff --git a/src/test/kc/examples/bresenham/bitmap-bresenham.c b/src/test/kc/examples/bresenham/bitmap-bresenham.c index 8a5316764..352a4ec66 100644 --- a/src/test/kc/examples/bresenham/bitmap-bresenham.c +++ b/src/test/kc/examples/bresenham/bitmap-bresenham.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include char* const SCREEN = $400; char* const BITMAP = $2000; diff --git a/src/test/kc/examples/chargen/chargen-analysis.c b/src/test/kc/examples/chargen/chargen-analysis.c index 336b8974e..02172c06c 100644 --- a/src/test/kc/examples/chargen/chargen-analysis.c +++ b/src/test/kc/examples/chargen/chargen-analysis.c @@ -1,6 +1,6 @@ // Allows analysis of the CHARGEN ROM font -#include -#include +#include +#include char* SCREEN = $400; diff --git a/src/test/kc/examples/fastmultiply/fastmultiply8.c b/src/test/kc/examples/fastmultiply/fastmultiply8.c index bedd4f662..33e9bccd2 100644 --- a/src/test/kc/examples/fastmultiply/fastmultiply8.c +++ b/src/test/kc/examples/fastmultiply/fastmultiply8.c @@ -6,7 +6,7 @@ // - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication // - http://codebase64.org/doku.php?id=magazines:chacking16 -#include +#include signed char vals[] = {-95, -64, -32, -16, 0, 16, 32, 64, 95}; diff --git a/src/test/kc/examples/fire/fire.c b/src/test/kc/examples/fire/fire.c index c8d6fe31f..90720fb62 100644 --- a/src/test/kc/examples/fire/fire.c +++ b/src/test/kc/examples/fire/fire.c @@ -4,7 +4,7 @@ // Ported to KickC by Jesper Gravgaard. // Original source https://github.com/cc65/cc65/blob/master/samples/fire.c -#include +#include #include "sid.c" unsigned char* SCREEN1 = 0x3800; diff --git a/src/test/kc/examples/font-2x2/font-2x2.c b/src/test/kc/examples/font-2x2/font-2x2.c index 4c3524ead..703249217 100644 --- a/src/test/kc/examples/font-2x2/font-2x2.c +++ b/src/test/kc/examples/font-2x2/font-2x2.c @@ -1,7 +1,7 @@ // Creates a 2x2 font from the system CHARGEN font and compress it by identifying identical chars -#include -#include +#include +#include char* const SCREEN = 0x0400; char* const FONT_ORIGINAL = 0x2000; diff --git a/src/test/kc/examples/helloworld/helloworld.c b/src/test/kc/examples/helloworld/helloworld.c index 9b46450d0..d9b46d0cd 100644 --- a/src/test/kc/examples/helloworld/helloworld.c +++ b/src/test/kc/examples/helloworld/helloworld.c @@ -1,4 +1,5 @@ -#include +#include + void main() { print_str("hello world!"); print_ln(); diff --git a/src/test/kc/examples/irq/irq-hyperscreen.c b/src/test/kc/examples/irq/irq-hyperscreen.c index c8853ee65..ec8d9765b 100644 --- a/src/test/kc/examples/irq/irq-hyperscreen.c +++ b/src/test/kc/examples/irq/irq-hyperscreen.c @@ -1,5 +1,5 @@ // A raster IRQ that opens the top/bottom border. -#include +#include char* const GHOST_BYTE = $3fff; diff --git a/src/test/kc/examples/kernalload/kernalload.c b/src/test/kc/examples/kernalload/kernalload.c index c786c89b2..af186b506 100644 --- a/src/test/kc/examples/kernalload/kernalload.c +++ b/src/test/kc/examples/kernalload/kernalload.c @@ -3,8 +3,8 @@ // To execute the program succesfully you must mount the D64 disk image and execute the kernalload.PRG program #pragma link("kernalload.ld") -#include -#include +#include +#include // Sprite file #pragma data_seg(Sprite) diff --git a/src/test/kc/examples/multiplexer/simple-multiplexer.c b/src/test/kc/examples/multiplexer/simple-multiplexer.c index 0130bca1b..89fc22841 100644 --- a/src/test/kc/examples/multiplexer/simple-multiplexer.c +++ b/src/test/kc/examples/multiplexer/simple-multiplexer.c @@ -1,6 +1,6 @@ // A simple usage of the flexible sprite multiplexer routine -#include -#include +#include +#include // Location of screen & sprites char* SCREEN = $400; diff --git a/src/test/kc/examples/music/music.c b/src/test/kc/examples/music/music.c index f6b9ececf..b8e0bbf10 100755 --- a/src/test/kc/examples/music/music.c +++ b/src/test/kc/examples/music/music.c @@ -1,5 +1,5 @@ // A simple SID music player playing music in the main loop. -#include +#include char* const MUSIC = $1000; diff --git a/src/test/kc/examples/music/music_irq.c b/src/test/kc/examples/music/music_irq.c index 733d18eeb..82ddc75a4 100755 --- a/src/test/kc/examples/music/music_irq.c +++ b/src/test/kc/examples/music/music_irq.c @@ -1,5 +1,5 @@ // A simple SID music player using RASTER IRQ -#include +#include char* const MUSIC = $1000; diff --git a/src/test/kc/examples/nmisamples/nmisamples.c b/src/test/kc/examples/nmisamples/nmisamples.c index 29d7a24fd..6b3d3e18b 100644 --- a/src/test/kc/examples/nmisamples/nmisamples.c +++ b/src/test/kc/examples/nmisamples/nmisamples.c @@ -2,7 +2,7 @@ // Code by Scan of Desire (Richard-William Loerakker) // Sample from ART OF NOISE: MOMENTS IN LOVE -#include +#include const unsigned int SAMPLE_SIZE = 0x6100; char SAMPLE[SAMPLE_SIZE] = kickasm(resource "moments_sample.bin") {{ .import binary "moments_sample.bin" }}; diff --git a/src/test/kc/examples/plasma/plasma-unroll.c b/src/test/kc/examples/plasma/plasma-unroll.c index 02c8b6bae..bb338d9e9 100644 --- a/src/test/kc/examples/plasma/plasma-unroll.c +++ b/src/test/kc/examples/plasma/plasma-unroll.c @@ -6,8 +6,8 @@ // Ported to KickC by Jesper Gravgaard. // Original source https://github.com/cc65/cc65/blob/master/samples/plasma.c -#include -#include +#include +#include #include "sid.c" unsigned char* const SCREEN1 = $2800; diff --git a/src/test/kc/examples/plasma/plasma.c b/src/test/kc/examples/plasma/plasma.c index d355458ee..cfd76dacb 100644 --- a/src/test/kc/examples/plasma/plasma.c +++ b/src/test/kc/examples/plasma/plasma.c @@ -4,8 +4,8 @@ // Ported to KickC by Jesper Gravgaard. // Original source https://github.com/cc65/cc65/blob/master/samples/plasma.c -#include -#include +#include +#include #include "sid.c" char* const SCREEN1 = 0x2800; diff --git a/src/test/kc/examples/rasterbars/raster-bars.c b/src/test/kc/examples/rasterbars/raster-bars.c index 1a34a2ed3..d09fef539 100644 --- a/src/test/kc/examples/rasterbars/raster-bars.c +++ b/src/test/kc/examples/rasterbars/raster-bars.c @@ -1,4 +1,4 @@ -#include +#include void main() { asm { diff --git a/src/test/kc/examples/rotate/rotate.c b/src/test/kc/examples/rotate/rotate.c index 52e2fd89f..954c13154 100644 --- a/src/test/kc/examples/rotate/rotate.c +++ b/src/test/kc/examples/rotate/rotate.c @@ -1,9 +1,9 @@ // 2D rotattion of 8 sprites -#include -#include -#include -#include +#include +#include +#include +#include char* SCREEN = $0400; diff --git a/src/test/kc/examples/scrolllogo/scrolllogo.c b/src/test/kc/examples/scrolllogo/scrolllogo.c index c0bc625cf..7286511e0 100644 --- a/src/test/kc/examples/scrolllogo/scrolllogo.c +++ b/src/test/kc/examples/scrolllogo/scrolllogo.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include char* SCREEN = $400; char* LOGO = $2000; diff --git a/src/test/kc/examples/showlogo/showlogo.c b/src/test/kc/examples/showlogo/showlogo.c index cbe16131b..fd38bf622 100644 --- a/src/test/kc/examples/showlogo/showlogo.c +++ b/src/test/kc/examples/showlogo/showlogo.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include char* SCREEN = $400; char* LOGO = $2000; diff --git a/src/test/kc/examples/sinplotter/sine-plotter.c b/src/test/kc/examples/sinplotter/sine-plotter.c index 8b1d291de..d42fe06ce 100644 --- a/src/test/kc/examples/sinplotter/sine-plotter.c +++ b/src/test/kc/examples/sinplotter/sine-plotter.c @@ -1,9 +1,9 @@ // Generate a big sinus and plot it on a bitmap -#include -#include -#include -#include +#include +#include +#include +#include char* SCREEN = $400; char* BITMAP = $2000; diff --git a/src/test/kc/examples/sinsprites/sinus-sprites.c b/src/test/kc/examples/sinsprites/sinus-sprites.c index da49fcd29..61a924a3a 100644 --- a/src/test/kc/examples/sinsprites/sinus-sprites.c +++ b/src/test/kc/examples/sinsprites/sinus-sprites.c @@ -1,6 +1,6 @@ -#include -#include "basic-floats.c" -#include +#include +#include +#include const char sinlen_x = 221; const char sintab_x[221]; diff --git a/src/test/kc/fastmultiply-127.c b/src/test/kc/fastmultiply-127.c index c07c910ab..057d330a3 100644 --- a/src/test/kc/fastmultiply-127.c +++ b/src/test/kc/fastmultiply-127.c @@ -4,7 +4,7 @@ // Uses principles from C=Hacking #16 https://codebase64.org/doku.php?id=magazines:chacking16 // Utilizes the fact that a*b = ((a+b)/2)^2 - ((a-b)/2)^2 -#include +#include void main() { print_cls(); diff --git a/src/test/kc/font-hex-show.c b/src/test/kc/font-hex-show.c index 98d014961..b0ea67e40 100644 --- a/src/test/kc/font-hex-show.c +++ b/src/test/kc/font-hex-show.c @@ -1,6 +1,6 @@ // Shows a font where each char contains the number of the char (00-ff) -#include -#include +#include +#include #include "font-hex.c" byte* SCREEN = 0x0400; diff --git a/src/test/kc/gfxbank.c b/src/test/kc/gfxbank.c index a952d5184..330bac557 100644 --- a/src/test/kc/gfxbank.c +++ b/src/test/kc/gfxbank.c @@ -1,6 +1,6 @@ // Test minimization of constants -#include +#include void main() { byte* const PLAYFIELD_CHARSET = $2800; diff --git a/src/test/kc/incrementinarray.c b/src/test/kc/incrementinarray.c index 6dec0d367..ddd3d4922 100644 --- a/src/test/kc/incrementinarray.c +++ b/src/test/kc/incrementinarray.c @@ -1,4 +1,4 @@ -#include +#include byte txt[] = "camelot"; diff --git a/src/test/kc/irq-hardware-clobber-jsr.c b/src/test/kc/irq-hardware-clobber-jsr.c index 276c7bc8b..0f9f8234e 100644 --- a/src/test/kc/irq-hardware-clobber-jsr.c +++ b/src/test/kc/irq-hardware-clobber-jsr.c @@ -1,5 +1,5 @@ // A minimal working raster hardware IRQ with clobber-based register savings -#include +#include void main() { asm { sei } diff --git a/src/test/kc/irq-idx-problem.c b/src/test/kc/irq-idx-problem.c index 09ab064cd..e1b8b2ed6 100644 --- a/src/test/kc/irq-idx-problem.c +++ b/src/test/kc/irq-idx-problem.c @@ -1,5 +1,5 @@ // Test interrupt routine using a variable between calls (irq_idx) -#include +#include byte* const SCREEN = $0400; diff --git a/src/test/kc/irq-kernel-minimal.c b/src/test/kc/irq-kernel-minimal.c index a18aea7bf..0f586ac9f 100644 --- a/src/test/kc/irq-kernel-minimal.c +++ b/src/test/kc/irq-kernel-minimal.c @@ -1,6 +1,6 @@ // A minimal working IRQ -#include +#include // Setup the IRQ routine void main() { diff --git a/src/test/kc/keyboard-glitch.c b/src/test/kc/keyboard-glitch.c index 21d91cd92..561640431 100644 --- a/src/test/kc/keyboard-glitch.c +++ b/src/test/kc/keyboard-glitch.c @@ -5,8 +5,8 @@ // Press "C" to enter pressed state (increaded bgcol) - and "SPACE" to leave presssed state again. // Holding SPACE will sometimes trigger the pressed state when normal interrupts are enabled (green border) // but never when they are disabled (red border) -#include -#include +#include +#include void main() { *BORDERCOL = GREEN; diff --git a/src/test/kc/line-anim.c b/src/test/kc/line-anim.c index 340d65e46..0df551438 100644 --- a/src/test/kc/line-anim.c +++ b/src/test/kc/line-anim.c @@ -1,6 +1,6 @@ // Animated lines drawn on a single color bitmap -#include -#include +#include +#include byte* BITMAP = $a000; byte* SCREEN = $8800; diff --git a/src/test/kc/linegen.c b/src/test/kc/linegen.c index 2dc43758f..3fff0a5c8 100644 --- a/src/test/kc/linegen.c +++ b/src/test/kc/linegen.c @@ -1,7 +1,7 @@ // Linear table generator // Work in progress towards a sinus generator -#include -#include +#include +#include void main() { word lintab1[20]; diff --git a/src/test/kc/logarithm.c b/src/test/kc/logarithm.c index 350cb2f4b..656aea5ed 100644 --- a/src/test/kc/logarithm.c +++ b/src/test/kc/logarithm.c @@ -8,7 +8,7 @@ // 2.8212026 23111.2917 23111 // -1.7417939 -14268.77563 -14269 -#include +#include void main() { diff --git a/src/test/kc/loophead-problem-3.c b/src/test/kc/loophead-problem-3.c index 160889117..639550771 100644 --- a/src/test/kc/loophead-problem-3.c +++ b/src/test/kc/loophead-problem-3.c @@ -1,8 +1,8 @@ // Program where loop-head optimization produces wrong return value // Reported by Richard-William Loerakker -#include -#include +#include +#include void main() { dword result = mul16u(4,123); diff --git a/src/test/kc/malloc-0.c b/src/test/kc/malloc-0.c index 4e266c690..a72e905fb 100644 --- a/src/test/kc/malloc-0.c +++ b/src/test/kc/malloc-0.c @@ -1,6 +1,6 @@ // Experiments with malloc() - a byte array -#include +#include byte* BYTES = malloc(0x100); diff --git a/src/test/kc/malloc-1.c b/src/test/kc/malloc-1.c index 13e961d6e..142bc1bb1 100644 --- a/src/test/kc/malloc-1.c +++ b/src/test/kc/malloc-1.c @@ -1,6 +1,6 @@ // Experiments with malloc() - a word array -#include +#include word* WORDS = malloc(0x200); diff --git a/src/test/kc/memcpy-0.c b/src/test/kc/memcpy-0.c index bcace967a..7222383fe 100644 --- a/src/test/kc/memcpy-0.c +++ b/src/test/kc/memcpy-0.c @@ -1,7 +1,7 @@ // Test memcpy - copy charset and screen using memcpy() from stdlib string -#include -#include +#include +#include byte* const CHARSET = 0x2000; byte* const SCREEN = 0x0400; diff --git a/src/test/kc/memcpy-1.c b/src/test/kc/memcpy-1.c index b7f982736..b77dea5f5 100644 --- a/src/test/kc/memcpy-1.c +++ b/src/test/kc/memcpy-1.c @@ -1,6 +1,6 @@ // Test memcpy on strings ( -#include +#include char* const SCREEN = 0x0400; const char CAMELOT[] = "camelot"; diff --git a/src/test/kc/memory-heap.c b/src/test/kc/memory-heap.c index c2c4f4c35..4dca3c566 100644 --- a/src/test/kc/memory-heap.c +++ b/src/test/kc/memory-heap.c @@ -1,6 +1,6 @@ // Experiments with malloc() -#include +#include void main() { unsigned char* buf1 = malloc(100); diff --git a/src/test/kc/millfork-benchmarks/benchcommon.c b/src/test/kc/millfork-benchmarks/benchcommon.c index 1e3175729..c4a907bfe 100644 --- a/src/test/kc/millfork-benchmarks/benchcommon.c +++ b/src/test/kc/millfork-benchmarks/benchcommon.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include unsigned int last_time; diff --git a/src/test/kc/millfork-benchmarks/plasma-kc.c b/src/test/kc/millfork-benchmarks/plasma-kc.c index d41f12be2..cfe766f19 100644 --- a/src/test/kc/millfork-benchmarks/plasma-kc.c +++ b/src/test/kc/millfork-benchmarks/plasma-kc.c @@ -1,5 +1,5 @@ #include "benchcommon.c" -#include +#include char* const SCREEN1 = 0xE000; char* const SCREEN2 = 0xE400; diff --git a/src/test/kc/millfork-benchmarks/romsum-kc.c b/src/test/kc/millfork-benchmarks/romsum-kc.c index 1d57a20f7..a059c33ee 100644 --- a/src/test/kc/millfork-benchmarks/romsum-kc.c +++ b/src/test/kc/millfork-benchmarks/romsum-kc.c @@ -1,5 +1,5 @@ #include "benchcommon.c" -#include +#include byte* const rom = (byte*)0xe000; diff --git a/src/test/kc/millfork-benchmarks/sieve-kc.c b/src/test/kc/millfork-benchmarks/sieve-kc.c index 01cae7348..12705a8f2 100644 --- a/src/test/kc/millfork-benchmarks/sieve-kc.c +++ b/src/test/kc/millfork-benchmarks/sieve-kc.c @@ -1,4 +1,4 @@ -#include +#include #include "benchcommon.c" const unsigned int COUNT = 16384; diff --git a/src/test/kc/min-fmul-16.c b/src/test/kc/min-fmul-16.c index a1ab43d54..bd0b11a92 100644 --- a/src/test/kc/min-fmul-16.c +++ b/src/test/kc/min-fmul-16.c @@ -1,4 +1,4 @@ -#include +#include byte* RASTER = $d012; byte* BORDERCOL = $d020; diff --git a/src/test/kc/mul8u-min.c b/src/test/kc/mul8u-min.c index 5a8b5b28b..5666e926e 100644 --- a/src/test/kc/mul8u-min.c +++ b/src/test/kc/mul8u-min.c @@ -1,6 +1,6 @@ // Minimal test of mul8u -#include +#include void main() { diff --git a/src/test/kc/multiplexer-irq/simple-multiplexer-irq.c b/src/test/kc/multiplexer-irq/simple-multiplexer-irq.c index 263ce9a66..e9d598e75 100644 --- a/src/test/kc/multiplexer-irq/simple-multiplexer-irq.c +++ b/src/test/kc/multiplexer-irq/simple-multiplexer-irq.c @@ -1,6 +1,6 @@ // A simple usage of the flexible sprite multiplexer routine -#include -#include +#include +#include // Location of screen & sprites char* SCREEN = 0x0400; diff --git a/src/test/kc/number-ternary-fail-2.c b/src/test/kc/number-ternary-fail-2.c index 930806cbc..0084fa669 100644 --- a/src/test/kc/number-ternary-fail-2.c +++ b/src/test/kc/number-ternary-fail-2.c @@ -1,7 +1,7 @@ // Failing number type resolving in ternary operator // Currently fails in the ternary operator with number-issues if integer literal is not specified! -#include +#include void SolveMaze(char *maze, word width, word height) { diff --git a/src/test/kc/plasma-center.c b/src/test/kc/plasma-center.c index 0df3175ea..531613e7f 100644 --- a/src/test/kc/plasma-center.c +++ b/src/test/kc/plasma-center.c @@ -1,11 +1,11 @@ // Plasma based on the distance/angle to the screen center -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include "sid.c" diff --git a/src/test/kc/printmsg.c b/src/test/kc/printmsg.c index 7f164d0d5..95cee02b6 100644 --- a/src/test/kc/printmsg.c +++ b/src/test/kc/printmsg.c @@ -1,4 +1,4 @@ -#include +#include byte msg[] = "hello world! "; byte msg2[] = "hello c64! "; diff --git a/src/test/kc/processor-port-test-writethrough.c b/src/test/kc/processor-port-test-writethrough.c index fde05cdcb..db6d9793a 100644 --- a/src/test/kc/processor-port-test-writethrough.c +++ b/src/test/kc/processor-port-test-writethrough.c @@ -1,7 +1,7 @@ // Test the write through to RAM when writing to VIC/CIA/colorram -#include -#include +#include +#include void main() { // Avoid interrupts diff --git a/src/test/kc/processor-port-test.c b/src/test/kc/processor-port-test.c index 21dea7192..43e8b8e04 100644 --- a/src/test/kc/processor-port-test.c +++ b/src/test/kc/processor-port-test.c @@ -1,8 +1,8 @@ // Test the functionality of the C64 processor port ($00/$01) // Tests by setting the value of the processor port - and then printing out values of $00/$01/$a000/$d000/$e000 -#include -#include +#include +#include char* const BASIC_ROM = $a000; char* const KERNAL_ROM = $e000; diff --git a/src/test/kc/robozzle64-label-problem.c b/src/test/kc/robozzle64-label-problem.c index 63914f78a..2c7afd0f6 100644 --- a/src/test/kc/robozzle64-label-problem.c +++ b/src/test/kc/robozzle64-label-problem.c @@ -1,4 +1,4 @@ -#include +#include void main() { word* screen = 0x0400; diff --git a/src/test/kc/roll-sprite-msb.c b/src/test/kc/roll-sprite-msb.c index e3c04246e..2252bab5e 100644 --- a/src/test/kc/roll-sprite-msb.c +++ b/src/test/kc/roll-sprite-msb.c @@ -1,6 +1,6 @@ // Tests rolling sprite MSB by variable amount -#include +#include void main() { word xpos = 200; diff --git a/src/test/kc/sandbox.c b/src/test/kc/sandbox.c index cd5c69b56..970a22868 100644 --- a/src/test/kc/sandbox.c +++ b/src/test/kc/sandbox.c @@ -1,4 +1,4 @@ -#include +#include byte * const zp1 = 0x61; // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169 byte * const zp2 = 0x62; diff --git a/src/test/kc/scan-desire-problem.c b/src/test/kc/scan-desire-problem.c index 261bea8ba..8b0c4b135 100644 --- a/src/test/kc/scan-desire-problem.c +++ b/src/test/kc/scan-desire-problem.c @@ -1,8 +1,8 @@ // Illustrates a problem with a missing fragment - pbuc1_derefidx_vwuz1=vbuz2 -#include -#include -#include -#include +#include +#include +#include +#include byte* const screen = $400; byte* const charset = $2000; diff --git a/src/test/kc/screen-center-angle.c b/src/test/kc/screen-center-angle.c index 85e6fdbc1..0ff01f8b0 100644 --- a/src/test/kc/screen-center-angle.c +++ b/src/test/kc/screen-center-angle.c @@ -1,11 +1,11 @@ // Calculate the angle to the center of the screen - and show it using font-hex // 4.65 million cycles -#include -#include +#include +#include #include "font-hex.c" -#include -#include -#include +#include +#include +#include byte* const CHARSET = 0x2000; byte* const SCREEN = 0x2800; diff --git a/src/test/kc/screen-center-distance.c b/src/test/kc/screen-center-distance.c index b0ee03abe..2890106cc 100644 --- a/src/test/kc/screen-center-distance.c +++ b/src/test/kc/screen-center-distance.c @@ -1,11 +1,11 @@ // Calculate the distance to the center of the screen - and show it using font-hex -#include -#include -#include +#include +#include +#include #include "font-hex.c" -#include -#include +#include +#include #pragma reserve(08) diff --git a/src/test/kc/screen-show-spiral-buckets.c b/src/test/kc/screen-show-spiral-buckets.c index ed377cf48..fb3a61863 100644 --- a/src/test/kc/screen-show-spiral-buckets.c +++ b/src/test/kc/screen-show-spiral-buckets.c @@ -1,10 +1,10 @@ // Fill screen using a spiral based on distance-to-center / angle-to-center // Utilizes a bucket sort for identifying the minimum angle/distance -#include -#include -#include -#include +#include +#include +#include +#include // Screen containing distance to center byte* SCREEN_DIST = malloc(1000); diff --git a/src/test/kc/screen-show-spiral.c b/src/test/kc/screen-show-spiral.c index 9e189ab59..3e3e0f7e4 100644 --- a/src/test/kc/screen-show-spiral.c +++ b/src/test/kc/screen-show-spiral.c @@ -1,8 +1,8 @@ // Fill screen using a spiral based on distance-to-center / angle-to-center -#include -#include -#include +#include +#include +#include // Screen containing distance to center diff --git a/src/test/kc/semi-struct-1.c b/src/test/kc/semi-struct-1.c index 30ef84222..5605b3067 100644 --- a/src/test/kc/semi-struct-1.c +++ b/src/test/kc/semi-struct-1.c @@ -6,7 +6,7 @@ // }; // Point points[NUM_POINTS]; -#include +#include // The size of a point const byte SIZEOF_POINT = 2; diff --git a/src/test/kc/semi-struct-2.c b/src/test/kc/semi-struct-2.c index 80e8b74d5..ab57283b2 100644 --- a/src/test/kc/semi-struct-2.c +++ b/src/test/kc/semi-struct-2.c @@ -18,9 +18,9 @@ // typedef struct fileentry ENTRY; // ENTRY files[MAX_FILES]; -#include -#include -#include +#include +#include +#include // The size of a file ENTRY const byte SIZEOF_ENTRY = 18; diff --git a/src/test/kc/sieve-min.c b/src/test/kc/sieve-min.c index 1cf7cd78f..c524b6f22 100644 --- a/src/test/kc/sieve-min.c +++ b/src/test/kc/sieve-min.c @@ -1,9 +1,7 @@ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include char* const SCREEN = 0x0400; diff --git a/src/test/kc/sieve.c b/src/test/kc/sieve.c index cb129f862..2ed38e6a0 100644 --- a/src/test/kc/sieve.c +++ b/src/test/kc/sieve.c @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include char* const SCREEN = 0x0400; diff --git a/src/test/kc/signed-indexed-subtract.c b/src/test/kc/signed-indexed-subtract.c index 7c0cf98d4..626e9626b 100644 --- a/src/test/kc/signed-indexed-subtract.c +++ b/src/test/kc/signed-indexed-subtract.c @@ -1,6 +1,6 @@ // Tests that signed indexed subtract works as intended -#include +#include signed word words[] = {-$6000, -$600, -$60, -6, 0, 6, $60, $600, $6000}; diff --git a/src/test/kc/signed-words.c b/src/test/kc/signed-words.c index 7ab70f32e..9d41b04c6 100644 --- a/src/test/kc/signed-words.c +++ b/src/test/kc/signed-words.c @@ -1,4 +1,4 @@ -#include +#include byte* const SCREEN = $0400; byte* const SPRITES_PTR = SCREEN+$3f8; diff --git a/src/test/kc/sinus-basic.c b/src/test/kc/sinus-basic.c index 8ee39581a..b7c5b4584 100644 --- a/src/test/kc/sinus-basic.c +++ b/src/test/kc/sinus-basic.c @@ -1,5 +1,5 @@ -#include -#include "basic-floats.c" +#include +#include void main() { byte f_i[] = {0, 0, 0, 0, 0}; diff --git a/src/test/kc/sinusb.c b/src/test/kc/sinusb.c index 88ffcf143..9a0c2191d 100644 --- a/src/test/kc/sinusb.c +++ b/src/test/kc/sinusb.c @@ -4,7 +4,7 @@ // Uses the approximation sin(x) = x - x^/6 + x^/128 // Optimization possibility: Use symmetries when generating sinustables. wavelength%2==0 -> mirror symmetry over PI, wavelength%4==0 -> mirror symmetry over PI/2. -#include +#include // Generate signed (large) word sinus table - on the full -$7fff - $7fff range // sintab - the table to generate into diff --git a/src/test/kc/sinusgen16.c b/src/test/kc/sinusgen16.c index 0da483b82..8d320223e 100644 --- a/src/test/kc/sinusgen16.c +++ b/src/test/kc/sinusgen16.c @@ -1,6 +1,6 @@ // Generates a 16-bit signed sinus -#include -#include +#include +#include void main() { word wavelength = 120; diff --git a/src/test/kc/sinusgen16b.c b/src/test/kc/sinusgen16b.c index 431b2bdc5..dfc83f0f2 100644 --- a/src/test/kc/sinusgen16b.c +++ b/src/test/kc/sinusgen16b.c @@ -1,7 +1,7 @@ // Generates a 16-bit signed sinus -#include +#include #include "sinusb.c" -#include +#include void main() { word wavelength = 120; diff --git a/src/test/kc/sinusgen8.c b/src/test/kc/sinusgen8.c index f591a64f6..d2e107a8e 100644 --- a/src/test/kc/sinusgen8.c +++ b/src/test/kc/sinusgen8.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include word wavelength = 192; signed byte sintab2[192]; diff --git a/src/test/kc/sinusgen8b.c b/src/test/kc/sinusgen8b.c index eca1279bc..e127dab5c 100644 --- a/src/test/kc/sinusgen8b.c +++ b/src/test/kc/sinusgen8b.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include void main() { word wavelength = 192; diff --git a/src/test/kc/sinusgenscale8.c b/src/test/kc/sinusgenscale8.c index c41089228..1928ad055 100644 --- a/src/test/kc/sinusgenscale8.c +++ b/src/test/kc/sinusgenscale8.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include void main() { word tabsize = 20; diff --git a/src/test/kc/sprite-font.c b/src/test/kc/sprite-font.c index 610a2ae71..fdfde7883 100644 --- a/src/test/kc/sprite-font.c +++ b/src/test/kc/sprite-font.c @@ -1,7 +1,7 @@ // Create a sprite font using lines -#include -#include +#include +#include char* const SCREEN = 0x0400; char* const SPRITE = 0x2000; diff --git a/src/test/kc/struct-ptr-22.c b/src/test/kc/struct-ptr-22.c index b81ab0926..3d99b4de6 100644 --- a/src/test/kc/struct-ptr-22.c +++ b/src/test/kc/struct-ptr-22.c @@ -2,7 +2,7 @@ // https://gitlab.com/camelot/kickc/issues/270 -#include +#include struct fileentry { char *bufEdit; diff --git a/src/test/kc/struct-ptr-26.c b/src/test/kc/struct-ptr-26.c index 5f1604f27..b206c4208 100644 --- a/src/test/kc/struct-ptr-26.c +++ b/src/test/kc/struct-ptr-26.c @@ -1,4 +1,4 @@ -#include +#include typedef unsigned char BYTE; typedef unsigned short WORD; struct fileentry { diff --git a/src/test/kc/test-comparisons-sword.c b/src/test/kc/test-comparisons-sword.c index 2131e3dd7..84de8bab2 100644 --- a/src/test/kc/test-comparisons-sword.c +++ b/src/test/kc/test-comparisons-sword.c @@ -1,7 +1,7 @@ // Test signed word comparisons -#include -#include +#include +#include signed word swords[] = { -$6fed, $0012, $7fed }; diff --git a/src/test/kc/test-comparisons-word.c b/src/test/kc/test-comparisons-word.c index 26fa858ea..8487f04d6 100644 --- a/src/test/kc/test-comparisons-word.c +++ b/src/test/kc/test-comparisons-word.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include word words[] = { $0012, $3f34, $cfed }; diff --git a/src/test/kc/test-comparisons.c b/src/test/kc/test-comparisons.c index e199234e3..e31504a82 100644 --- a/src/test/kc/test-comparisons.c +++ b/src/test/kc/test-comparisons.c @@ -1,4 +1,4 @@ -#include +#include void main() { print_cls(); diff --git a/src/test/kc/test-division.c b/src/test/kc/test-division.c index 91d9b1c90..a9b61174a 100644 --- a/src/test/kc/test-division.c +++ b/src/test/kc/test-division.c @@ -1,6 +1,6 @@ // Test the binary division library -#include -#include +#include +#include void main() { print_cls(); diff --git a/src/test/kc/test-keyboard-space.c b/src/test/kc/test-keyboard-space.c index a7eb160fe..912a2c08c 100644 --- a/src/test/kc/test-keyboard-space.c +++ b/src/test/kc/test-keyboard-space.c @@ -1,5 +1,5 @@ // Test keyboard input - test the space bar -#include +#include void main() { keyboard_init(); diff --git a/src/test/kc/test-keyboard.c b/src/test/kc/test-keyboard.c index a37c439a1..4dd7660c0 100644 --- a/src/test/kc/test-keyboard.c +++ b/src/test/kc/test-keyboard.c @@ -1,6 +1,6 @@ // Test keyboard input - in the keyboard matrix and mapping screen codes to key codes -#include +#include void main() { // Clear screen diff --git a/src/test/kc/test-lowhigh.c b/src/test/kc/test-lowhigh.c index 5ed59e790..6012471ea 100644 --- a/src/test/kc/test-lowhigh.c +++ b/src/test/kc/test-lowhigh.c @@ -1,4 +1,4 @@ -#include +#include void main() { print_cls(); diff --git a/src/test/kc/test-multiply-16bit.c b/src/test/kc/test-multiply-16bit.c index 2bc95ccf5..cd17bdc6a 100644 --- a/src/test/kc/test-multiply-16bit.c +++ b/src/test/kc/test-multiply-16bit.c @@ -1,7 +1,7 @@ // Test the fast multiplication library -#include -#include -#include +#include +#include +#include byte* BGCOL = $d021; diff --git a/src/test/kc/test-multiply-8bit.c b/src/test/kc/test-multiply-8bit.c index ba3577a32..c09b8bf6d 100644 --- a/src/test/kc/test-multiply-8bit.c +++ b/src/test/kc/test-multiply-8bit.c @@ -1,7 +1,7 @@ // Test the fast multiplication library -#include -#include -#include +#include +#include +#include byte* BGCOL = $d021; diff --git a/src/test/kc/test-signed-word-minus-byte.c b/src/test/kc/test-signed-word-minus-byte.c index 8972809e2..0f88a9944 100644 --- a/src/test/kc/test-signed-word-minus-byte.c +++ b/src/test/kc/test-signed-word-minus-byte.c @@ -1,6 +1,6 @@ // Tests subtracting bytes from signed words -#include +#include void main() { signed word w1 = 1234; diff --git a/src/test/kc/test-utoa.c b/src/test/kc/test-utoa.c index 57619bdcb..80f6f7062 100644 --- a/src/test/kc/test-utoa.c +++ b/src/test/kc/test-utoa.c @@ -1,6 +1,6 @@ // Tests the utoa10() function that converts unsigned int to DECIMAL string -#include -#include +#include +#include // buffer for number char buf[17]; diff --git a/src/test/kc/textbox.c b/src/test/kc/textbox.c index 6d2ff47c6..98b1f16be 100644 --- a/src/test/kc/textbox.c +++ b/src/test/kc/textbox.c @@ -1,5 +1,5 @@ /* Textbox routine with word wrap for KickC by Scan/Desire */ -#include +#include byte* const screen = $0400; const byte text[] = "this is a small test with word wrap, if a word is too long it moves it to the next line. isn't that supercalifragilisticexpialidocious? i think it's cool!"; diff --git a/src/test/kc/travis1.c b/src/test/kc/travis1.c index f6e535b30..594dd7152 100644 --- a/src/test/kc/travis1.c +++ b/src/test/kc/travis1.c @@ -1,6 +1,6 @@ // Adding a missing word-fragment for Travis Fisher -#include +#include byte action_count = 0; const byte READY_FRAMES = 5; diff --git a/src/test/kc/type-signed.c b/src/test/kc/type-signed.c index ee64f8c53..7699ccea9 100644 --- a/src/test/kc/type-signed.c +++ b/src/test/kc/type-signed.c @@ -1,6 +1,6 @@ // Tests the special "signed" / "unsigned" without a simple type name -#include +#include void main() { signed a = -1023; diff --git a/src/test/kc/wfragment1.c b/src/test/kc/wfragment1.c index 510293e26..6675bb388 100644 --- a/src/test/kc/wfragment1.c +++ b/src/test/kc/wfragment1.c @@ -1,6 +1,6 @@ // Adding a missing word-fragment for Travis Fisher -#include +#include const byte MAX_OBJECTS = 16; word OBJ_WORLD_X[MAX_OBJECTS]; diff --git a/src/test/kc/zeropage-sinus.c b/src/test/kc/zeropage-sinus.c index 582b77b03..ef3d51bd6 100644 --- a/src/test/kc/zeropage-sinus.c +++ b/src/test/kc/zeropage-sinus.c @@ -1,7 +1,7 @@ // Attempt to store and use a sinus on zeropage // $00/$11 is carefully chosen to be $ff - which plays well with the processor port -#include +#include // A 256-byte (co)sinus (with $ff in the first two entries) const unsigned char align(0x100) SINTABLE[0x100] = kickasm {{ diff --git a/src/test/ref/c64dtv-8bppcharstretch.log b/src/test/ref/c64dtv-8bppcharstretch.log index cd1e69ea3..8852d5b3e 100644 --- a/src/test/ref/c64dtv-8bppcharstretch.log +++ b/src/test/ref/c64dtv-8bppcharstretch.log @@ -1,5 +1,5 @@ -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx Culled Empty Block (label) @1 Culled Empty Block (label) @2 diff --git a/src/test/ref/c64dtv-8bppchunkystretch.log b/src/test/ref/c64dtv-8bppchunkystretch.log index 4a9e27cbb..57f8e9af3 100644 --- a/src/test/ref/c64dtv-8bppchunkystretch.log +++ b/src/test/ref/c64dtv-8bppchunkystretch.log @@ -1,5 +1,5 @@ -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx Culled Empty Block (label) @1 Culled Empty Block (label) @2 diff --git a/src/test/ref/c64dtv-blitter-box.log b/src/test/ref/c64dtv-blitter-box.log index 4e422df86..c09f501ed 100644 --- a/src/test/ref/c64dtv-blitter-box.log +++ b/src/test/ref/c64dtv-blitter-box.log @@ -1,5 +1,5 @@ -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx Culled Empty Block (label) @1 Culled Empty Block (label) @2 diff --git a/src/test/ref/c64dtv-blittermin.log b/src/test/ref/c64dtv-blittermin.log index 77fa122d0..abc8c8f35 100644 --- a/src/test/ref/c64dtv-blittermin.log +++ b/src/test/ref/c64dtv-blittermin.log @@ -1,5 +1,5 @@ -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx Culled Empty Block (label) @1 Culled Empty Block (label) @2 diff --git a/src/test/ref/c64dtv-color.log b/src/test/ref/c64dtv-color.log index 299d07eb8..ffe398e8d 100644 --- a/src/test/ref/c64dtv-color.log +++ b/src/test/ref/c64dtv-color.log @@ -1,5 +1,5 @@ -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx Culled Empty Block (label) @1 Culled Empty Block (label) @2 diff --git a/src/test/ref/c64dtv-gfxexplorer.log b/src/test/ref/c64dtv-gfxexplorer.log index 7a146d8c9..9f4ad6f3c 100644 --- a/src/test/ref/c64dtv-gfxexplorer.log +++ b/src/test/ref/c64dtv-gfxexplorer.log @@ -10,8 +10,8 @@ Warning! Adding boolean cast to non-boolean condition (byte) print_str_lines::ch Warning! Adding boolean cast to non-boolean condition *((byte*) print_str::str) Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_at::str) Warning! Adding boolean cast to non-boolean sub-expression (byte) print_str_lines::ch -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) HEAP_TOP Identified constant variable (byte) form_fields_cnt Identified constant variable (byte) gfx_init_vic_bitmap::lines_cnt diff --git a/src/test/ref/c64dtv-gfxmodes.log b/src/test/ref/c64dtv-gfxmodes.log index d13c85ad6..299d96e5b 100644 --- a/src/test/ref/c64dtv-gfxmodes.log +++ b/src/test/ref/c64dtv-gfxmodes.log @@ -10,8 +10,8 @@ Warning! Adding boolean cast to non-boolean condition (byte) print_str_lines::ch Warning! Adding boolean cast to non-boolean condition *((byte*) print_str::str) Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_at::str) Warning! Adding boolean cast to non-boolean sub-expression (byte) print_str_lines::ch -Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) DTV_BLITTER_ALU +Identified constant variable (byte*) dtvSetCpuBankSegment1::cpuBank Identified constant variable (byte*) HEAP_TOP Identified constant variable (byte) mode_stdbitmap::lines_cnt Identified constant variable (byte*) mode_8bpppixelcell::CHARGEN diff --git a/src/test/ref/complex/clearscreen/clearscreen.log b/src/test/ref/complex/clearscreen/clearscreen.log index ff7f22f68..912336f05 100644 --- a/src/test/ref/complex/clearscreen/clearscreen.log +++ b/src/test/ref/complex/clearscreen/clearscreen.log @@ -21,14 +21,14 @@ Fixing pointer array-indexing *((const to_nomodify word*) VYSIN + (byte) process Constantified RValue *((const struct ProcessingSprite*) PROCESSING + (byte~) main::$10) ← { x: (word) 0, y: (word) 0, vx: (word) 0, vy: (word) 0, id: (byte) 0, ptr: (byte) 0, col: (byte) 0, status: (const byte) STATUS_FREE, screenPtr: (byte*)(number) 0 } Constantified RValue (struct ProcessingChar) getCharToProcess::closest ← (struct ProcessingChar){ (byte) getCharToProcess::x, (byte) getCharToProcess::y, (byte) getCharToProcess::dist } Constantified RValue *((const struct ProcessingSprite*) PROCESSING + (byte~) startProcessing::$28) ← (struct ProcessingSprite){ (word) startProcessing::spriteX, (word) startProcessing::spriteY, (word~) startProcessing::$21, (word) $3c, (byte) startProcessing::spriteIdx, (byte) startProcessing::spritePtr, (byte) startProcessing::spriteCol, (const byte) STATUS_NEW, (byte*) startProcessing::screenPtr } -Created struct value member variable (byte~) main::$5_x -Created struct value member variable (byte~) main::$5_y -Created struct value member variable (byte~) main::$5_dist -Converted struct value to member variables (struct ProcessingChar~) main::$5 Created struct value member variable (byte) main::center_x Created struct value member variable (byte) main::center_y Created struct value member variable (byte) main::center_dist Converted struct value to member variables (struct ProcessingChar) main::center +Created struct value member variable (byte~) main::$5_x +Created struct value member variable (byte~) main::$5_y +Created struct value member variable (byte~) main::$5_dist +Converted struct value to member variables (struct ProcessingChar~) main::$5 Created struct value member variable (byte) getCharToProcess::return_x Created struct value member variable (byte) getCharToProcess::return_y Created struct value member variable (byte) getCharToProcess::return_dist diff --git a/src/test/ref/complex/includes/includes-3.asm b/src/test/ref/complex/includes/includes-3.asm new file mode 100644 index 000000000..867e4f534 --- /dev/null +++ b/src/test/ref/complex/includes/includes-3.asm @@ -0,0 +1,14 @@ +// A file using a library +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 +main: { + // SCREEN[i++] = value + lda #'a' + sta SCREEN + lda #'x' + sta SCREEN+1 + // } + rts +} diff --git a/src/test/ref/complex/includes/includes-3.cfg b/src/test/ref/complex/includes/includes-3.cfg new file mode 100644 index 000000000..0022ab87a --- /dev/null +++ b/src/test/ref/complex/includes/includes-3.cfg @@ -0,0 +1,18 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + [4] *((const to_nomodify byte*) SCREEN) ← (byte) 'a' + [5] *((const to_nomodify byte*) SCREEN+(byte) 1) ← (byte) 'x' + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/complex/includes/includes-3.log b/src/test/ref/complex/includes/includes-3.log new file mode 100644 index 000000000..6cf814fac --- /dev/null +++ b/src/test/ref/complex/includes/includes-3.log @@ -0,0 +1,284 @@ +Identified constant variable (to_nomodify byte*) SCREEN + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte) value#0 ← (byte) 'a' + to:@1 + +(void()) main() +main: scope:[main] from @1 + (byte) value#4 ← phi( @1/(byte) value#7 ) + (byte) main::i#0 ← (byte) 0 + *((const to_nomodify byte*) SCREEN + (byte) main::i#0) ← (byte) value#4 + (byte) main::i#1 ← ++ (byte) main::i#0 + (byte) value#1 ← (byte) 'x' + *((const to_nomodify byte*) SCREEN + (byte) main::i#1) ← (byte) value#1 + (byte) main::i#2 ← ++ (byte) main::i#1 + to:main::@return +main::@return: scope:[main] from main + (byte) value#5 ← phi( main/(byte) value#1 ) + (byte) value#2 ← (byte) value#5 + return + to:@return +@1: scope:[] from @begin + (byte) value#7 ← phi( @begin/(byte) value#0 ) + call main + to:@2 +@2: scope:[] from @1 + (byte) value#6 ← phi( @1/(byte) value#2 ) + (byte) value#3 ← (byte) value#6 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(const to_nomodify byte*) SCREEN = (byte*)(number) $400 +(void()) main() +(label) main::@return +(byte) main::i +(byte) main::i#0 +(byte) main::i#1 +(byte) main::i#2 +(byte) value +(byte) value#0 +(byte) value#1 +(byte) value#2 +(byte) value#3 +(byte) value#4 +(byte) value#5 +(byte) value#6 +(byte) value#7 + +Simplifying constant pointer cast (byte*) 1024 +Successful SSA optimization PassNCastSimplification +Alias value#1 = value#5 value#2 +Alias value#0 = value#7 +Alias value#3 = value#6 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) value#4 (byte) value#0 +Identical Phi Values (byte) value#3 (byte) value#1 +Successful SSA optimization Pass2IdenticalPhiElimination +Constant (const byte) value#0 = 'a' +Constant (const byte) main::i#0 = 0 +Constant (const byte) value#1 = 'x' +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero SCREEN in [3] *((const to_nomodify byte*) SCREEN + (const byte) main::i#0) ← (const byte) value#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused variable (byte) main::i#2 and assignment [3] (byte) main::i#2 ← ++ (byte) main::i#1 +Successful SSA optimization PassNEliminateUnusedVars +Constant right-side identified [1] (byte) main::i#1 ← ++ (const byte) main::i#0 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) main::i#1 = ++main::i#0 +Successful SSA optimization Pass2ConstantIdentification +Inlining constant with different constant siblings (const byte) main::i#0 +Inlining constant with different constant siblings (const byte) main::i#1 +Inlining constant with different constant siblings (const byte) value#0 +Inlining constant with different constant siblings (const byte) value#1 +Constant inlined main::i#0 = (byte) 0 +Constant inlined value#1 = (byte) 'x' +Constant inlined value#0 = (byte) 'a' +Constant inlined main::i#1 = ++(byte) 0 +Successful SSA optimization Pass2ConstantInlining +Consolidated array index constant in *(SCREEN+++0) +Successful SSA optimization Pass2ConstantAdditionElimination +Simplifying constant integer increment ++0 +Successful SSA optimization Pass2ConstantSimplification +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + [4] *((const to_nomodify byte*) SCREEN) ← (byte) 'a' + [5] *((const to_nomodify byte*) SCREEN+(byte) 1) ← (byte) 'x' + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte) main::i +(byte) value + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// A file using a library + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + // [4] *((const to_nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2 + lda #'a' + sta SCREEN + // [5] *((const to_nomodify byte*) SCREEN+(byte) 1) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const to_nomodify byte*) SCREEN) ← (byte) 'a' [ ] ( main:2 [ ] { } ) always clobbers reg byte a +Statement [5] *((const to_nomodify byte*) SCREEN+(byte) 1) ← (byte) 'x' [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 33 combination +Uplifting [] best 33 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// A file using a library + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + // [4] *((const to_nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2 + lda #'a' + sta SCREEN + // [5] *((const to_nomodify byte*) SCREEN+(byte) 1) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from___bbegin: +Removing instruction __b1: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __bend: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction __bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const to_nomodify byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +(byte) main::i +(byte) value + + + +FINAL ASSEMBLER +Score: 18 + + // File Comments +// A file using a library + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @begin + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + // SCREEN[i++] = value + // [4] *((const to_nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2 + lda #'a' + sta SCREEN + // [5] *((const to_nomodify byte*) SCREEN+(byte) 1) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN+1 + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/complex/includes/includes-3.sym b/src/test/ref/complex/includes/includes-3.sym new file mode 100644 index 000000000..e8e3055bc --- /dev/null +++ b/src/test/ref/complex/includes/includes-3.sym @@ -0,0 +1,9 @@ +(label) @1 +(label) @begin +(label) @end +(const to_nomodify byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +(byte) main::i +(byte) value + diff --git a/src/test/ref/complex/tetris/test-sprites.log b/src/test/ref/complex/tetris/test-sprites.log index 8b31ed823..28e131393 100644 --- a/src/test/ref/complex/tetris/test-sprites.log +++ b/src/test/ref/complex/tetris/test-sprites.log @@ -2020,8 +2020,8 @@ sprites_init: { // Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr1_return = PLAYFIELD_SPRITES/$40 - .label __0 = $14 .label raster_sprite_gfx_modify = $15 + .label __0 = $14 .label ypos = $13 .label ptr = $16 .label ptr_1 = $19 diff --git a/src/test/ref/complex/tetris/tetris.log b/src/test/ref/complex/tetris/tetris.log index f15200920..eb8cc3829 100644 --- a/src/test/ref/complex/tetris/tetris.log +++ b/src/test/ref/complex/tetris/tetris.log @@ -15296,8 +15296,8 @@ sid_rnd_init: { // Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr1_return = PLAYFIELD_SPRITES/$40 - .label __0 = $d9 .label raster_sprite_gfx_modify = $da + .label __0 = $d9 .label ypos = $d8 .label ptr = $db .label ptr_1 = $de diff --git a/src/test/ref/cstyle-decl-var.log b/src/test/ref/cstyle-decl-var.log index 95e860568..fc458eb06 100644 --- a/src/test/ref/cstyle-decl-var.log +++ b/src/test/ref/cstyle-decl-var.log @@ -2,31 +2,30 @@ CONTROL FLOW GRAPH SSA @begin: scope:[] from (byte) idx#0 ← (byte) 0 - (byte) idx#1 ← (byte) 0 to:@1 (void()) main() main: scope:[main] from @1 - (byte) idx#7 ← phi( @1/(byte) idx#10 ) - *((const nomodify byte*) SCREEN + (byte) idx#7) ← (byte) 'c' - (byte) idx#2 ← ++ (byte) idx#7 - *((const nomodify byte*) SCREEN + (byte) idx#2) ← (byte) 'm' + (byte) idx#6 ← phi( @1/(byte) idx#9 ) + *((const nomodify byte*) SCREEN + (byte) idx#6) ← (byte) 'c' + (byte) idx#1 ← ++ (byte) idx#6 + *((const nomodify byte*) SCREEN + (byte) idx#1) ← (byte) 'm' + (byte) idx#2 ← ++ (byte) idx#1 + *((const nomodify byte*) SCREEN + (byte) idx#2) ← (byte) 'l' (byte) idx#3 ← ++ (byte) idx#2 - *((const nomodify byte*) SCREEN + (byte) idx#3) ← (byte) 'l' - (byte) idx#4 ← ++ (byte) idx#3 to:main::@return main::@return: scope:[main] from main - (byte) idx#8 ← phi( main/(byte) idx#4 ) - (byte) idx#5 ← (byte) idx#8 + (byte) idx#7 ← phi( main/(byte) idx#3 ) + (byte) idx#4 ← (byte) idx#7 return to:@return @1: scope:[] from @begin - (byte) idx#10 ← phi( @begin/(byte) idx#1 ) + (byte) idx#9 ← phi( @begin/(byte) idx#0 ) call main to:@2 @2: scope:[] from @1 - (byte) idx#9 ← phi( @1/(byte) idx#5 ) - (byte) idx#6 ← (byte) idx#9 + (byte) idx#8 ← phi( @1/(byte) idx#4 ) + (byte) idx#5 ← (byte) idx#8 to:@end @end: scope:[] from @2 @@ -39,7 +38,6 @@ SYMBOL TABLE SSA (byte) idx (byte) idx#0 (byte) idx#1 -(byte) idx#10 (byte) idx#2 (byte) idx#3 (byte) idx#4 @@ -53,35 +51,33 @@ SYMBOL TABLE SSA Simplifying constant pointer cast (byte*) 1024 Successful SSA optimization PassNCastSimplification -Alias idx#4 = idx#8 idx#5 -Alias idx#1 = idx#10 -Alias idx#6 = idx#9 +Alias idx#3 = idx#7 idx#4 +Alias idx#0 = idx#9 +Alias idx#5 = idx#8 Successful SSA optimization Pass2AliasElimination -Identical Phi Values (byte) idx#7 (byte) idx#1 -Identical Phi Values (byte) idx#6 (byte) idx#4 +Identical Phi Values (byte) idx#6 (byte) idx#0 +Identical Phi Values (byte) idx#5 (byte) idx#3 Successful SSA optimization Pass2IdenticalPhiElimination Constant (const byte) idx#0 = 0 -Constant (const byte) idx#1 = 0 Successful SSA optimization Pass2ConstantIdentification -Simplifying expression containing zero SCREEN in [3] *((const nomodify byte*) SCREEN + (const byte) idx#1) ← (byte) 'c' +Simplifying expression containing zero SCREEN in [2] *((const nomodify byte*) SCREEN + (const byte) idx#0) ← (byte) 'c' Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable (byte) idx#4 and assignment [5] (byte) idx#4 ← ++ (byte) idx#3 -Eliminating unused constant (const byte) idx#0 +Eliminating unused variable (byte) idx#3 and assignment [5] (byte) idx#3 ← ++ (byte) idx#2 Successful SSA optimization PassNEliminateUnusedVars -Constant right-side identified [1] (byte) idx#2 ← ++ (const byte) idx#1 +Constant right-side identified [1] (byte) idx#1 ← ++ (const byte) idx#0 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) idx#1 = ++idx#0 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [2] (byte) idx#2 ← ++ (const byte) idx#1 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) idx#2 = ++idx#1 Successful SSA optimization Pass2ConstantIdentification -Constant right-side identified [2] (byte) idx#3 ← ++ (const byte) idx#2 -Successful SSA optimization Pass2ConstantRValueConsolidation -Constant (const byte) idx#3 = ++idx#2 -Successful SSA optimization Pass2ConstantIdentification +Inlining constant with different constant siblings (const byte) idx#0 Inlining constant with different constant siblings (const byte) idx#1 Inlining constant with different constant siblings (const byte) idx#2 -Inlining constant with different constant siblings (const byte) idx#3 -Constant inlined idx#2 = ++(byte) 0 -Constant inlined idx#3 = ++++(byte) 0 -Constant inlined idx#1 = (byte) 0 +Constant inlined idx#2 = ++++(byte) 0 +Constant inlined idx#0 = (byte) 0 +Constant inlined idx#1 = ++(byte) 0 Successful SSA optimization Pass2ConstantInlining Consolidated array index constant in *(SCREEN+++0) Consolidated array index constant in *(SCREEN+++++0) diff --git a/src/test/ref/keyboard-glitch.asm b/src/test/ref/keyboard-glitch.asm index e95a6658a..6e44bb668 100644 --- a/src/test/ref/keyboard-glitch.asm +++ b/src/test/ref/keyboard-glitch.asm @@ -8,6 +8,10 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" + .const KEY_E = $e + .const KEY_C = $14 + .const KEY_I = $21 + .const KEY_SPACE = $3c .label BORDERCOL = $d020 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -16,10 +20,6 @@ .label CIA1_PORT_B = $dc01 .const RED = 2 .const GREEN = 5 - .const KEY_E = $e - .const KEY_C = $14 - .const KEY_I = $21 - .const KEY_SPACE = $3c .label SCREEN = $400 main: { // *BORDERCOL = GREEN diff --git a/src/test/ref/keyboard-glitch.log b/src/test/ref/keyboard-glitch.log index 9a8f1ccbe..eab1dee8f 100644 --- a/src/test/ref/keyboard-glitch.log +++ b/src/test/ref/keyboard-glitch.log @@ -622,6 +622,10 @@ Target platform is c64basic / MOS6502X :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + .const KEY_E = $e + .const KEY_C = $14 + .const KEY_I = $21 + .const KEY_SPACE = $3c .label BORDERCOL = $d020 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -630,10 +634,6 @@ Target platform is c64basic / MOS6502X .label CIA1_PORT_B = $dc01 .const RED = 2 .const GREEN = 5 - .const KEY_E = $e - .const KEY_C = $14 - .const KEY_I = $21 - .const KEY_SPACE = $3c .label SCREEN = $400 // @begin __bbegin: @@ -975,6 +975,10 @@ ASSEMBLER BEFORE OPTIMIZATION :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + .const KEY_E = $e + .const KEY_C = $14 + .const KEY_I = $21 + .const KEY_SPACE = $3c .label BORDERCOL = $d020 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -983,10 +987,6 @@ ASSEMBLER BEFORE OPTIMIZATION .label CIA1_PORT_B = $dc01 .const RED = 2 .const GREEN = 5 - .const KEY_E = $e - .const KEY_C = $14 - .const KEY_I = $21 - .const KEY_SPACE = $3c .label SCREEN = $400 // @begin __bbegin: @@ -1367,6 +1367,10 @@ Score: 3151 :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels + .const KEY_E = $e + .const KEY_C = $14 + .const KEY_I = $21 + .const KEY_SPACE = $3c .label BORDERCOL = $d020 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -1375,10 +1379,6 @@ Score: 3151 .label CIA1_PORT_B = $dc01 .const RED = 2 .const GREEN = 5 - .const KEY_E = $e - .const KEY_C = $14 - .const KEY_I = $21 - .const KEY_SPACE = $3c .label SCREEN = $400 // @begin // [1] phi from @begin to @1 [phi:@begin->@1] diff --git a/src/test/ref/malloc-0.log b/src/test/ref/malloc-0.log index 84a04e86a..c7725ea72 100644 --- a/src/test/ref/malloc-0.log +++ b/src/test/ref/malloc-0.log @@ -365,13 +365,13 @@ Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte a , reg REGISTER UPLIFT SCOPES Uplift Scope [main] 353.5: zp[1]:2 [ main::i#2 main::i#1 ] -Uplift Scope [malloc] Uplift Scope [RADIX] +Uplift Scope [malloc] Uplift Scope [] Uplifting [main] best 308 combination reg byte x [ main::i#2 main::i#1 ] -Uplifting [malloc] best 308 combination Uplifting [RADIX] best 308 combination +Uplifting [malloc] best 308 combination Uplifting [] best 308 combination ASSEMBLER BEFORE OPTIMIZATION diff --git a/src/test/ref/malloc-1.log b/src/test/ref/malloc-1.log index 2ae2a1f7b..a606eda56 100644 --- a/src/test/ref/malloc-1.log +++ b/src/test/ref/malloc-1.log @@ -410,13 +410,13 @@ Potential registers zp[2]:3 [ main::w#2 main::w#1 ] : zp[2]:3 , REGISTER UPLIFT SCOPES Uplift Scope [main] 252.5: zp[1]:2 [ main::i#2 main::i#1 ] 218.83: zp[2]:3 [ main::w#2 main::w#1 ] -Uplift Scope [malloc] Uplift Scope [RADIX] +Uplift Scope [malloc] Uplift Scope [] Uplifting [main] best 713 combination reg byte x [ main::i#2 main::i#1 ] zp[2]:3 [ main::w#2 main::w#1 ] -Uplifting [malloc] best 713 combination Uplifting [RADIX] best 713 combination +Uplifting [malloc] best 713 combination Uplifting [] best 713 combination Allocated (was zp[2]:3) zp[2]:2 [ main::w#2 main::w#1 ] diff --git a/src/test/ref/memory-heap.log b/src/test/ref/memory-heap.log index ef01b6982..7cbfe1a59 100644 --- a/src/test/ref/memory-heap.log +++ b/src/test/ref/memory-heap.log @@ -636,14 +636,14 @@ REGISTER UPLIFT SCOPES Uplift Scope [main] 303: zp[1]:2 [ main::i#2 main::i#1 ] 202: zp[1]:9 [ main::$4 ] 0.92: zp[2]:7 [ main::buf2#0 ] 0.85: zp[2]:5 [ main::buf1#0 ] Uplift Scope [] 140: zp[2]:3 [ heap_head#7 heap_head#1 ] Uplift Scope [malloc] 40.4: zp[2]:10 [ malloc::mem#0 ] -Uplift Scope [free] Uplift Scope [RADIX] +Uplift Scope [free] Uplifting [main] best 556 combination reg byte y [ main::i#2 main::i#1 ] reg byte a [ main::$4 ] zp[2]:7 [ main::buf2#0 ] zp[2]:5 [ main::buf1#0 ] Uplifting [] best 556 combination zp[2]:3 [ heap_head#7 heap_head#1 ] Uplifting [malloc] best 556 combination zp[2]:10 [ malloc::mem#0 ] -Uplifting [free] best 556 combination Uplifting [RADIX] best 556 combination +Uplifting [free] best 556 combination Coalescing zero page register [ zp[2]:7 [ main::buf2#0 ] ] with [ zp[2]:10 [ malloc::mem#0 ] ] - score: 1 Allocated (was zp[2]:3) zp[2]:2 [ heap_head#7 heap_head#1 ] Allocated (was zp[2]:5) zp[2]:4 [ main::buf1#0 ] diff --git a/src/test/ref/procedure-callingconvention-stack-10.log b/src/test/ref/procedure-callingconvention-stack-10.log index 5e4c44a8a..5aa8ef697 100644 --- a/src/test/ref/procedure-callingconvention-stack-10.log +++ b/src/test/ref/procedure-callingconvention-stack-10.log @@ -1,9 +1,9 @@ -Created struct value member variable (byte~) main::$1_x -Created struct value member variable (byte~) main::$1_y -Converted struct value to member variables (struct Point~) main::$1 Created struct value member variable (byte) main::p_x Created struct value member variable (byte) main::p_y Converted struct value to member variables (struct Point) main::p +Created struct value member variable (byte~) main::$1_x +Created struct value member variable (byte~) main::$1_y +Converted struct value to member variables (struct Point~) main::$1 Created struct value member variable (byte) get::return_x Created struct value member variable (byte) get::return_y Converted struct value to member variables (struct Point) get::return diff --git a/src/test/ref/procedure-callingconvention-stack-11.log b/src/test/ref/procedure-callingconvention-stack-11.log index 894a784f8..eb1d37546 100644 --- a/src/test/ref/procedure-callingconvention-stack-11.log +++ b/src/test/ref/procedure-callingconvention-stack-11.log @@ -1,9 +1,9 @@ -Created struct value member variable (struct Point~) main::$1_p1 -Created struct value member variable (struct Point~) main::$1_p2 -Converted struct value to member variables (struct Vector~) main::$1 Created struct value member variable (struct Point) main::v_p1 Created struct value member variable (struct Point) main::v_p2 Converted struct value to member variables (struct Vector) main::v +Created struct value member variable (struct Point~) main::$1_p1 +Created struct value member variable (struct Point~) main::$1_p2 +Converted struct value to member variables (struct Vector~) main::$1 Created struct value member variable (struct Point) get::return_p1 Created struct value member variable (struct Point) get::return_p2 Converted struct value to member variables (struct Vector) get::return @@ -13,18 +13,18 @@ Converted struct value to member variables (struct Vector) get::v Created struct value member variable (struct Point) print::v_p1 Created struct value member variable (struct Point) print::v_p2 Converted struct value to member variables (struct Vector) print::v -Created struct value member variable (byte~) main::$1_p1_x -Created struct value member variable (byte~) main::$1_p1_y -Converted struct value to member variables (struct Point~) main::$1_p1 -Created struct value member variable (byte~) main::$1_p2_x -Created struct value member variable (byte~) main::$1_p2_y -Converted struct value to member variables (struct Point~) main::$1_p2 Created struct value member variable (byte) main::v_p1_x Created struct value member variable (byte) main::v_p1_y Converted struct value to member variables (struct Point) main::v_p1 Created struct value member variable (byte) main::v_p2_x Created struct value member variable (byte) main::v_p2_y Converted struct value to member variables (struct Point) main::v_p2 +Created struct value member variable (byte~) main::$1_p1_x +Created struct value member variable (byte~) main::$1_p1_y +Converted struct value to member variables (struct Point~) main::$1_p1 +Created struct value member variable (byte~) main::$1_p2_x +Created struct value member variable (byte~) main::$1_p2_y +Converted struct value to member variables (struct Point~) main::$1_p2 Created struct value member variable (byte) get::return_p1_x Created struct value member variable (byte) get::return_p1_y Converted struct value to member variables (struct Point) get::return_p1 diff --git a/src/test/ref/screen-center-distance.log b/src/test/ref/screen-center-distance.log index f3f1bd47b..667f24a33 100644 --- a/src/test/ref/screen-center-distance.log +++ b/src/test/ref/screen-center-distance.log @@ -4406,8 +4406,8 @@ Uplift Scope [print_word_at] 955: zp[2]:2 [ print_word_at::w#2 print_word_at::w# Uplift Scope [print_dword_at] 71: zp[4]:54 [ print_dword_at::dw#0 ] Uplift Scope [clock] 37.33: zp[4]:60 [ clock::return#0 ] 22: zp[4]:42 [ clock::return#2 ] Uplift Scope [main] 22: zp[4]:46 [ main::$4 ] 22: zp[4]:50 [ main::cyclecount#0 ] -Uplift Scope [malloc] Uplift Scope [RADIX] +Uplift Scope [malloc] Uplift Scope [clock_start] Uplift Scope [] @@ -4425,8 +4425,8 @@ Uplifting [print_word_at] best 239596 combination zp[2]:2 [ print_word_at::w#2 p Uplifting [print_dword_at] best 239596 combination zp[4]:54 [ print_dword_at::dw#0 ] Uplifting [clock] best 239596 combination zp[4]:60 [ clock::return#0 ] zp[4]:42 [ clock::return#2 ] Uplifting [main] best 239596 combination zp[4]:46 [ main::$4 ] zp[4]:50 [ main::cyclecount#0 ] -Uplifting [malloc] best 239596 combination Uplifting [RADIX] best 239596 combination +Uplifting [malloc] best 239596 combination Uplifting [clock_start] best 239596 combination Uplifting [] best 239596 combination Attempting to uplift remaining variables inzp[1]:41 [ init_font_hex::idx#5 init_font_hex::idx#2 ] diff --git a/src/test/ref/semi-struct-2.asm b/src/test/ref/semi-struct-2.asm index 333662712..1cafc898d 100644 --- a/src/test/ref/semi-struct-2.asm +++ b/src/test/ref/semi-struct-2.asm @@ -20,6 +20,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" + .const KEY_SPACE = $3c // CIA#1 Port A: keyboard matrix columns and joystick #2 .label CIA1_PORT_A = $dc00 // CIA#1 Port B: keyboard matrix rows and joystick #1. @@ -28,7 +29,6 @@ .label CIA1_PORT_A_DDR = $dc02 // CIA #1 Port B data direction register. .label CIA1_PORT_B_DDR = $dc03 - .const KEY_SPACE = $3c // The size of a file ENTRY .const SIZEOF_ENTRY = $12 // The maximal number of files diff --git a/src/test/ref/semi-struct-2.log b/src/test/ref/semi-struct-2.log index af8ee3ff6..d650cb96c 100644 --- a/src/test/ref/semi-struct-2.log +++ b/src/test/ref/semi-struct-2.log @@ -5106,6 +5106,7 @@ Target platform is c64basic / MOS6502X :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + .const KEY_SPACE = $3c // CIA#1 Port A: keyboard matrix columns and joystick #2 .label CIA1_PORT_A = $dc00 // CIA#1 Port B: keyboard matrix rows and joystick #1. @@ -5114,7 +5115,6 @@ Target platform is c64basic / MOS6502X .label CIA1_PORT_A_DDR = $dc02 // CIA #1 Port B data direction register. .label CIA1_PORT_B_DDR = $dc03 - .const KEY_SPACE = $3c // The size of a file ENTRY .const SIZEOF_ENTRY = $12 // The maximal number of files @@ -7247,6 +7247,7 @@ ASSEMBLER BEFORE OPTIMIZATION :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + .const KEY_SPACE = $3c // CIA#1 Port A: keyboard matrix columns and joystick #2 .label CIA1_PORT_A = $dc00 // CIA#1 Port B: keyboard matrix rows and joystick #1. @@ -7255,7 +7256,6 @@ ASSEMBLER BEFORE OPTIMIZATION .label CIA1_PORT_A_DDR = $dc02 // CIA #1 Port B data direction register. .label CIA1_PORT_B_DDR = $dc03 - .const KEY_SPACE = $3c // The size of a file ENTRY .const SIZEOF_ENTRY = $12 // The maximal number of files @@ -9801,6 +9801,7 @@ Score: 4104 :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels + .const KEY_SPACE = $3c // CIA#1 Port A: keyboard matrix columns and joystick #2 .label CIA1_PORT_A = $dc00 // CIA#1 Port B: keyboard matrix rows and joystick #1. @@ -9809,7 +9810,6 @@ Score: 4104 .label CIA1_PORT_A_DDR = $dc02 // CIA #1 Port B data direction register. .label CIA1_PORT_B_DDR = $dc03 - .const KEY_SPACE = $3c // The size of a file ENTRY .const SIZEOF_ENTRY = $12 // The maximal number of files diff --git a/src/test/ref/sieve-min.log b/src/test/ref/sieve-min.log index 6b32d6452..fc4b46670 100644 --- a/src/test/ref/sieve-min.log +++ b/src/test/ref/sieve-min.log @@ -38,7 +38,6 @@ Culled Empty Block (label) @15 Culled Empty Block (label) @16 Culled Empty Block (label) @17 Culled Empty Block (label) @18 -Culled Empty Block (label) @19 Culled Empty Block (label) @20 Culled Empty Block (label) @21 Culled Empty Block (label) @22 @@ -46,6 +45,7 @@ Culled Empty Block (label) @23 Culled Empty Block (label) @24 Culled Empty Block (label) @25 Culled Empty Block (label) @26 +Culled Empty Block (label) @27 Culled Empty Block (label) @28 Culled Empty Block (label) @29 Culled Empty Block (label) @30 @@ -62,14 +62,6 @@ Culled Empty Block (label) @40 Culled Empty Block (label) @41 Culled Empty Block (label) @42 Culled Empty Block (label) @43 -Culled Empty Block (label) @44 -Culled Empty Block (label) @45 -Culled Empty Block (label) @46 -Culled Empty Block (label) @47 -Culled Empty Block (label) @48 -Culled Empty Block (label) @49 -Culled Empty Block (label) @50 -Culled Empty Block (label) @51 Culled Empty Block (label) main::@11 Culled Empty Block (label) main::@12 Culled Empty Block (label) main::@8 @@ -88,7 +80,7 @@ Culled Empty Block (label) main::@28 CONTROL FLOW GRAPH SSA @begin: scope:[] from - to:@27 + to:@19 (void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num) memset: scope:[memset] from main @@ -133,11 +125,11 @@ memset::@return: scope:[memset] from memset::@1 (void*) memset::return#1 ← (void*) memset::return#3 return to:@return -@27: scope:[] from @begin +@19: scope:[] from @begin (byte*) print_screen#0 ← (byte*)(number) $400 (byte*) print_line_cursor#0 ← (byte*) print_screen#0 (byte*) print_char_cursor#0 ← (byte*) print_line_cursor#0 - to:@52 + to:@44 (void()) print_word((word) print_word::w) print_word: scope:[print_word] from main::@21 @@ -205,8 +197,8 @@ print_char::@return: scope:[print_char] from print_char to:@return (void()) main() -main: scope:[main] from @52 - (byte*) print_char_cursor#38 ← phi( @52/(byte*) print_char_cursor#29 ) +main: scope:[main] from @44 + (byte*) print_char_cursor#38 ← phi( @44/(byte*) print_char_cursor#29 ) (void*) memset::str#0 ← (void*)(const byte*) sieve (byte) memset::c#0 ← (number) 0 (word) memset::num#0 ← (const nomodify word) COUNT @@ -324,20 +316,20 @@ main::@return: scope:[main] from main::@23 (byte*) print_char_cursor#11 ← (byte*) print_char_cursor#23 return to:@return -@52: scope:[] from @27 - (byte*) print_char_cursor#29 ← phi( @27/(byte*) print_char_cursor#0 ) +@44: scope:[] from @19 + (byte*) print_char_cursor#29 ← phi( @19/(byte*) print_char_cursor#0 ) call main - to:@53 -@53: scope:[] from @52 - (byte*) print_char_cursor#24 ← phi( @52/(byte*) print_char_cursor#11 ) + to:@45 +@45: scope:[] from @44 + (byte*) print_char_cursor#24 ← phi( @44/(byte*) print_char_cursor#11 ) (byte*) print_char_cursor#12 ← (byte*) print_char_cursor#24 to:@end -@end: scope:[] from @53 +@end: scope:[] from @45 SYMBOL TABLE SSA -(label) @27 -(label) @52 -(label) @53 +(label) @19 +(label) @44 +(label) @45 (label) @begin (label) @end (const nomodify word) COUNT = (word) $4000 @@ -716,9 +708,9 @@ Constant inlined main::sieve_i#0 = (const byte*) sieve+(word) 2 Successful SSA optimization Pass2ConstantInlining Added new block during phi lifting main::@32(between main::@16 and main::@18) Adding NOP phi() at start of @begin -Adding NOP phi() at start of @27 -Adding NOP phi() at start of @52 -Adding NOP phi() at start of @53 +Adding NOP phi() at start of @19 +Adding NOP phi() at start of @44 +Adding NOP phi() at start of @45 Adding NOP phi() at start of @end Adding NOP phi() at start of main Adding NOP phi() at start of main::@29 @@ -757,8 +749,8 @@ Coalesced [66] print_char::ch#5 ← print_char::ch#1 Coalesced (already) [67] print_char_cursor#47 ← print_char_cursor#20 Coalesced [79] memset::dst#4 ← memset::dst#1 Coalesced down to 9 phi equivalence classes -Culled Empty Block (label) @27 -Culled Empty Block (label) @53 +Culled Empty Block (label) @19 +Culled Empty Block (label) @45 Culled Empty Block (label) main::@29 Culled Empty Block (label) main::@3 Culled Empty Block (label) main::@23 @@ -768,7 +760,7 @@ Culled Empty Block (label) print_word::@2 Culled Empty Block (label) print_byte::@2 Culled Empty Block (label) memset::@2 Culled Empty Block (label) memset::@1 -Renumbering block @52 to @1 +Renumbering block @44 to @1 Renumbering block memset::@4 to memset::@1 Renumbering block memset::@5 to memset::@2 Renumbering block main::@4 to main::@3 diff --git a/src/test/ref/sieve.asm b/src/test/ref/sieve.asm index f5d54b96d..2d75db447 100644 --- a/src/test/ref/sieve.asm +++ b/src/test/ref/sieve.asm @@ -1,6 +1,15 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" + // Clock cycles per frame (on a C64 PAL) + .const CLOCKS_PER_FRAME = $4cc8 + // Frames per second (on a C64 PAL) + .const FRAMES_PER_SEC = $3c + // Clock cycles per second (on a C64 PAL) + .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC + // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. + // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. + .const CLOCKS_PER_INIT = $12 .label D018 = $d018 // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 @@ -12,15 +21,6 @@ .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 - // Clock cycles per frame (on a C64 PAL) - .const CLOCKS_PER_FRAME = $4cc8 - // Frames per second (on a C64 PAL) - .const FRAMES_PER_SEC = $3c - // Clock cycles per second (on a C64 PAL) - .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC - // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. - // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. - .const CLOCKS_PER_INIT = $12 .label SCREEN = $400 .const COUNT = $4000 /* Up to what number? */ diff --git a/src/test/ref/sieve.log b/src/test/ref/sieve.log index baef0b7c2..4689fdf36 100644 --- a/src/test/ref/sieve.log +++ b/src/test/ref/sieve.log @@ -3901,6 +3901,15 @@ Target platform is c64basic / MOS6502X :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + // Clock cycles per frame (on a C64 PAL) + .const CLOCKS_PER_FRAME = $4cc8 + // Frames per second (on a C64 PAL) + .const FRAMES_PER_SEC = $3c + // Clock cycles per second (on a C64 PAL) + .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC + // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. + // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. + .const CLOCKS_PER_INIT = $12 .label D018 = $d018 // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 @@ -3912,15 +3921,6 @@ Target platform is c64basic / MOS6502X .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 - // Clock cycles per frame (on a C64 PAL) - .const CLOCKS_PER_FRAME = $4cc8 - // Frames per second (on a C64 PAL) - .const FRAMES_PER_SEC = $3c - // Clock cycles per second (on a C64 PAL) - .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC - // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. - // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. - .const CLOCKS_PER_INIT = $12 .label SCREEN = $400 .const COUNT = $4000 /* Up to what number? */ @@ -5829,6 +5829,15 @@ ASSEMBLER BEFORE OPTIMIZATION :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + // Clock cycles per frame (on a C64 PAL) + .const CLOCKS_PER_FRAME = $4cc8 + // Frames per second (on a C64 PAL) + .const FRAMES_PER_SEC = $3c + // Clock cycles per second (on a C64 PAL) + .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC + // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. + // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. + .const CLOCKS_PER_INIT = $12 .label D018 = $d018 // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 @@ -5840,15 +5849,6 @@ ASSEMBLER BEFORE OPTIMIZATION .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 - // Clock cycles per frame (on a C64 PAL) - .const CLOCKS_PER_FRAME = $4cc8 - // Frames per second (on a C64 PAL) - .const FRAMES_PER_SEC = $3c - // Clock cycles per second (on a C64 PAL) - .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC - // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. - // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. - .const CLOCKS_PER_INIT = $12 .label SCREEN = $400 .const COUNT = $4000 /* Up to what number? */ @@ -7802,6 +7802,15 @@ Score: 83095 :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels + // Clock cycles per frame (on a C64 PAL) + .const CLOCKS_PER_FRAME = $4cc8 + // Frames per second (on a C64 PAL) + .const FRAMES_PER_SEC = $3c + // Clock cycles per second (on a C64 PAL) + .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC + // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. + // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. + .const CLOCKS_PER_INIT = $12 .label D018 = $d018 // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 @@ -7813,15 +7822,6 @@ Score: 83095 .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 - // Clock cycles per frame (on a C64 PAL) - .const CLOCKS_PER_FRAME = $4cc8 - // Frames per second (on a C64 PAL) - .const FRAMES_PER_SEC = $3c - // Clock cycles per second (on a C64 PAL) - .const CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC - // Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine. - // To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code. - .const CLOCKS_PER_INIT = $12 .label SCREEN = $400 .const COUNT = $4000 /* Up to what number? */ diff --git a/src/test/ref/test-keyboard-space.asm b/src/test/ref/test-keyboard-space.asm index a67cc6008..19d0d0111 100644 --- a/src/test/ref/test-keyboard-space.asm +++ b/src/test/ref/test-keyboard-space.asm @@ -2,6 +2,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" + .const KEY_SPACE = $3c .label RASTER = $d012 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -14,7 +15,6 @@ .label CIA1_PORT_B_DDR = $dc03 .const GREEN = 5 .const BLUE = 6 - .const KEY_SPACE = $3c main: { // keyboard_init() jsr keyboard_init diff --git a/src/test/ref/test-keyboard-space.log b/src/test/ref/test-keyboard-space.log index 73e5dc48e..f946c346b 100644 --- a/src/test/ref/test-keyboard-space.log +++ b/src/test/ref/test-keyboard-space.log @@ -392,6 +392,7 @@ Target platform is c64basic / MOS6502X :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + .const KEY_SPACE = $3c .label RASTER = $d012 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -404,7 +405,6 @@ Target platform is c64basic / MOS6502X .label CIA1_PORT_B_DDR = $dc03 .const GREEN = 5 .const BLUE = 6 - .const KEY_SPACE = $3c // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -582,6 +582,7 @@ ASSEMBLER BEFORE OPTIMIZATION :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels + .const KEY_SPACE = $3c .label RASTER = $d012 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -594,7 +595,6 @@ ASSEMBLER BEFORE OPTIMIZATION .label CIA1_PORT_B_DDR = $dc03 .const GREEN = 5 .const BLUE = 6 - .const KEY_SPACE = $3c // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -814,6 +814,7 @@ Score: 1141 :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels + .const KEY_SPACE = $3c .label RASTER = $d012 .label BGCOL = $d021 // CIA#1 Port A: keyboard matrix columns and joystick #2 @@ -826,7 +827,6 @@ Score: 1141 .label CIA1_PORT_B_DDR = $dc03 .const GREEN = 5 .const BLUE = 6 - .const KEY_SPACE = $3c // @begin // [1] phi from @begin to @1 [phi:@begin->@1] // @1 diff --git a/src/test/ref/test-keyboard.asm b/src/test/ref/test-keyboard.asm index d78ba465d..21612e23e 100644 --- a/src/test/ref/test-keyboard.asm +++ b/src/test/ref/test-keyboard.asm @@ -2,15 +2,6 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .label RASTER = $d012 - // CIA#1 Port A: keyboard matrix columns and joystick #2 - .label CIA1_PORT_A = $dc00 - // CIA#1 Port B: keyboard matrix rows and joystick #1. - .label CIA1_PORT_B = $dc01 - // CIA #1 Port A data direction register. - .label CIA1_PORT_A_DDR = $dc02 - // CIA #1 Port B data direction register. - .label CIA1_PORT_B_DDR = $dc03 .const KEY_3 = 8 .const KEY_W = 9 .const KEY_A = $a @@ -61,6 +52,15 @@ .const KEY_2 = $3b .const KEY_SPACE = $3c .const KEY_Q = $3e + .label RASTER = $d012 + // CIA#1 Port A: keyboard matrix columns and joystick #2 + .label CIA1_PORT_A = $dc00 + // CIA#1 Port B: keyboard matrix rows and joystick #1. + .label CIA1_PORT_B = $dc01 + // CIA #1 Port A data direction register. + .label CIA1_PORT_A_DDR = $dc02 + // CIA #1 Port B data direction register. + .label CIA1_PORT_B_DDR = $dc03 main: { .label sc = 2 .label screen = 5 diff --git a/src/test/ref/test-keyboard.log b/src/test/ref/test-keyboard.log index 24eaf2e0c..716c18f58 100644 --- a/src/test/ref/test-keyboard.log +++ b/src/test/ref/test-keyboard.log @@ -1002,15 +1002,6 @@ Target platform is c64basic / MOS6502X :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels - .label RASTER = $d012 - // CIA#1 Port A: keyboard matrix columns and joystick #2 - .label CIA1_PORT_A = $dc00 - // CIA#1 Port B: keyboard matrix rows and joystick #1. - .label CIA1_PORT_B = $dc01 - // CIA #1 Port A data direction register. - .label CIA1_PORT_A_DDR = $dc02 - // CIA #1 Port B data direction register. - .label CIA1_PORT_B_DDR = $dc03 .const KEY_3 = 8 .const KEY_W = 9 .const KEY_A = $a @@ -1061,6 +1052,15 @@ Target platform is c64basic / MOS6502X .const KEY_2 = $3b .const KEY_SPACE = $3c .const KEY_Q = $3e + .label RASTER = $d012 + // CIA#1 Port A: keyboard matrix columns and joystick #2 + .label CIA1_PORT_A = $dc00 + // CIA#1 Port B: keyboard matrix rows and joystick #1. + .label CIA1_PORT_B = $dc01 + // CIA #1 Port A data direction register. + .label CIA1_PORT_A_DDR = $dc02 + // CIA #1 Port B data direction register. + .label CIA1_PORT_B_DDR = $dc03 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -1578,15 +1578,6 @@ ASSEMBLER BEFORE OPTIMIZATION :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels - .label RASTER = $d012 - // CIA#1 Port A: keyboard matrix columns and joystick #2 - .label CIA1_PORT_A = $dc00 - // CIA#1 Port B: keyboard matrix rows and joystick #1. - .label CIA1_PORT_B = $dc01 - // CIA #1 Port A data direction register. - .label CIA1_PORT_A_DDR = $dc02 - // CIA #1 Port B data direction register. - .label CIA1_PORT_B_DDR = $dc03 .const KEY_3 = 8 .const KEY_W = 9 .const KEY_A = $a @@ -1637,6 +1628,15 @@ ASSEMBLER BEFORE OPTIMIZATION .const KEY_2 = $3b .const KEY_SPACE = $3c .const KEY_Q = $3e + .label RASTER = $d012 + // CIA#1 Port A: keyboard matrix columns and joystick #2 + .label CIA1_PORT_A = $dc00 + // CIA#1 Port B: keyboard matrix rows and joystick #1. + .label CIA1_PORT_B = $dc01 + // CIA #1 Port A data direction register. + .label CIA1_PORT_A_DDR = $dc02 + // CIA #1 Port B data direction register. + .label CIA1_PORT_B_DDR = $dc03 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] @@ -2262,15 +2262,6 @@ Score: 57707 :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels - .label RASTER = $d012 - // CIA#1 Port A: keyboard matrix columns and joystick #2 - .label CIA1_PORT_A = $dc00 - // CIA#1 Port B: keyboard matrix rows and joystick #1. - .label CIA1_PORT_B = $dc01 - // CIA #1 Port A data direction register. - .label CIA1_PORT_A_DDR = $dc02 - // CIA #1 Port B data direction register. - .label CIA1_PORT_B_DDR = $dc03 .const KEY_3 = 8 .const KEY_W = 9 .const KEY_A = $a @@ -2321,6 +2312,15 @@ Score: 57707 .const KEY_2 = $3b .const KEY_SPACE = $3c .const KEY_Q = $3e + .label RASTER = $d012 + // CIA#1 Port A: keyboard matrix columns and joystick #2 + .label CIA1_PORT_A = $dc00 + // CIA#1 Port B: keyboard matrix rows and joystick #1. + .label CIA1_PORT_B = $dc01 + // CIA #1 Port A data direction register. + .label CIA1_PORT_A_DDR = $dc02 + // CIA #1 Port B data direction register. + .label CIA1_PORT_B_DDR = $dc03 // @begin // [1] phi from @begin to @1 [phi:@begin->@1] // @1