From 91da76e087a4fc70778c5ceb022d3176a9bf7e5d Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 30 Mar 2020 22:39:39 +0200 Subject: [PATCH] Created font 2x2 to sprite converter. Improved a few bitwise operators. --- .../model/operators/OperatorBitwiseAnd.java | 9 +-- .../model/operators/OperatorBitwiseOr.java | 13 ++++- .../model/operators/OperatorBitwiseXor.java | 8 ++- .../kickc/model/operators/OperatorPlus.java | 22 +++----- .../dk/camelot64/kickc/test/TestPrograms.java | 5 ++ .../kc/complex/elefont/elefont-sprites.kc | 55 +++++++++++++++++++ 6 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 src/test/kc/complex/elefont/elefont-sprites.kc diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java index 9fef8972e..5d44e8a60 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java @@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.values.ConstantEnumerable; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantPointer; @@ -15,10 +16,10 @@ public class OperatorBitwiseAnd extends OperatorBinary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { - if(left instanceof ConstantInteger && right instanceof ConstantInteger) { - return new ConstantInteger(((ConstantInteger) left).getInteger() & ((ConstantInteger) right).getInteger()); - } else if(left instanceof ConstantPointer && right instanceof ConstantInteger) { - return new ConstantPointer(((ConstantPointer) left).getLocation() & ((ConstantInteger) right).getInteger(), ((ConstantPointer) left).getElementType()); + if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) { + return new ConstantPointer(((ConstantPointer) left).getLocation() & ((ConstantEnumerable) right).getInteger(), ((ConstantPointer) left).getElementType()); + } else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) { + return new ConstantInteger(((ConstantEnumerable)left).getInteger() & ((ConstantEnumerable) right).getInteger()); } throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseOr.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseOr.java index 9a0309952..4b08dacac 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseOr.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseOr.java @@ -1,9 +1,14 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; +import dk.camelot64.kickc.model.types.SymbolTypeInteger; +import dk.camelot64.kickc.model.types.SymbolTypePointer; +import dk.camelot64.kickc.model.values.ConstantEnumerable; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; +import dk.camelot64.kickc.model.values.ConstantPointer; /** Binary bitwise or Operator ( x | y ) */ public class OperatorBitwiseOr extends OperatorBinary { @@ -14,8 +19,10 @@ public class OperatorBitwiseOr extends OperatorBinary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { - if(left instanceof ConstantInteger && right instanceof ConstantInteger) { - return new ConstantInteger(((ConstantInteger) left).getInteger() | ((ConstantInteger) right).getInteger()); + if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) { + return new ConstantPointer(((ConstantPointer) left).getLocation() | ((ConstantEnumerable) right).getInteger(), ((ConstantPointer) left).getElementType()); + } else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) { + return new ConstantInteger(((ConstantEnumerable) left).getInteger() | ((ConstantEnumerable) right).getInteger()); } throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseXor.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseXor.java index 8c4d71d4a..39dba810e 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseXor.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseXor.java @@ -2,8 +2,10 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.values.ConstantEnumerable; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; +import dk.camelot64.kickc.model.values.ConstantPointer; /** Binary bitwise exclusive or Operator ( x ^ y ) */ public class OperatorBitwiseXor extends OperatorBinary { @@ -14,8 +16,10 @@ public class OperatorBitwiseXor extends OperatorBinary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { - if(left instanceof ConstantInteger && right instanceof ConstantInteger) { - return new ConstantInteger(((ConstantInteger) left).getInteger() ^ ((ConstantInteger) right).getInteger()); + if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) { + return new ConstantPointer(((ConstantPointer) left).getLocation() ^ ((ConstantEnumerable) right).getInteger(), ((ConstantPointer) left).getElementType()); + } else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) { + return new ConstantInteger(((ConstantEnumerable) left).getInteger() ^ ((ConstantEnumerable) right).getInteger()); } throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java index d771f874b..3f34fad90 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java @@ -2,7 +2,10 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.ConstantNotLiteral; -import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; +import dk.camelot64.kickc.model.types.SymbolTypeInteger; +import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.values.*; /** Binary plus Operator ( x + y ) */ @@ -14,18 +17,11 @@ public class OperatorPlus extends OperatorBinary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { - if(left instanceof ConstantInteger && right instanceof ConstantInteger) { - return new ConstantInteger(((ConstantInteger) left).getInteger() + ((ConstantInteger) right).getInteger()); - } else if(left instanceof ConstantInteger && right instanceof ConstantChar) { - return new ConstantInteger(((ConstantInteger) left).getInteger() + ((ConstantChar) right).getChar()); - } else if(left instanceof ConstantChar && right instanceof ConstantInteger) { - return new ConstantInteger(((ConstantChar) left).getChar() + ((ConstantInteger) right).getInteger()); - } else if(left instanceof ConstantPointer && right instanceof ConstantInteger) { - long location = ((ConstantPointer) left).getLocation() + ((ConstantInteger) right).getInteger(); + if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) { + long location = ((ConstantPointer) left).getLocation() + ((ConstantEnumerable) right).getInteger(); return new ConstantPointer(location, ((ConstantPointer) left).getElementType()); - } else if(left instanceof ConstantInteger && right instanceof ConstantPointer) { - long location = ((ConstantPointer) right).getLocation() + ((ConstantInteger) left).getInteger(); - return new ConstantPointer(location, ((ConstantPointer) right).getElementType()); + } else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) { + return new ConstantInteger(((ConstantEnumerable) left).getInteger() + ((ConstantEnumerable) right).getInteger()); } else if(left instanceof ConstantString && right instanceof ConstantInteger) { throw new ConstantNotLiteral("String pointer not literal"); } @@ -42,7 +38,7 @@ public class OperatorPlus extends OperatorBinary { } // Handle numeric types through proper promotion if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) { - return SymbolTypeConversion.convertedMathType( (SymbolTypeInteger) type1, (SymbolTypeInteger)type2); + return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2); } throw new CompileError("Type inference case not handled " + type1 + " " + getOperator() + " " + type2); diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index d6b85ef97..9a33350f9 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -198,6 +198,11 @@ public class TestPrograms { assertError("constant-prepost", "Constant value contains a pre/post-modifier"); } + //@Test + //public void testElefont() throws IOException, URISyntaxException { + // compileAndCompare("complex/elefont/elefont-sprites", log()); + //} + @Test public void testGridBobs() throws IOException, URISyntaxException { compileAndCompare("complex/prebob/grid-bobs"); diff --git a/src/test/kc/complex/elefont/elefont-sprites.kc b/src/test/kc/complex/elefont/elefont-sprites.kc new file mode 100644 index 000000000..d75036338 --- /dev/null +++ b/src/test/kc/complex/elefont/elefont-sprites.kc @@ -0,0 +1,55 @@ +// Put a 2x2 font into sprites and show on screen + +import "c64" + +char * const CHARSET_DEFAULT = 0x1000; +char * const ELEFONT = 0x2000; +char * const SPRITES = 0x3000; +char * const SCREEN = 0x0400; +char * const SCREEN_SPRITES = SCREEN + SPRITE_PTRS; + + +kickasm(pc ELEFONT, resource "elefont.bin") {{ + .import binary "elefont.bin" +}} + +void main() { + *D018 = toD018(SCREEN, CHARSET_DEFAULT); + font_2x2_to_sprites(ELEFONT, SPRITES, 64); + *SPRITES_ENABLE = 1; + SPRITES_XPOS[0] = 100; + SPRITES_YPOS[0] = 100; + SPRITES_COLS[0] = WHITE; + SCREEN_SPRITES[0] = toSpritePtr(SPRITES)+1; +} + +// Convert a 2x2-font to sprites +// - font_2x2 The source 2x2-font +// - sprites The destination sprites +// - num_chars The number of chars to convert +void font_2x2_to_sprites(char* font_2x2, char* sprites, char num_chars) { + char * char_current = font_2x2; + char * sprite = sprites; + for(char c=0;c