1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Working on bitmap bresenham. Added lo/hi unary operators.

This commit is contained in:
jespergravgaard 2017-10-26 12:48:04 +02:00
parent 7def3abf28
commit f60be66531
17 changed files with 261 additions and 120 deletions

View File

@ -256,12 +256,12 @@ public class Compiler {
// Attempt uplifting registers through a lot of combinations
//program.getLog().setVerboseUplift(true);
new Pass4RegisterUpliftCombinations(program).performUplift(10_000);
new Pass4RegisterUpliftCombinations(program).performUplift(200_000);
//new Pass4RegisterUpliftStatic(program).performUplift();
// Attempt uplifting registers one at a time to catch remaining potential not realized by combination search
new Pass4RegisterUpliftRemains(program).performUplift(10_000);
new Pass4RegisterUpliftRemains(program).performUplift(100_000);
// Final register coalesce and finalization
new Pass4ZeroPageCoalesce(program).allocate();

View File

@ -1,5 +1,5 @@
Known Problems
- Increment/decrement of value pointed to by piinter does not work. eg. byte* BGCOL = $d020; (*BGCOL)++;
- Increment/decrement of value pointed to by pointer does not work. eg. byte* BGCOL = $d020; (*BGCOL)++;
- Arrays / strings allocated inline destroy functions (because they are allocated where the call enters.
- Classic for() does not allow assignment as increment, eg. for(byte i=0;i<25;i=i+2) {}
@ -7,8 +7,7 @@ Features
- Move the main code into a main() function, and disallow code outside functions. The main function per default has no parameters and exits with RTS.
- Improve locality of block sequence for if(cond) { stmt1; } else { stmt2; } to if(!cond) goto @else stmt1; jmp @end; @else: stmt2; @end:
- Optimize if/else by swapping if & else if cond is easier to evaluate than !cond.
- Add signed bytes
- Add signed words
- Add signed bytes / words
- Add Fixed Point number types fixed[8.8], fixed[16.8] - maybe even fixed[24.4]
- Add imports
- Add structs
@ -24,6 +23,8 @@ Features
- Remove unused functions.
- Support calculated pointers eg. *(ptr+i)
- Add syntax for encoded chars (eg. PETSCII instead of SCREEN)
- Add support for casting. Specifically casting a byte* to a word (to enable calculating D018-value from pointer to bitmap & screen.)
- Add UpliftRemains support for attempting to uplift potentials to ALU (requires modifying two registers: 1. the ALU potential to ALU - the one added to the ALU potential to A.)
Arrays / Strings / Inline data
- New semantic: Arrays are always allocated inline (and must therefore have a size). Pointers are never.

View File

@ -239,9 +239,17 @@ public class AsmFragment {
case "!=":
return "_neq_";
case "<":
return "_lt_";
if(operator.getType().equals(Operator.Type.UNARY)) {
return "_lo_";
} else {
return "_lt_";
}
case ">":
return "_gt_";
if(operator.getType().equals(Operator.Type.UNARY)) {
return "_hi_";
} else {
return "_gt_";
}
case "<=":
case "=<":
return "_le_";

View File

@ -0,0 +1 @@
lda >{zpptrby1}

View File

@ -0,0 +1 @@
lda <{zpptrby1}

View File

@ -0,0 +1,4 @@
lda #{coby1}
sta {zpptrby1}
lda #0
sta {zpptrby1}+1

View File

@ -74,6 +74,10 @@ public class Operator {
return BOOL_NOT;
case "*":
return STAR;
case "<":
return LOWBYTE;
case ">":
return HIBYTE;
default:
throw new RuntimeException("Unknown operator " + op);
}
@ -90,6 +94,8 @@ public class Operator {
public static Operator BOOL_NOT = new Operator("~", Type.UNARY, 2);
public static Operator NOT = new Operator("!", Type.UNARY, 2);
public static Operator STAR = new Operator("*", Type.UNARY, 2);
public static Operator LOWBYTE = new Operator("<", Type.UNARY, 2);
public static Operator HIBYTE = new Operator(">", Type.UNARY, 2);
public static Operator STAR_IDX = new Operator("*idx", Type.BINARY, 2);
public static Operator MULTIPLY = new Operator("*", Type.BINARY, 3);
public static Operator DIVIDE = new Operator("/", Type.BINARY, 3);
@ -117,6 +123,10 @@ public class Operator {
return precedence;
}
public Type getType() {
return type;
}
@Override
public String toString() {
return operator;

View File

@ -15,6 +15,12 @@ public class SymbolTypeInference {
} else {
throw new RuntimeException("Type error: Dereferencing a non-pointer "+subType);
}
case "<":
case ">":
if(subType instanceof SymbolTypePointer || SymbolTypeBasic.WORD.equals(subType)) {
return SymbolTypeBasic.BYTE;
}
default:
return subType;
}
@ -75,6 +81,9 @@ public class SymbolTypeInference {
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
case "/":
if (type1 instanceof SymbolTypePointer && SymbolTypeBasic.BYTE.equals(type2)) {
return type1;
}
case "&":
case "|":
case "^":
@ -83,6 +92,7 @@ public class SymbolTypeInference {
} else if (SymbolTypeBasic.BYTE.equals(type1) && SymbolTypeBasic.BYTE.equals(type2)) {
return SymbolTypeBasic.BYTE;
}
throw new RuntimeException("Type inference case not handled " + type1 + " " + operator + " " + type2);
case "<<":
case ">>":

View File

@ -62,7 +62,7 @@ expr
| expr '[' expr ']' #exprArray
| ('--' | '++' ) expr #exprPreMod
| expr ('--' | '++' )#exprPostMod
| ('+' | '-' | 'not' | '!' | '&' | '*' | '~' ) expr #exprUnary
| ('+' | '-' | 'not' | '!' | '&' | '*' | '~' | '<' | '>') expr #exprUnary
| expr ('>>' | '<<' ) expr #exprBinary
| expr ('*' | '/' | '%' ) expr #exprBinary
| expr ( '+' | '-') expr #exprBinary

View File

@ -88,19 +88,19 @@ COMMENT_BLOCK=63
'!'=25
'&'=26
'~'=27
'>>'=28
'<<'=29
'/'=30
'%'=31
'=='=32
'!='=33
'<>'=34
'<'=35
'<='=36
'=<'=37
'>='=38
'=>'=39
'>'=40
'<'=28
'>'=29
'>>'=30
'<<'=31
'/'=32
'%'=33
'=='=34
'!='=35
'<>'=36
'<='=37
'=<'=38
'>='=39
'=>'=40
'^'=41
'|'=42
'and'=43

View File

@ -49,9 +49,9 @@ public class KickCLexer extends Lexer {
private static final String[] _LITERAL_NAMES = {
null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'",
"'while'", "'do'", "'for'", "'return'", "':'", "'..'", "','", "'*'", "'['",
"']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'>>'",
"'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<'", "'<='", "'=<'", "'>='",
"'=>'", "'>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'"
"']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'<'",
"'>'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'",
"'>='", "'=>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
@ -134,10 +134,10 @@ public class KickCLexer extends Lexer {
"\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\21\3\21"+
"\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3\26\3\27\3\27"+
"\3\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35"+
"\3\35\3\36\3\36\3\36\3\37\3\37\3 \3 \3!\3!\3!\3\"\3\"\3\"\3#\3#\3#\3$"+
"\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3*\3*\3+\3+\3,\3,\3,"+
"\3,\3-\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60"+
"\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\5\60\u0122\n\60"+
"\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3!\3!\3\"\3\"\3#\3#\3#\3$\3$\3$\3%"+
"\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3*\3*\3+\3+\3,\3,\3,\3,"+
"\3-\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3"+
"\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\5\60\u0122\n\60"+
"\3\61\3\61\3\61\3\61\7\61\u0128\n\61\f\61\16\61\u012b\13\61\3\61\3\61"+
"\3\62\3\62\3\62\3\62\5\62\u0133\n\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63"+
"\3\63\3\63\3\63\3\63\5\63\u0140\n\63\3\64\3\64\5\64\u0144\n\64\3\65\3"+
@ -174,9 +174,9 @@ public class KickCLexer extends Lexer {
"\37\u00bb\3\2\2\2!\u00be\3\2\2\2#\u00c0\3\2\2\2%\u00c2\3\2\2\2\'\u00c4"+
"\3\2\2\2)\u00c6\3\2\2\2+\u00c9\3\2\2\2-\u00cc\3\2\2\2/\u00ce\3\2\2\2\61"+
"\u00d0\3\2\2\2\63\u00d4\3\2\2\2\65\u00d6\3\2\2\2\67\u00d8\3\2\2\29\u00da"+
"\3\2\2\2;\u00dd\3\2\2\2=\u00e0\3\2\2\2?\u00e2\3\2\2\2A\u00e4\3\2\2\2C"+
"\u00e7\3\2\2\2E\u00ea\3\2\2\2G\u00ed\3\2\2\2I\u00ef\3\2\2\2K\u00f2\3\2"+
"\2\2M\u00f5\3\2\2\2O\u00f8\3\2\2\2Q\u00fb\3\2\2\2S\u00fd\3\2\2\2U\u00ff"+
"\3\2\2\2;\u00dc\3\2\2\2=\u00de\3\2\2\2?\u00e1\3\2\2\2A\u00e4\3\2\2\2C"+
"\u00e6\3\2\2\2E\u00e8\3\2\2\2G\u00eb\3\2\2\2I\u00ee\3\2\2\2K\u00f1\3\2"+
"\2\2M\u00f4\3\2\2\2O\u00f7\3\2\2\2Q\u00fa\3\2\2\2S\u00fd\3\2\2\2U\u00ff"+
"\3\2\2\2W\u0101\3\2\2\2Y\u0105\3\2\2\2[\u0108\3\2\2\2]\u010b\3\2\2\2_"+
"\u0121\3\2\2\2a\u0123\3\2\2\2c\u012e\3\2\2\2e\u013f\3\2\2\2g\u0143\3\2"+
"\2\2i\u0148\3\2\2\2k\u014f\3\2\2\2m\u0160\3\2\2\2o\u016e\3\2\2\2q\u017f"+
@ -203,65 +203,65 @@ public class KickCLexer extends Lexer {
".\3\2\2\2\u00ce\u00cf\7/\2\2\u00cf\60\3\2\2\2\u00d0\u00d1\7p\2\2\u00d1"+
"\u00d2\7q\2\2\u00d2\u00d3\7v\2\2\u00d3\62\3\2\2\2\u00d4\u00d5\7#\2\2\u00d5"+
"\64\3\2\2\2\u00d6\u00d7\7(\2\2\u00d7\66\3\2\2\2\u00d8\u00d9\7\u0080\2"+
"\2\u00d98\3\2\2\2\u00da\u00db\7@\2\2\u00db\u00dc\7@\2\2\u00dc:\3\2\2\2"+
"\u00dd\u00de\7>\2\2\u00de\u00df\7>\2\2\u00df<\3\2\2\2\u00e0\u00e1\7\61"+
"\2\2\u00e1>\3\2\2\2\u00e2\u00e3\7\'\2\2\u00e3@\3\2\2\2\u00e4\u00e5\7?"+
"\2\2\u00e5\u00e6\7?\2\2\u00e6B\3\2\2\2\u00e7\u00e8\7#\2\2\u00e8\u00e9"+
"\7?\2\2\u00e9D\3\2\2\2\u00ea\u00eb\7>\2\2\u00eb\u00ec\7@\2\2\u00ecF\3"+
"\2\2\2\u00ed\u00ee\7>\2\2\u00eeH\3\2\2\2\u00ef\u00f0\7>\2\2\u00f0\u00f1"+
"\7?\2\2\u00f1J\3\2\2\2\u00f2\u00f3\7?\2\2\u00f3\u00f4\7>\2\2\u00f4L\3"+
"\2\2\2\u00f5\u00f6\7@\2\2\u00f6\u00f7\7?\2\2\u00f7N\3\2\2\2\u00f8\u00f9"+
"\7?\2\2\u00f9\u00fa\7@\2\2\u00faP\3\2\2\2\u00fb\u00fc\7@\2\2\u00fcR\3"+
"\2\2\2\u00fd\u00fe\7`\2\2\u00feT\3\2\2\2\u00ff\u0100\7~\2\2\u0100V\3\2"+
"\2\2\u0101\u0102\7c\2\2\u0102\u0103\7p\2\2\u0103\u0104\7f\2\2\u0104X\3"+
"\2\2\2\u0105\u0106\7(\2\2\u0106\u0107\7(\2\2\u0107Z\3\2\2\2\u0108\u0109"+
"\7q\2\2\u0109\u010a\7t\2\2\u010a\\\3\2\2\2\u010b\u010c\7~\2\2\u010c\u010d"+
"\7~\2\2\u010d^\3\2\2\2\u010e\u010f\7d\2\2\u010f\u0110\7{\2\2\u0110\u0111"+
"\7v\2\2\u0111\u0122\7g\2\2\u0112\u0113\7y\2\2\u0113\u0114\7q\2\2\u0114"+
"\u0115\7t\2\2\u0115\u0122\7f\2\2\u0116\u0117\7d\2\2\u0117\u0118\7q\2\2"+
"\u0118\u0119\7q\2\2\u0119\u011a\7n\2\2\u011a\u011b\7g\2\2\u011b\u011c"+
"\7c\2\2\u011c\u0122\7p\2\2\u011d\u011e\7x\2\2\u011e\u011f\7q\2\2\u011f"+
"\u0120\7k\2\2\u0120\u0122\7f\2\2\u0121\u010e\3\2\2\2\u0121\u0112\3\2\2"+
"\2\u0121\u0116\3\2\2\2\u0121\u011d\3\2\2\2\u0122`\3\2\2\2\u0123\u0129"+
"\7$\2\2\u0124\u0125\7^\2\2\u0125\u0128\7$\2\2\u0126\u0128\n\2\2\2\u0127"+
"\u0124\3\2\2\2\u0127\u0126\3\2\2\2\u0128\u012b\3\2\2\2\u0129\u0127\3\2"+
"\2\2\u0129\u012a\3\2\2\2\u012a\u012c\3\2\2\2\u012b\u0129\3\2\2\2\u012c"+
"\u012d\7$\2\2\u012db\3\2\2\2\u012e\u0132\7)\2\2\u012f\u0130\7^\2\2\u0130"+
"\u0133\7)\2\2\u0131\u0133\n\3\2\2\u0132\u012f\3\2\2\2\u0132\u0131\3\2"+
"\2\2\u0133\u0134\3\2\2\2\u0134\u0135\7)\2\2\u0135d\3\2\2\2\u0136\u0137"+
"\7v\2\2\u0137\u0138\7t\2\2\u0138\u0139\7w\2\2\u0139\u0140\7g\2\2\u013a"+
"\u013b\7h\2\2\u013b\u013c\7c\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2"+
"\u013e\u0140\7g\2\2\u013f\u0136\3\2\2\2\u013f\u013a\3\2\2\2\u0140f\3\2"+
"\2\2\u0141\u0144\5i\65\2\u0142\u0144\5q9\2\u0143\u0141\3\2\2\2\u0143\u0142"+
"\3\2\2\2\u0144h\3\2\2\2\u0145\u0149\5k\66\2\u0146\u0149\5m\67\2\u0147"+
"\u0149\5o8\2\u0148\u0145\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0147\3\2\2"+
"\2\u0149j\3\2\2\2\u014a\u0150\7\'\2\2\u014b\u014c\7\62\2\2\u014c\u0150"+
"\7d\2\2\u014d\u014e\7\62\2\2\u014e\u0150\7D\2\2\u014f\u014a\3\2\2\2\u014f"+
"\u014b\3\2\2\2\u014f\u014d\3\2\2\2\u0150\u0154\3\2\2\2\u0151\u0153\5y"+
"=\2\u0152\u0151\3\2\2\2\u0153\u0156\3\2\2\2\u0154\u0152\3\2\2\2\u0154"+
"\u0155\3\2\2\2\u0155\u0157\3\2\2\2\u0156\u0154\3\2\2\2\u0157\u0159\7\60"+
"\2\2\u0158\u015a\5y=\2\u0159\u0158\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u0159"+
"\3\2\2\2\u015b\u015c\3\2\2\2\u015cl\3\2\2\2\u015d\u015f\5{>\2\u015e\u015d"+
"\3\2\2\2\u015f\u0162\3\2\2\2\u0160\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161"+
"\u0163\3\2\2\2\u0162\u0160\3\2\2\2\u0163\u0165\7\60\2\2\u0164\u0166\5"+
"{>\2\u0165\u0164\3\2\2\2\u0166\u0167\3\2\2\2\u0167\u0165\3\2\2\2\u0167"+
"\u0168\3\2\2\2\u0168n\3\2\2\2\u0169\u016f\7&\2\2\u016a\u016b\7\62\2\2"+
"\u016b\u016f\7z\2\2\u016c\u016d\7\62\2\2\u016d\u016f\7Z\2\2\u016e\u0169"+
"\3\2\2\2\u016e\u016a\3\2\2\2\u016e\u016c\3\2\2\2\u016f\u0173\3\2\2\2\u0170"+
"\u0172\5}?\2\u0171\u0170\3\2\2\2\u0172\u0175\3\2\2\2\u0173\u0171\3\2\2"+
"\2\u0173\u0174\3\2\2\2\u0174\u0176\3\2\2\2\u0175\u0173\3\2\2\2\u0176\u0178"+
"\7\60\2\2\u0177\u0179\5}?\2\u0178\u0177\3\2\2\2\u0179\u017a\3\2\2\2\u017a"+
"\u0178\3\2\2\2\u017a\u017b\3\2\2\2\u017bp\3\2\2\2\u017c\u0180\5u;\2\u017d"+
"\u0180\5w<\2\u017e\u0180\5s:\2\u017f\u017c\3\2\2\2\u017f\u017d\3\2\2\2"+
"\u017f\u017e\3\2\2\2\u0180r\3\2\2\2\u0181\u0182\7\62\2\2\u0182\u0184\t"+
"\4\2\2\u0183\u0185\5y=\2\u0184\u0183\3\2\2\2\u0185\u0186\3\2\2\2\u0186"+
"\u0184\3\2\2\2\u0186\u0187\3\2\2\2\u0187\u018f\3\2\2\2\u0188\u018a\7\'"+
"\2\2\u0189\u018b\5y=\2\u018a\u0189\3\2\2\2\u018b\u018c\3\2\2\2\u018c\u018a"+
"\3\2\2\2\u018c\u018d\3\2\2\2\u018d\u018f\3\2\2\2\u018e\u0181\3\2\2\2\u018e"+
"\u0188\3\2\2\2\u018ft\3\2\2\2\u0190\u0192\5{>\2\u0191\u0190\3\2\2\2\u0192"+
"\u0193\3\2\2\2\u0193\u0191\3\2\2\2\u0193\u0194\3\2\2\2\u0194v\3\2\2\2"+
"\u0195\u019b\7&\2\2\u0196\u0197\7\62\2\2\u0197\u019b\7z\2\2\u0198\u0199"+
"\7\62\2\2\u0199\u019b\7Z\2\2\u019a\u0195\3\2\2\2\u019a\u0196\3\2\2\2\u019a"+
"\2\u00d98\3\2\2\2\u00da\u00db\7>\2\2\u00db:\3\2\2\2\u00dc\u00dd\7@\2\2"+
"\u00dd<\3\2\2\2\u00de\u00df\7@\2\2\u00df\u00e0\7@\2\2\u00e0>\3\2\2\2\u00e1"+
"\u00e2\7>\2\2\u00e2\u00e3\7>\2\2\u00e3@\3\2\2\2\u00e4\u00e5\7\61\2\2\u00e5"+
"B\3\2\2\2\u00e6\u00e7\7\'\2\2\u00e7D\3\2\2\2\u00e8\u00e9\7?\2\2\u00e9"+
"\u00ea\7?\2\2\u00eaF\3\2\2\2\u00eb\u00ec\7#\2\2\u00ec\u00ed\7?\2\2\u00ed"+
"H\3\2\2\2\u00ee\u00ef\7>\2\2\u00ef\u00f0\7@\2\2\u00f0J\3\2\2\2\u00f1\u00f2"+
"\7>\2\2\u00f2\u00f3\7?\2\2\u00f3L\3\2\2\2\u00f4\u00f5\7?\2\2\u00f5\u00f6"+
"\7>\2\2\u00f6N\3\2\2\2\u00f7\u00f8\7@\2\2\u00f8\u00f9\7?\2\2\u00f9P\3"+
"\2\2\2\u00fa\u00fb\7?\2\2\u00fb\u00fc\7@\2\2\u00fcR\3\2\2\2\u00fd\u00fe"+
"\7`\2\2\u00feT\3\2\2\2\u00ff\u0100\7~\2\2\u0100V\3\2\2\2\u0101\u0102\7"+
"c\2\2\u0102\u0103\7p\2\2\u0103\u0104\7f\2\2\u0104X\3\2\2\2\u0105\u0106"+
"\7(\2\2\u0106\u0107\7(\2\2\u0107Z\3\2\2\2\u0108\u0109\7q\2\2\u0109\u010a"+
"\7t\2\2\u010a\\\3\2\2\2\u010b\u010c\7~\2\2\u010c\u010d\7~\2\2\u010d^\3"+
"\2\2\2\u010e\u010f\7d\2\2\u010f\u0110\7{\2\2\u0110\u0111\7v\2\2\u0111"+
"\u0122\7g\2\2\u0112\u0113\7y\2\2\u0113\u0114\7q\2\2\u0114\u0115\7t\2\2"+
"\u0115\u0122\7f\2\2\u0116\u0117\7d\2\2\u0117\u0118\7q\2\2\u0118\u0119"+
"\7q\2\2\u0119\u011a\7n\2\2\u011a\u011b\7g\2\2\u011b\u011c\7c\2\2\u011c"+
"\u0122\7p\2\2\u011d\u011e\7x\2\2\u011e\u011f\7q\2\2\u011f\u0120\7k\2\2"+
"\u0120\u0122\7f\2\2\u0121\u010e\3\2\2\2\u0121\u0112\3\2\2\2\u0121\u0116"+
"\3\2\2\2\u0121\u011d\3\2\2\2\u0122`\3\2\2\2\u0123\u0129\7$\2\2\u0124\u0125"+
"\7^\2\2\u0125\u0128\7$\2\2\u0126\u0128\n\2\2\2\u0127\u0124\3\2\2\2\u0127"+
"\u0126\3\2\2\2\u0128\u012b\3\2\2\2\u0129\u0127\3\2\2\2\u0129\u012a\3\2"+
"\2\2\u012a\u012c\3\2\2\2\u012b\u0129\3\2\2\2\u012c\u012d\7$\2\2\u012d"+
"b\3\2\2\2\u012e\u0132\7)\2\2\u012f\u0130\7^\2\2\u0130\u0133\7)\2\2\u0131"+
"\u0133\n\3\2\2\u0132\u012f\3\2\2\2\u0132\u0131\3\2\2\2\u0133\u0134\3\2"+
"\2\2\u0134\u0135\7)\2\2\u0135d\3\2\2\2\u0136\u0137\7v\2\2\u0137\u0138"+
"\7t\2\2\u0138\u0139\7w\2\2\u0139\u0140\7g\2\2\u013a\u013b\7h\2\2\u013b"+
"\u013c\7c\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2\u013e\u0140\7g\2\2"+
"\u013f\u0136\3\2\2\2\u013f\u013a\3\2\2\2\u0140f\3\2\2\2\u0141\u0144\5"+
"i\65\2\u0142\u0144\5q9\2\u0143\u0141\3\2\2\2\u0143\u0142\3\2\2\2\u0144"+
"h\3\2\2\2\u0145\u0149\5k\66\2\u0146\u0149\5m\67\2\u0147\u0149\5o8\2\u0148"+
"\u0145\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0147\3\2\2\2\u0149j\3\2\2\2"+
"\u014a\u0150\7\'\2\2\u014b\u014c\7\62\2\2\u014c\u0150\7d\2\2\u014d\u014e"+
"\7\62\2\2\u014e\u0150\7D\2\2\u014f\u014a\3\2\2\2\u014f\u014b\3\2\2\2\u014f"+
"\u014d\3\2\2\2\u0150\u0154\3\2\2\2\u0151\u0153\5y=\2\u0152\u0151\3\2\2"+
"\2\u0153\u0156\3\2\2\2\u0154\u0152\3\2\2\2\u0154\u0155\3\2\2\2\u0155\u0157"+
"\3\2\2\2\u0156\u0154\3\2\2\2\u0157\u0159\7\60\2\2\u0158\u015a\5y=\2\u0159"+
"\u0158\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015c\3\2"+
"\2\2\u015cl\3\2\2\2\u015d\u015f\5{>\2\u015e\u015d\3\2\2\2\u015f\u0162"+
"\3\2\2\2\u0160\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u0163\3\2\2\2\u0162"+
"\u0160\3\2\2\2\u0163\u0165\7\60\2\2\u0164\u0166\5{>\2\u0165\u0164\3\2"+
"\2\2\u0166\u0167\3\2\2\2\u0167\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168"+
"n\3\2\2\2\u0169\u016f\7&\2\2\u016a\u016b\7\62\2\2\u016b\u016f\7z\2\2\u016c"+
"\u016d\7\62\2\2\u016d\u016f\7Z\2\2\u016e\u0169\3\2\2\2\u016e\u016a\3\2"+
"\2\2\u016e\u016c\3\2\2\2\u016f\u0173\3\2\2\2\u0170\u0172\5}?\2\u0171\u0170"+
"\3\2\2\2\u0172\u0175\3\2\2\2\u0173\u0171\3\2\2\2\u0173\u0174\3\2\2\2\u0174"+
"\u0176\3\2\2\2\u0175\u0173\3\2\2\2\u0176\u0178\7\60\2\2\u0177\u0179\5"+
"}?\2\u0178\u0177\3\2\2\2\u0179\u017a\3\2\2\2\u017a\u0178\3\2\2\2\u017a"+
"\u017b\3\2\2\2\u017bp\3\2\2\2\u017c\u0180\5u;\2\u017d\u0180\5w<\2\u017e"+
"\u0180\5s:\2\u017f\u017c\3\2\2\2\u017f\u017d\3\2\2\2\u017f\u017e\3\2\2"+
"\2\u0180r\3\2\2\2\u0181\u0182\7\62\2\2\u0182\u0184\t\4\2\2\u0183\u0185"+
"\5y=\2\u0184\u0183\3\2\2\2\u0185\u0186\3\2\2\2\u0186\u0184\3\2\2\2\u0186"+
"\u0187\3\2\2\2\u0187\u018f\3\2\2\2\u0188\u018a\7\'\2\2\u0189\u018b\5y"+
"=\2\u018a\u0189\3\2\2\2\u018b\u018c\3\2\2\2\u018c\u018a\3\2\2\2\u018c"+
"\u018d\3\2\2\2\u018d\u018f\3\2\2\2\u018e\u0181\3\2\2\2\u018e\u0188\3\2"+
"\2\2\u018ft\3\2\2\2\u0190\u0192\5{>\2\u0191\u0190\3\2\2\2\u0192\u0193"+
"\3\2\2\2\u0193\u0191\3\2\2\2\u0193\u0194\3\2\2\2\u0194v\3\2\2\2\u0195"+
"\u019b\7&\2\2\u0196\u0197\7\62\2\2\u0197\u019b\7z\2\2\u0198\u0199\7\62"+
"\2\2\u0199\u019b\7Z\2\2\u019a\u0195\3\2\2\2\u019a\u0196\3\2\2\2\u019a"+
"\u0198\3\2\2\2\u019b\u019d\3\2\2\2\u019c\u019e\5}?\2\u019d\u019c\3\2\2"+
"\2\u019e\u019f\3\2\2\2\u019f\u019d\3\2\2\2\u019f\u01a0\3\2\2\2\u01a0x"+
"\3\2\2\2\u01a1\u01a2\t\5\2\2\u01a2z\3\2\2\2\u01a3\u01a4\t\6\2\2\u01a4"+

View File

@ -88,19 +88,19 @@ COMMENT_BLOCK=63
'!'=25
'&'=26
'~'=27
'>>'=28
'<<'=29
'/'=30
'%'=31
'=='=32
'!='=33
'<>'=34
'<'=35
'<='=36
'=<'=37
'>='=38
'=>'=39
'>'=40
'<'=28
'>'=29
'>>'=30
'<<'=31
'/'=32
'%'=33
'=='=34
'!='=35
'<>'=36
'<='=37
'=<'=38
'>='=39
'=>'=40
'^'=41
'|'=42
'and'=43

View File

@ -39,9 +39,9 @@ public class KickCParser extends Parser {
private static final String[] _LITERAL_NAMES = {
null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'",
"'while'", "'do'", "'for'", "'return'", "':'", "'..'", "','", "'*'", "'['",
"']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'>>'",
"'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<'", "'<='", "'=<'", "'>='",
"'=>'", "'>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'"
"']'", "'--'", "'++'", "'+'", "'-'", "'not'", "'!'", "'&'", "'~'", "'<'",
"'>'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='", "'<>'", "'<='", "'=<'",
"'>='", "'=>'", "'^'", "'|'", "'and'", "'&&'", "'or'", "'||'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
@ -194,7 +194,7 @@ public class KickCParser extends Parser {
setState(30);
_errHandler.sync(this);
_la = _input.LA(1);
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) );
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0) );
}
}
catch (RecognitionException re) {
@ -459,7 +459,7 @@ public class KickCParser extends Parser {
setState(34);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
{
setState(33);
stmtSeq();
@ -497,7 +497,7 @@ public class KickCParser extends Parser {
setState(46);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << T__4) | (1L << T__7) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << SIMPLETYPE) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
{
setState(45);
stmtSeq();
@ -663,7 +663,7 @@ public class KickCParser extends Parser {
setState(102);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
{
setState(101);
expr(0);
@ -844,7 +844,7 @@ public class KickCParser extends Parser {
setState(119);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
{
setState(118);
expr(0);
@ -1122,7 +1122,7 @@ public class KickCParser extends Parser {
setState(147);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
{
setState(146);
expr(0);
@ -1224,6 +1224,8 @@ public class KickCParser extends Parser {
case T__24:
case T__25:
case T__26:
case T__27:
case T__28:
case STRING:
case CHAR:
case BOOLEAN:
@ -1767,7 +1769,7 @@ public class KickCParser extends Parser {
setState(197);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__2) | (1L << T__16) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28) | (1L << STRING) | (1L << CHAR) | (1L << BOOLEAN) | (1L << NUMBER) | (1L << NAME))) != 0)) {
{
setState(196);
parameterList();
@ -1819,7 +1821,7 @@ public class KickCParser extends Parser {
_prevctx = _localctx;
setState(207);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26))) != 0)) ) {
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__25) | (1L << T__26) | (1L << T__27) | (1L << T__28))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@ -1897,7 +1899,7 @@ public class KickCParser extends Parser {
if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)");
setState(217);
_la = _input.LA(1);
if ( !(_la==T__27 || _la==T__28) ) {
if ( !(_la==T__29 || _la==T__30) ) {
_errHandler.recoverInline(this);
}
else {
@ -1917,7 +1919,7 @@ public class KickCParser extends Parser {
if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)");
setState(220);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__29) | (1L << T__30))) != 0)) ) {
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__31) | (1L << T__32))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@ -1957,7 +1959,7 @@ public class KickCParser extends Parser {
if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)");
setState(226);
_la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__31) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39))) != 0)) ) {
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__27) | (1L << T__28) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@ -2242,9 +2244,9 @@ public class KickCParser extends Parser {
"\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3"+
"\f\3\f\3\f\7\f\u00fd\n\f\f\f\16\f\u0100\13\f\3\r\3\r\3\r\7\r\u0105\n\r"+
"\f\r\16\r\u0108\13\r\3\r\2\5\20\24\26\16\2\4\6\b\n\f\16\20\22\24\26\30"+
"\2\n\3\2\26\27\4\2\23\23\30\35\3\2\36\37\4\2\23\23 !\3\2\30\31\3\2\"*"+
"\3\2-.\3\2/\60\2\u0132\2\32\3\2\2\2\4\36\3\2\2\2\6k\3\2\2\2\bn\3\2\2\2"+
"\n\u0080\3\2\2\2\f\u0082\3\2\2\2\16\u008a\3\2\2\2\20\u008d\3\2\2\2\22"+
"\2\n\3\2\26\27\4\2\23\23\30\37\3\2 !\4\2\23\23\"#\3\2\30\31\4\2\36\37"+
"$*\3\2-.\3\2/\60\2\u0132\2\32\3\2\2\2\4\36\3\2\2\2\6k\3\2\2\2\bn\3\2\2"+
"\2\n\u0080\3\2\2\2\f\u0082\3\2\2\2\16\u008a\3\2\2\2\20\u008d\3\2\2\2\22"+
"\u00a9\3\2\2\2\24\u00b3\3\2\2\2\26\u00d8\3\2\2\2\30\u0101\3\2\2\2\32\33"+
"\5\4\3\2\33\34\7\2\2\3\34\3\3\2\2\2\35\37\5\6\4\2\36\35\3\2\2\2\37 \3"+
"\2\2\2 \36\3\2\2\2 !\3\2\2\2!\5\3\2\2\2\"$\7\3\2\2#%\5\4\3\2$#\3\2\2\2"+

View File

@ -158,6 +158,10 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
case "+":
case "*":
case "/":
case "&":
case "|":
case "<<":
case ">>":
return new ConstantBinary(c1, operator, c2);
case "*idx":
// Pointer dereference - not constant

View File

@ -50,12 +50,22 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
*/
// Clobber combination for scroll-clobber.kc
/*
setRegister(combination, "main::c#0", Registers.getRegisterA());
setRegister(combination, "main::c#1", Registers.getRegisterA());
setRegister(combination, "main::c#2", Registers.getRegisterA());
setRegister(combination, "main::i#1", Registers.getRegisterX());
setRegister(combination, "main::i#3", Registers.getRegisterX());
setRegister(combination, "main::nxt#1", new Registers.RegisterZpPointerByte(2));
*/
// ALU combination for bitmap-bresenham.kc
setRegister(combination, "line::$3", Registers.getRegisterA());
setRegister(combination, "line::$5", Registers.getRegisterA());
setRegister(combination, "line::$4", Registers.getRegisterALU());
setRegister(combination, "line::$6", Registers.getRegisterA());
setRegister(combination, "line::$8", Registers.getRegisterA());
setRegister(combination, "line::$7", Registers.getRegisterALU());
boolean success = Pass4RegisterUpliftCombinations.generateCombinationAsm(
combination,

View File

@ -24,6 +24,10 @@ public class TestCompilationOutput extends TestCase {
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
}
public void testBitmapBresenham() throws IOException, URISyntaxException {
compileAndCompare("bitmap-bresenham");
}
public void testScrollClobber() throws IOException, URISyntaxException {
compileAndCompare("scroll-clobber");
}

View File

@ -0,0 +1,86 @@
byte* COLS = $d800;
byte* BGCOL = $d020;
byte* FGCOL = $d021;
byte* SCROLL = $d016;
byte* D018 = $d018;
byte* D011 = $d011;
byte RST8 = %10000000;
byte ECM = %01000000;
byte BMM = %00100000;
byte DEN = %00010000;
byte RSEL = %00001000;
byte* D016 = $d016;
byte MCM = %00010000;
byte CSEL = %00001000;
byte* SCREEN = $400;
byte* BITMAP = $2000;
byte[] plot_xlo = $1000;
byte[] plot_xhi = $1100;
byte[] plot_ylo = $1200;
byte[] plot_yhi = $1300;
main();
void main() {
*BGCOL = 0;
*FGCOL = 0;
*D011 = BMM|DEN|RSEL;
*D018 = $18; // ((word)SCREEN/$40)|((word)BITMAP/$400); - casting byte* to word needed before this works.
initscreen();
initplottables();
line(0,0,10,20);
line(10,20,40,40);
}
void initscreen() {
for(byte* b = BITMAP; b!=BITMAP+$2000; b++) {
*b = $5a;
}
for(byte* c = SCREEN; c!=SCREEN+$400;c++) {
*c = $14;
}
}
void initplottables() {
for(byte x : 0..255) {
plot_xlo[x] = x&$f8;
plot_xhi[x] = $20;
}
byte* yoffs = $0;
for(byte y : 0..255) {
plot_xlo[y] = <yoffs | y&$7;
plot_xhi[y] = >yoffs;
yoffs = yoffs + 40*8;
}
}
void line(byte x0, byte y0, byte x1, byte y1) {
byte* plot_lo = $fd;
byte* plot_hi = $fe;
byte xd = x1-x0;
byte yd = y1-y0;
byte x = x0;
byte y = y0;
byte e = yd<<1;
do {
//plot(x,y);
*plot_lo = plot_xlo[x]+plot_ylo[y];
*plot_hi = plot_xhi[x]+plot_yhi[y];
x = x + 1;
e = e+yd;
if(xd<e) {
y = y+1;
e = e - xd;
}
} while (x<(x1+1))
}
//void plot(byte x, byte y) {
//}