1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-26 18:29:54 +00:00

Created font 2x2 to sprite converter. Improved a few bitwise operators.

This commit is contained in:
jespergravgaard 2020-03-30 22:39:39 +02:00
parent beb30de7d1
commit 91da76e087
6 changed files with 90 additions and 22 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<num_chars;c++) {
// Upper char
char * char_left = char_current;
char * char_right = char_current + 0x40*8;
char sprite_idx = 0;
for(char i: 0..20) {
sprite[sprite_idx++] = char_left[i&7];
sprite[sprite_idx++] = char_right[i&7];
sprite[sprite_idx++] = 0x00;
if(i==7) {
// Lower char
char_left = char_current + 0x80*8;
char_right = char_current + 0xc0*8;
} else if(i==15) {
// Empty char
char_left = font_2x2+' '*8;
char_right = font_2x2+' '*8;
}
}
char_current += 8;
sprite += 0x40;
}
}