From 9cec38d0754a38044605a314b94d96230321c845 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 18 May 2019 21:37:34 +0200 Subject: [PATCH] Fixed negative numbers, zero-addition, zero inlining. --- .../java/dk/camelot64/kickc/Compiler.java | 7 + .../camelot64/kickc/fragment/AsmFormat.java | 2 +- .../kickc/fragment/AsmFragmentInstance.java | 3 +- .../AsmFragmentInstanceSpecFactory.java | 43 ++++-- .../model/operators/OperatorBitwiseAnd.java | 5 +- .../model/operators/OperatorGetHigh.java | 6 + .../kickc/model/operators/OperatorGetLow.java | 8 +- .../model/types/SymbolTypeConversion.java | 15 +- .../kickc/passes/Pass2InlineDerefIdx.java | 6 + .../passes/Pass4RegisterUpliftRemains.java | 7 +- .../passes/PassNSimplifyConstantZero.java | 44 ++++++ .../PassNSimplifyExpressionWithZero.java | 58 ++++++++ .../dk/camelot64/kickc/test/TestPrograms.java | 7 +- .../kc/examples/sinplotter/sine-plotter.kc | 2 +- src/test/kc/gfxbank.kc | 8 + src/test/ref/bresenhamarr.asm | 3 +- src/test/ref/c64dtv-8bppcharstretch.asm | 7 +- src/test/ref/c64dtv-8bppchunkystretch.asm | 10 +- src/test/ref/c64dtv-blittermin.asm | 7 +- src/test/ref/cast-not-needed-2.asm | 6 +- src/test/ref/cast-not-needed-3.asm | 6 +- src/test/ref/cast-precedence-problem.asm | 2 +- src/test/ref/complex/tetris/test-sprites.asm | 2 +- src/test/ref/complex/tetris/tetris.asm | 46 +++--- src/test/ref/consolidate-constant-problem.asm | 4 +- src/test/ref/const-signed-promotion.asm | 1 - src/test/ref/constantmin.asm | 3 +- src/test/ref/constants.asm | 2 +- src/test/ref/derefidx-word-0.asm | 39 +++++ src/test/ref/derefidx-word-1.asm | 10 ++ src/test/ref/derefidx-word-2.asm | 15 ++ src/test/ref/examples/3d/3d.asm | 51 +++---- src/test/ref/examples/3d/perspective.asm | 6 +- .../examples/bresenham/bitmap-bresenham.asm | 11 +- .../ref/examples/chargen/chargen-analysis.asm | 5 +- .../examples/fastmultiply/fastmultiply8.asm | 7 +- src/test/ref/examples/fire/fire.asm | 2 +- .../multiplexer/simple-multiplexer.asm | 8 +- .../ref/examples/plasma/plasma-unroll.asm | 2 +- src/test/ref/examples/plasma/plasma.asm | 2 +- src/test/ref/examples/rotate/rotate.asm | 80 +++++----- .../ref/examples/scrolllogo/scrolllogo.asm | 133 +++++++++-------- .../ref/examples/sinplotter/sine-plotter.asm | 137 ++++++++++-------- .../ref/examples/sinsprites/sinus-sprites.asm | 6 +- src/test/ref/forrangedwords.asm | 2 +- src/test/ref/fragment-variations.asm | 74 ++++++++++ src/test/ref/gfxbank.asm | 16 ++ src/test/ref/halfscii.asm | 28 ++-- src/test/ref/inline-function-if.asm | 4 +- src/test/ref/inline-kasm-resource.asm | 2 +- src/test/ref/inline-pointer-0.asm | 10 ++ src/test/ref/inline-pointer-1.asm | 24 +++ src/test/ref/inline-pointer-2.asm | 9 ++ src/test/ref/inline-string-3.asm | 9 +- src/test/ref/inline-word-0.asm | 13 ++ src/test/ref/inline-word-1.asm | 13 ++ src/test/ref/inline-word-2.asm | 13 ++ src/test/ref/inline-word.asm | 3 +- src/test/ref/int-literals.asm | 16 +- src/test/ref/line-anim.asm | 84 ++++++----- src/test/ref/linegen.asm | 16 +- src/test/ref/liverange-call-problem.asm | 4 +- src/test/ref/min-fmul-16.asm | 2 +- src/test/ref/mixed-array-0.asm | 15 ++ src/test/ref/mixed-array-1.asm | 15 ++ .../simple-multiplexer-irq.asm | 8 +- src/test/ref/number-conversion.asm | 8 +- src/test/ref/operator-lohi-problem.asm | 6 +- src/test/ref/ptr-complex.asm | 3 +- src/test/ref/roll-sprite-msb.asm | 6 +- src/test/ref/scan-desire-problem.asm | 5 +- src/test/ref/semi-struct-2.asm | 5 +- src/test/ref/signed-indexed-subtract.asm | 53 ++++--- src/test/ref/signed-words.asm | 36 +++-- src/test/ref/sinus-basic.asm | 4 +- src/test/ref/sinusgen16.asm | 65 +++++---- src/test/ref/sinusgen16b.asm | 124 +++++++++------- src/test/ref/sinusgen8.asm | 25 ++-- src/test/ref/sinusgen8b.asm | 83 ++++++----- src/test/ref/sinusgenscale8.asm | 28 ++-- src/test/ref/sizeof-expr.asm | 10 +- src/test/ref/test-comparisons-sword.asm | 6 +- src/test/ref/test-division.asm | 65 ++++----- src/test/ref/test-multiply-16bit.asm | 99 +++++++++---- src/test/ref/test-multiply-8bit.asm | 65 ++++++--- src/test/ref/test-scroll-up.asm | 4 +- src/test/ref/test-signed-word-minus-byte.asm | 28 +++- src/test/ref/test-word-size-arrays.asm | 2 +- src/test/ref/true-inline-words.asm | 6 +- src/test/ref/type-inference.asm | 23 +++ src/test/ref/type-mix.asm | 15 +- src/test/ref/typeid-plus-bytes.asm | 113 +++++++++++++-- src/test/ref/uninitialized.asm | 7 +- src/test/ref/valuelist-error.asm | 10 ++ 94 files changed, 1441 insertions(+), 677 deletions(-) create mode 100644 src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java create mode 100644 src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java create mode 100644 src/test/kc/gfxbank.kc create mode 100644 src/test/ref/derefidx-word-0.asm create mode 100644 src/test/ref/derefidx-word-1.asm create mode 100644 src/test/ref/derefidx-word-2.asm create mode 100644 src/test/ref/fragment-variations.asm create mode 100644 src/test/ref/gfxbank.asm create mode 100644 src/test/ref/inline-pointer-0.asm create mode 100644 src/test/ref/inline-pointer-1.asm create mode 100644 src/test/ref/inline-pointer-2.asm create mode 100644 src/test/ref/inline-word-0.asm create mode 100644 src/test/ref/inline-word-1.asm create mode 100644 src/test/ref/inline-word-2.asm create mode 100644 src/test/ref/mixed-array-0.asm create mode 100644 src/test/ref/mixed-array-1.asm create mode 100644 src/test/ref/type-inference.asm create mode 100644 src/test/ref/valuelist-error.asm diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 3aa809b1b..b5dd695b3 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -269,8 +269,12 @@ public class Compiler { optimizations.add(new Pass2SizeOfSimplification(program)); optimizations.add(new Pass2InlineCast(program)); optimizations.add(new PassNCastSimplification(program)); + optimizations.add(new PassNStatementIndices(program)); + optimizations.add(new PassNVariableReferenceInfos(program)); optimizations.add(new Pass2InlineDerefIdx(program)); optimizations.add(new Pass2DeInlineWordDerefIdx(program)); + optimizations.add(new PassNSimplifyConstantZero(program)); + optimizations.add(new PassNSimplifyExpressionWithZero(program)); pass2Execute(optimizations); } @@ -319,6 +323,9 @@ public class Compiler { constantOptimizations.add(new Pass2ConstantIfs(program)); constantOptimizations.add(new Pass2InlineDerefIdx(program)); constantOptimizations.add(new PassNEliminateUnusedVars(program, true)); + constantOptimizations.add(new PassNSimplifyConstantZero(program)); + constantOptimizations.add(new PassNSimplifyExpressionWithZero(program)); + pass2Execute(constantOptimizations); diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java index 3e0c94f69..edd3e0899 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java @@ -231,7 +231,7 @@ public class AsmFormat { return SHORT_ASM_NUMBERS[number.intValue()]; } else { if(number.longValue()<0) { - return String.format("-$%x", -number.longValue()); + return "-"+getAsmNumber(-number.longValue()); } else { return String.format("$%x", number.longValue()); } diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java index 53793f4c9..21f9e65f3 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java @@ -300,8 +300,7 @@ public class AsmFragmentInstance { @Override public AsmParameter visitAsmExprInt(KickCParser.AsmExprIntContext ctx) { Number number = NumberParser.parseLiteral(ctx.NUMBER().getText()); - ConstantInteger intVal = new ConstantInteger(number.longValue()); - boolean isZp = SymbolType.BYTE.equals(intVal.getType()) || SymbolType.SBYTE.equals(intVal.getType()); + boolean isZp = SymbolType.BYTE.contains(number.longValue()) || SymbolType.SBYTE.contains(number.longValue()); String param = AsmFormat.getAsmNumber(number); return new AsmParameter(param, isZp); } diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java index 5030079a3..f3e3624c4 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java @@ -1,9 +1,6 @@ package dk.camelot64.kickc.fragment; -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.ControlFlowGraph; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.Registers; +import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.operators.Operator; import dk.camelot64.kickc.model.operators.OperatorUnary; import dk.camelot64.kickc.model.operators.Operators; @@ -17,6 +14,7 @@ import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.*; +import java.lang.InternalError; import java.util.LinkedHashMap; import java.util.Map; @@ -242,17 +240,32 @@ public class AsmFragmentInstanceSpecFactory { if(castType == null) { SymbolType toType = castVal.getToType(); // If value literal not matching cast type then add expression code to transform it into the value space ( eg. value & 0xff ) - ConstantLiteral constantLiteral = val.calculateLiteral(program.getScope()); - if(constantLiteral instanceof ConstantInteger) { - if(toType instanceof SymbolTypeIntegerFixed) { - if(!((SymbolTypeIntegerFixed) toType).contains(((ConstantInteger) constantLiteral).getValue())) { - if(toType.getSizeBytes() == 1) { - val = new ConstantBinary(new ConstantInteger(0xffL, SymbolType.BYTE), Operators.BOOL_AND, val); - } else if(toType.getSizeBytes() == 2) { - val = new ConstantBinary(new ConstantInteger(0xffffL, SymbolType.WORD), Operators.BOOL_AND, val); - } else { - throw new InternalError("Not implemented!"); - } + + if(toType instanceof SymbolTypeIntegerFixed) { + SymbolTypeIntegerFixed integerFixed = (SymbolTypeIntegerFixed) toType; + ConstantLiteral constantLiteral; + Long integerValue; + try { + constantLiteral = val.calculateLiteral(program.getScope()); + if(constantLiteral instanceof ConstantInteger) { + integerValue = ((ConstantInteger) constantLiteral).getValue(); + } else if(constantLiteral instanceof ConstantPointer) { + integerValue = ((ConstantPointer) constantLiteral).getValue(); + } else { + throw new InternalError("Not implemented "+constantLiteral); + } + } catch (ConstantNotLiteral e) { + // Assume it is a word + integerValue = 0xffffL; + } + + if(!integerFixed.contains(integerValue)) { + if(toType.getSizeBytes() == 1) { + val = new ConstantBinary(new ConstantInteger(0xffL, SymbolType.BYTE), Operators.BOOL_AND, val); + } else if(toType.getSizeBytes() == 2) { + val = new ConstantBinary(new ConstantInteger(0xffffL, SymbolType.WORD), Operators.BOOL_AND, val); + } else { + throw new InternalError("Not implemented "+toType); } } } 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 e7906ff6f..931576215 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java @@ -31,7 +31,10 @@ public class OperatorBitwiseAnd extends OperatorBinary { } // Handle numeric types if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) { - return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2); + if(type1.getSizeBytes()>8); } else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) { return new ConstantInteger(operandInt.getInteger()>>16); + } else if(SymbolType.BYTE.equals(operandInt.getType()) || SymbolType.SBYTE.equals(operandInt.getType())) { + return new ConstantInteger(0L, SymbolType.BYTE); + } else if(SymbolType.NUMBER.equals(operandInt.getType())) { + throw new ConstantNotLiteral("Operand not resolved "+operand); } } else if(operand instanceof ConstantPointer) { return new ConstantInteger(((ConstantPointer) operand).getLocation()>>8); @@ -41,6 +45,8 @@ public class OperatorGetHigh extends OperatorUnary { return SymbolType.BYTE; } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { return SymbolType.WORD; + } else if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { + return SymbolType.BYTE; } else if(SymbolType.STRING.equals(operandType)) { return SymbolType.BYTE; } else if(SymbolType.NUMBER.equals(operandType)) { diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java index c05e748d4..7542903f6 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java @@ -26,13 +26,17 @@ public class OperatorGetLow extends OperatorUnary { return new ConstantInteger(operandInt.getInteger()&0xff); } else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) { return new ConstantInteger(operandInt.getInteger()&0xffff); + } else if(SymbolType.BYTE.equals(operandInt.getType()) || SymbolType.SBYTE.equals(operandInt.getType())) { + return operandInt; + } else if(SymbolType.NUMBER.equals(operandInt.getType())) { + throw new ConstantNotLiteral("Operand not resolved "+operand); } } else if(operand instanceof ConstantPointer) { return new ConstantInteger(((ConstantPointer) operand).getLocation()&0xff); } else if(operand instanceof ConstantString) { throw new ConstantNotLiteral("address of string is not literal"); } - throw new CompileError("Calculation not implemented " + getOperator() + " " + operand ); + throw new ConstantNotLiteral("Calculation not implemented " + getOperator() + " " + operand ); } @Override @@ -41,6 +45,8 @@ public class OperatorGetLow extends OperatorUnary { return SymbolType.BYTE; } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { return SymbolType.WORD; + } else if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { + return SymbolType.BYTE; } else if(SymbolType.STRING.equals(operandType)) { return SymbolType.BYTE; } else if(SymbolType.NUMBER.equals(operandType)) { diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java index b82e23e76..df8ec8b90 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.model.types; import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.symbols.ProgramScope; @@ -103,7 +104,13 @@ public class SymbolTypeConversion { // Find the cast type if possible if(numberVal instanceof ConstantValue) { - ConstantLiteral constantLiteral = ((ConstantValue) numberVal).calculateLiteral(symbols); + ConstantLiteral constantLiteral; + try { + constantLiteral = ((ConstantValue) numberVal).calculateLiteral(symbols); + } catch( ConstantNotLiteral e) { + // Postpone til later! + return null; + } if(constantLiteral instanceof ConstantInteger) { ConstantInteger constantInteger = (ConstantInteger) constantLiteral; if(SymbolType.NUMBER.equals(constantInteger.getType())) { @@ -161,7 +168,11 @@ public class SymbolTypeConversion { if(lValueType.equals(SymbolType.SDWORD) && rValueType.equals(SymbolType.SWORD)) return true; if(SymbolType.NUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) { - // L-value is still a number - constants are probably not done being identified & typed + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.NUMBER.equals(lValueType) && SymbolType.isInteger(rValueType)) { + // R-value is still a number - constants are probably not done being identified & typed return true; } if(SymbolType.STRING.equals(rValueType) && lValueType instanceof SymbolTypePointer && ((SymbolTypePointer) lValueType).getElementType().equals(SymbolType.BYTE)) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java b/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java index 795d55117..3a8146be7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java @@ -12,6 +12,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.values.*; +import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; /** Identify derefs of pointers that are defined as pointer + value - and inline them as derefidx instead */ @@ -71,6 +72,11 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization { public RValue attemptInlineDeref(StatementAssignment derefAssignment) { + VariableRef derefVar = (VariableRef) derefAssignment.getlValue(); + Collection varUseStatements = getProgram().getVariableReferenceInfos().getVarUseStatements(derefVar); + if(varUseStatements.size()>2) { + return null; + } if(Operators.PLUS.equals(derefAssignment.getOperator())) { SymbolType derefLeftType = SymbolTypeInference.inferType(getScope(), derefAssignment.getrValue1()); if(derefLeftType instanceof SymbolTypePointer) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java index 6e023bbb0..7e4f48ee0 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java @@ -18,12 +18,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base { LiveRangeEquivalenceClassSet equivalenceClassSet = getProgram().getLiveRangeEquivalenceClassSet(); List equivalenceClasses = new ArrayList<>(equivalenceClassSet.getEquivalenceClasses()); final VariableRegisterWeights registerWeights = getProgram().getVariableRegisterWeights(); - Collections.sort(equivalenceClasses, new Comparator() { - @Override - public int compare(LiveRangeEquivalenceClass o1, LiveRangeEquivalenceClass o2) { - return Double.compare(registerWeights.getTotalWeight(o2), registerWeights.getTotalWeight(o1)); - } - }); + Collections.sort(equivalenceClasses, (o1, o2) -> Double.compare(registerWeights.getTotalWeight(o2), registerWeights.getTotalWeight(o1))); Set unknownFragments = new LinkedHashSet<>(); diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java new file mode 100644 index 000000000..6b01d695d --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java @@ -0,0 +1,44 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ConstantNotLiteral; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.values.*; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Simplify any constant expression evaluating to zero + */ +public class PassNSimplifyConstantZero extends Pass2SsaOptimization { + + public PassNSimplifyConstantZero(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + + ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { + Value value = programValue.get(); + if(value instanceof ConstantValue && !(value instanceof ConstantInteger) &&!(value instanceof ConstantRef)) { + ConstantLiteral literal; + try { + literal = ((ConstantValue) value).calculateLiteral(getProgram().getScope()); + } catch( ConstantNotLiteral e) { + return; + } + if(literal instanceof ConstantInteger) { + if(((ConstantInteger) literal).getInteger()==0L) { + getLog().append("Simplifying constant evaluating to zero "+value.toString(getProgram()) + " in "+(currentStmt==null?"":currentStmt.toString(getProgram(), false))); + programValue.set(new ConstantInteger(0L, ((ConstantInteger) literal).getType())); + modified.set(true); + } + } + } + }); + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java new file mode 100644 index 000000000..c59ea0bd1 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java @@ -0,0 +1,58 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.operators.Operator; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.PointerDereferenceSimple; +import dk.camelot64.kickc.model.values.RValue; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Simplify any binary expression containing a zero value (if possible + */ +public class PassNSimplifyExpressionWithZero extends Pass2SsaOptimization { + + public PassNSimplifyExpressionWithZero(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(programExpression instanceof ProgramExpressionBinary) { + ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression; + RValue left = binary.getLeft(); + RValue right = binary.getRight(); + Operator operator = programExpression.getOperator(); + if(Operators.PLUS.equals(operator) || Operators.MINUS.equals(operator) || Operators.BOOL_OR.equals(operator) || Operators.BOOL_XOR.equals(operator)) { + if(left instanceof ConstantInteger && ((ConstantInteger) left).getInteger() == 0) { + getLog().append("Simplifying expression containing zero " + binary.getRight().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) { + programExpression.set(new PointerDereferenceSimple(binary.getRight())); + } else { + programExpression.set(binary.getRight()); + } + modified.set(true); + } else if(right instanceof ConstantInteger && ((ConstantInteger) right).getInteger() == 0) { + getLog().append("Simplifying expression containing zero " + binary.getLeft().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) { + programExpression.set(new PointerDereferenceSimple(binary.getLeft())); + } else { + programExpression.set(binary.getLeft()); + } + modified.set(true); + } + } + } + }); + + return modified.get(); + } + +} diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 9f56c9b5e..7a4ea6db5 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -63,6 +63,11 @@ public class TestPrograms { */ + @Test + public void testGfxBankOptimization() throws IOException, URISyntaxException { + compileAndCompare("gfxbank"); + } + @Test public void testDoubleIndexingArrays() throws IOException, URISyntaxException { compileAndCompare("double-indexing-arrays"); @@ -1743,7 +1748,7 @@ public class TestPrograms { @Test public void testForClassicMin() throws IOException, URISyntaxException { - compileAndCompare("forclassicmin", log()); + compileAndCompare("forclassicmin"); } @Test diff --git a/src/test/kc/examples/sinplotter/sine-plotter.kc b/src/test/kc/examples/sinplotter/sine-plotter.kc index 300f5591c..a46eb11c2 100644 --- a/src/test/kc/examples/sinplotter/sine-plotter.kc +++ b/src/test/kc/examples/sinplotter/sine-plotter.kc @@ -12,7 +12,7 @@ const word SIN_SIZE = 512; signed word[512] align($100) sin; -signed word* sin2 = $1500; +signed word* sin2 = $1400; kickasm(pc sin2) {{ .for(var i=0; i<512; i++) { diff --git a/src/test/kc/gfxbank.kc b/src/test/kc/gfxbank.kc new file mode 100644 index 000000000..990aaa585 --- /dev/null +++ b/src/test/kc/gfxbank.kc @@ -0,0 +1,8 @@ +// Test minimization of constants + +import "c64" + +void main() { + const byte* PLAYFIELD_CHARSET = $2800; + vicSelectGfxBank(PLAYFIELD_CHARSET); +} diff --git a/src/test/ref/bresenhamarr.asm b/src/test/ref/bresenhamarr.asm index 7c3c586de..6f5b47054 100644 --- a/src/test/ref/bresenhamarr.asm +++ b/src/test/ref/bresenhamarr.asm @@ -19,9 +19,8 @@ main: { ldx #yd/2 lda #x0 sta x - lda #x0+y0*$28 + lda #<0 sta idx - lda #0 sta idx+1 b1: lda idx diff --git a/src/test/ref/c64dtv-8bppcharstretch.asm b/src/test/ref/c64dtv-8bppcharstretch.asm index 0e1316723..4cb9bf646 100644 --- a/src/test/ref/c64dtv-8bppcharstretch.asm +++ b/src/test/ref/c64dtv-8bppcharstretch.asm @@ -77,7 +77,7 @@ main: { lda #VIC_MCM|VIC_CSEL sta VIC_CONTROL2 // Plane A: SCREEN - lda #SCREEN sta DTV_PLANEA_START_MI @@ -89,7 +89,6 @@ main: { sta DTV_PLANEA_MODULO_LO sta DTV_PLANEA_MODULO_HI // Plane B: CHARSET8 - lda #CHARSET8 sta DTV_PLANEB_START_MI @@ -233,9 +232,9 @@ gfx_init_plane_charset8: { lda #0 sta ch sta col - lda #<$4000+(CHARSET8&$3fff) + lda #<$4000 sta gfxa - lda #>$4000+(CHARSET8&$3fff) + lda #>$4000 sta gfxa+1 lda #CHUNKY sta DTV_PLANEB_START_MI @@ -84,9 +84,9 @@ main: { sta CIA2_PORT_A // Set VIC Bank // VIC memory - lda #(CHUNKY&$3fff)/$40|(0)/4 + lda #0 sta VIC_MEMORY - ldx #0 + tax // DTV Palette - Grey Tones b1: txa @@ -195,7 +195,7 @@ gfx_init_chunky: { .label gfxb = 5 .label x = 3 .label y = 2 - lda #$ff&CHUNKY/$4000 + lda #CHUNKY/$4000 jsr dtvSetCpuBankSegment1 ldx #($ff&CHUNKY/$4000)+1 lda #0 @@ -205,7 +205,7 @@ gfx_init_chunky: { lda #>$4000 sta gfxb+1 b1: - lda #0 + lda #<0 sta x sta x+1 b2: diff --git a/src/test/ref/c64dtv-blittermin.asm b/src/test/ref/c64dtv-blittermin.asm index b74c1966c..b7e126dea 100644 --- a/src/test/ref/c64dtv-blittermin.asm +++ b/src/test/ref/c64dtv-blittermin.asm @@ -85,9 +85,9 @@ main: { sta DTV_BLITTER_SRCA_HI sta DTV_BLITTER_SRCA_MOD_LO sta DTV_BLITTER_SRCA_MOD_HI - lda #<$100 + lda #<$80 sta DTV_BLITTER_SRCA_LIN_LO - lda #>$100 + lda #0 sta DTV_BLITTER_SRCA_LIN_HI lda #$10 sta DTV_BLITTER_SRCA_STEP @@ -100,14 +100,12 @@ main: { sta DTV_BLITTER_SRCB_HI sta DTV_BLITTER_SRCB_MOD_LO sta DTV_BLITTER_SRCB_MOD_HI - lda #<$100 sta DTV_BLITTER_SRCB_LIN_LO lda #>$100 sta DTV_BLITTER_SRCB_LIN_HI lda #0 sta DTV_BLITTER_SRCB_STEP // Step 0.0 - lda #SCREEN sta DTV_BLITTER_DEST_MI @@ -115,7 +113,6 @@ main: { sta DTV_BLITTER_DEST_HI sta DTV_BLITTER_DEST_MOD_LO sta DTV_BLITTER_DEST_MOD_HI - lda #<$100 sta DTV_BLITTER_DEST_LIN_LO lda #>$100 sta DTV_BLITTER_DEST_LIN_HI diff --git a/src/test/ref/cast-not-needed-2.asm b/src/test/ref/cast-not-needed-2.asm index c91a7229a..f6c04cf1c 100644 --- a/src/test/ref/cast-not-needed-2.asm +++ b/src/test/ref/cast-not-needed-2.asm @@ -2,14 +2,12 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .const SIZEOF_POINTER = 2 main: { - .const getScreen1_id = 0 .label getScreen1_return = 2 .label spritePtr1_return = 2 - lda screens+getScreen1_id*SIZEOF_POINTER + lda screens sta getScreen1_return - lda screens+getScreen1_id*SIZEOF_POINTER+1 + lda screens+1 sta getScreen1_return+1 clc lda spritePtr1_return diff --git a/src/test/ref/cast-not-needed-3.asm b/src/test/ref/cast-not-needed-3.asm index 4a3ee07b6..c57565015 100644 --- a/src/test/ref/cast-not-needed-3.asm +++ b/src/test/ref/cast-not-needed-3.asm @@ -2,15 +2,13 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .const SIZEOF_POINTER = 2 main: { .label DSP = $400 - .const getScreen1_id = 0 .label getScreen1_return = 2 .label spritePtr1__0 = 2 - lda screens+getScreen1_id*SIZEOF_POINTER + lda screens sta getScreen1_return - lda screens+getScreen1_id*SIZEOF_POINTER+1 + lda screens+1 sta getScreen1_return+1 clc lda spritePtr1__0 diff --git a/src/test/ref/cast-precedence-problem.asm b/src/test/ref/cast-precedence-problem.asm index d0d46735c..18f118178 100644 --- a/src/test/ref/cast-precedence-problem.asm +++ b/src/test/ref/cast-precedence-problem.asm @@ -7,8 +7,8 @@ main: { .const min = $a .const max = $c8 .label BGCOL = $d021 - .const sumb = min+max .const sumw = min+max + .const sumb = min+max .const midb = (sumb>>1)+1 .const midw = (sumw>>1)+1 lda #midw diff --git a/src/test/ref/complex/tetris/test-sprites.asm b/src/test/ref/complex/tetris/test-sprites.asm index a35164dc2..61571e8bb 100644 --- a/src/test/ref/complex/tetris/test-sprites.asm +++ b/src/test/ref/complex/tetris/test-sprites.asm @@ -84,7 +84,7 @@ bbegin: rts main: { .const toSpritePtr2_return = SIN_SPRITE/$40 - .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_SCREEN_1)/$40 + .const vicSelectGfxBank1_toDd001_return = 3 .const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)*4)|(>PLAYFIELD_CHARSET)/4&$f .label xpos = 2 .label ypos = 3 diff --git a/src/test/ref/complex/tetris/tetris.asm b/src/test/ref/complex/tetris/tetris.asm index 889a3b29e..5787e8dbe 100644 --- a/src/test/ref/complex/tetris/tetris.asm +++ b/src/test/ref/complex/tetris/tetris.asm @@ -205,18 +205,20 @@ main: { ldx play_spawn_current.piece_idx lda #$20 jsr render_next - ldy play_spawn_current._7 - lda PIECES,y + lda current_piece_gfx sta current_piece - lda PIECES+1,y + lda current_piece_gfx+1 sta current_piece+1 lda #0 sta level_bcd sta level sta score_bcd sta score_bcd+1 + lda #<0>>$10 sta score_bcd+2 + lda #>0>>$10 sta score_bcd+3 + lda #<0 sta lines_bcd sta lines_bcd+1 sta current_movedown_counter @@ -308,16 +310,16 @@ render_score: { jsr render_bcd ldx score_bytes+1 ldy #0 - lda #score_offset+2 + lda #score_offset+2 sta render_bcd.offset+1 jsr render_bcd ldx score_bytes ldy #0 - lda #score_offset+4 + lda #score_offset+4 sta render_bcd.offset+1 jsr render_bcd lda lines_bcd+1 @@ -331,9 +333,9 @@ render_score: { lda lines_bcd tax ldy #0 - lda #lines_offset+1 + lda #lines_offset+1 sta render_bcd.offset+1 jsr render_bcd ldx level_bcd @@ -390,8 +392,8 @@ render_bcd: { // Render the next tetromino in the "next" area render_next: { .const next_area_offset = $28*$c+$18+4 - .label next_piece_char = $a .label next_piece_gfx = 5 + .label next_piece_char = $a .label screen_next_area = 7 .label l = 9 cmp #0 @@ -409,13 +411,14 @@ render_next: { b1: txa asl + // Render the next piece tay - lda PIECES_NEXT_CHARS,x - sta next_piece_char lda PIECES,y sta next_piece_gfx lda PIECES+1,y sta next_piece_gfx+1 + lda PIECES_NEXT_CHARS,x + sta next_piece_char lda #0 sta l b3: @@ -816,10 +819,9 @@ play_move_down: { tax jsr play_update_score jsr play_spawn_current - ldy play_spawn_current._7 - lda PIECES,y + lda current_piece_gfx sta current_piece - lda PIECES+1,y + lda current_piece_gfx+1 sta current_piece+1 lda #0 sta current_orientation @@ -838,20 +840,18 @@ play_move_down: { // Spawn a new piece // Moves the next piece into the current and spawns a new next piece play_spawn_current: { - .label _7 = 4 .label piece_idx = $21 // Move next piece into current ldx next_piece_idx txa asl - sta _7 - lda PIECES_CHARS,x - sta current_piece_char - ldy _7 + tay lda PIECES,y sta current_piece_gfx lda PIECES+1,y sta current_piece_gfx+1 + lda PIECES_CHARS,x + sta current_piece_char lda PIECES_START_X,x sta current_xpos lda PIECES_START_Y,x @@ -860,9 +860,9 @@ play_spawn_current: { sta play_collision.xpos lda current_ypos sta play_collision.ypos - lda PIECES,y + lda current_piece_gfx sta current_piece_104 - lda PIECES+1,y + lda current_piece_gfx+1 sta current_piece_104+1 ldx #0 jsr play_collision @@ -1378,7 +1378,7 @@ sprites_init: { } // Initialize rendering render_init: { - .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)/$40 + .const vicSelectGfxBank1_toDd001_return = 3 .label li_1 = 5 .label li_2 = 7 lda #3 diff --git a/src/test/ref/consolidate-constant-problem.asm b/src/test/ref/consolidate-constant-problem.asm index f8146c526..be6c8721f 100644 --- a/src/test/ref/consolidate-constant-problem.asm +++ b/src/test/ref/consolidate-constant-problem.asm @@ -6,7 +6,7 @@ main: { lda #0 sta screen+$27 sta screen+$26 - sta $28*1+screen+$27 - sta screen+$26+$28*1 + sta screen+$28*1+$27 + sta screen+$28*1+$26 rts } diff --git a/src/test/ref/const-signed-promotion.asm b/src/test/ref/const-signed-promotion.asm index 90042051c..fbe66dba9 100644 --- a/src/test/ref/const-signed-promotion.asm +++ b/src/test/ref/const-signed-promotion.asm @@ -2,7 +2,6 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .const SIZEOF_SIGNED_WORD = 2 main: { .label screen = $400 ldx #0 diff --git a/src/test/ref/constantmin.asm b/src/test/ref/constantmin.asm index 4832ff399..5fc98d7cf 100644 --- a/src/test/ref/constantmin.asm +++ b/src/test/ref/constantmin.asm @@ -5,12 +5,11 @@ .const STAR = $51 .label VIC = $d000 .const RED = 2 - .label BGCOL = VIC+$10*2+1 main: { lda #STAR sta SCREEN lda #RED - sta BGCOL + sta VIC+$10*2+1 ldx #$28 b1: lda #STAR+1 diff --git a/src/test/ref/constants.asm b/src/test/ref/constants.asm index e49be31e1..7d603723c 100644 --- a/src/test/ref/constants.asm +++ b/src/test/ref/constants.asm @@ -18,8 +18,8 @@ main: { test_sbytes: { .const bb = 0 .const bc = bb+2 - .const bd = bc-4 .const bf = $ff&-$7f-$7f + .const bd = bc-4 .const be = -bd lda #0 sta assert_sbyte.c diff --git a/src/test/ref/derefidx-word-0.asm b/src/test/ref/derefidx-word-0.asm new file mode 100644 index 000000000..a893d8fe3 --- /dev/null +++ b/src/test/ref/derefidx-word-0.asm @@ -0,0 +1,39 @@ +// Tests that array-indexing by a word variable is turned into pointer addition +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label i = 2 + .label _1 = 4 + lda #<0 + sta i + sta i+1 + b1: + lda i + clc + adc #screen + sta _1+1 + lda #'a' + ldy #0 + sta (_1),y + lda #$28 + clc + adc i + sta i + bcc !+ + inc i+1 + !: + lda i+1 + cmp #>$3e8 + bcc b1 + bne !+ + lda i + cmp #<$3e8 + bcc b1 + !: + rts +} diff --git a/src/test/ref/derefidx-word-1.asm b/src/test/ref/derefidx-word-1.asm new file mode 100644 index 000000000..631845860 --- /dev/null +++ b/src/test/ref/derefidx-word-1.asm @@ -0,0 +1,10 @@ +// Tests that array-indexing by a constant word is turned into a constant pointer +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + lda #'a' + sta screen+$28*$a + rts +} diff --git a/src/test/ref/derefidx-word-2.asm b/src/test/ref/derefidx-word-2.asm new file mode 100644 index 000000000..44af2978a --- /dev/null +++ b/src/test/ref/derefidx-word-2.asm @@ -0,0 +1,15 @@ +// Tests that array-indexing by a word variable that is a sum of a constant word and a byte is turned back into derefidx +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + ldx #0 + b1: + lda #'a' + sta screen+$28*$a,x + inx + cpx #$28 + bne b1 + rts +} diff --git a/src/test/ref/examples/3d/3d.asm b/src/test/ref/examples/3d/3d.asm index 0dcdcb236..c555981f4 100644 --- a/src/test/ref/examples/3d/3d.asm +++ b/src/test/ref/examples/3d/3d.asm @@ -129,13 +129,13 @@ anim: { tya asl tax - lda #$80 + lda xp clc - adc xp + adc #$80 sta SPRITES_XPOS,x - lda #$80 + lda yp clc - adc yp + adc #$80 sta SPRITES_YPOS,x inc i lda #8 @@ -149,10 +149,9 @@ anim: { // Increment angles inc sx inc sx - lda sy - sec - sbc #3 - sta sy + lax sy + axs #3 + stx sy jmp b2 } debug_print: { @@ -336,8 +335,7 @@ print_sbyte_at: { .label at = 6 cpx #0 bmi b1 - lda #' ' - sta print_char_at.ch + ldy #' ' jsr print_char_at b2: inc print_byte_at.at @@ -347,8 +345,7 @@ print_sbyte_at: { jsr print_byte_at rts b1: - lda #'-' - sta print_char_at.ch + ldy #'-' jsr print_char_at txa eor #$ff @@ -358,17 +355,16 @@ print_sbyte_at: { jmp b2 } // Print a single char -// print_char_at(byte zeropage(8) ch, byte* zeropage(6) at) +// print_char_at(byte register(Y) ch, byte* zeropage(6) at) print_char_at: { .label at = 6 - .label ch = 8 - lda ch + tya ldy #0 sta (at),y rts } // Print a byte as HEX at a specific position -// print_byte_at(byte* zeropage(6) at) +// print_byte_at(byte register(X) b, byte* zeropage(6) at) print_byte_at: { .label at = 6 txa @@ -378,7 +374,7 @@ print_byte_at: { lsr tay lda print_hextab,y - sta print_char_at.ch + tay jsr print_char_at lda #$f axs #0 @@ -386,8 +382,7 @@ print_byte_at: { bne !+ inc print_char_at.at+1 !: - lda print_hextab,x - sta print_char_at.ch + ldy print_hextab,x jsr print_char_at rts } @@ -395,10 +390,10 @@ print_byte_at: { // The rotation matrix is prepared by calling prepare_matrix() // The passed points must be in the interval [-$3f;$3f]. // Implemented in assembler to utilize seriously fast multiplication -// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage(8) z) +// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage($a) z) rotate_matrix: { .label y = 5 - .label z = 8 + .label z = $a txa sta xr lda y @@ -543,7 +538,7 @@ calculate_matrix: { .label sy = 3 .label t1 = 4 .label t3 = 5 - .label t4 = 8 + .label t4 = $a .label t5 = $b .label t6 = $c .label t7 = $d @@ -959,9 +954,9 @@ debug_print_init: { str11: .text "yp@" } // Print a string at a specific screen position -// print_str_at(byte* zeropage(6) str, byte* zeropage(9) at) +// print_str_at(byte* zeropage(6) str, byte* zeropage(8) at) print_str_at: { - .label at = 9 + .label at = 8 .label str = 6 b1: ldy #0 @@ -1014,7 +1009,7 @@ sprites_init: { sta SPRITES_ENABLE ldx #0 b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta sprites_ptr,x lda #GREEN sta SPRITES_COLS,x @@ -1024,6 +1019,9 @@ sprites_init: { rts } print_hextab: .text "0123456789abcdef" + // Positions to rotate + xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34 + ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34 zs: .byte $34, $34, $34, $34, $34, $34, $34, $34 // Rotated positions xrs: .fill 8, 0 @@ -1036,9 +1034,6 @@ sprites_init: { yps: .fill 8, 0 // The rotation matrix rotation_matrix: .fill 9, 0 - // Positions to rotate - xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34 - ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34 .pc = mulf_sqr1 "mulf_sqr1" .for(var i=0;i<$200;i++) { .if(i<=159) { .byte round((i*i)/256) } diff --git a/src/test/ref/examples/3d/perspective.asm b/src/test/ref/examples/3d/perspective.asm index 7dea6c315..db564e9c2 100644 --- a/src/test/ref/examples/3d/perspective.asm +++ b/src/test/ref/examples/3d/perspective.asm @@ -32,8 +32,8 @@ main: { rts } do_perspective: { - .label y = -$47 .label x = $39 + .label y = -$47 .label z = $36 lda #<$400 sta print_char_cursor @@ -240,9 +240,9 @@ mulf_init: { .label val = 6 .label sqr = 2 .label add = 4 - lda #1 + lda #<1 sta add - lda #0 + lda #>1 sta add+1 tax sta sqr diff --git a/src/test/ref/examples/bresenham/bitmap-bresenham.asm b/src/test/ref/examples/bresenham/bitmap-bresenham.asm index a5ee012ff..9c513d6a8 100644 --- a/src/test/ref/examples/bresenham/bitmap-bresenham.asm +++ b/src/test/ref/examples/bresenham/bitmap-bresenham.asm @@ -187,6 +187,7 @@ bitmap_plot: { .label _0 = 9 .label plotter_x = 9 .label plotter_y = $b + .label plotter = 9 lda bitmap_plot_xhi,x sta plotter_x+1 lda bitmap_plot_xlo,x @@ -204,8 +205,8 @@ bitmap_plot: { sta _0+1 lda bitmap_plot_bit,x ldy #0 - ora (_0),y - sta (_0),y + ora (plotter),y + sta (plotter),y rts } // bitmap_line_ydxi(byte zeropage(7) y, byte register(X) x, byte zeropage(6) y1, byte zeropage(3) yd, byte zeropage(4) xd) @@ -335,11 +336,11 @@ init_screen: { bitmap_clear: { .label bitmap = 9 .label y = 2 - .label _3 = 9 + .label _4 = 9 lda bitmap_plot_xlo - sta _3 + sta _4 lda bitmap_plot_xhi - sta _3+1 + sta _4+1 lda #0 sta y b1: diff --git a/src/test/ref/examples/chargen/chargen-analysis.asm b/src/test/ref/examples/chargen/chargen-analysis.asm index 3acea7f3d..9a4f94c32 100644 --- a/src/test/ref/examples/chargen/chargen-analysis.asm +++ b/src/test/ref/examples/chargen/chargen-analysis.asm @@ -312,10 +312,11 @@ mul8u: { .label mb = $b .label res = 9 .label return = 9 - lda #b + lda #b sta mb+1 + lda #<0 sta res sta res+1 b1: diff --git a/src/test/ref/examples/fastmultiply/fastmultiply8.asm b/src/test/ref/examples/fastmultiply/fastmultiply8.asm index 1ca0be223..b01b2b3b8 100644 --- a/src/test/ref/examples/fastmultiply/fastmultiply8.asm +++ b/src/test/ref/examples/fastmultiply/fastmultiply8.asm @@ -145,10 +145,11 @@ print_char_at: { rts } // Print a byte as HEX at a specific position -// print_byte_at(byte* zeropage(8) at) +// print_byte_at(byte zeropage($a) b, byte* zeropage(8) at) print_byte_at: { + .label b = $a .label at = 8 - lda print_sbyte_at.b + lda b lsr lsr lsr @@ -158,7 +159,7 @@ print_byte_at: { sta print_char_at.ch jsr print_char_at lda #$f - and print_sbyte_at.b + and b tay inc print_char_at.at bne !+ diff --git a/src/test/ref/examples/fire/fire.asm b/src/test/ref/examples/fire/fire.asm index d14cf06e3..e6481db83 100644 --- a/src/test/ref/examples/fire/fire.asm +++ b/src/test/ref/examples/fire/fire.asm @@ -307,7 +307,7 @@ sid_rnd_init: { fillscreen: { .label screen = 2 .label i = 4 - lda #0 + lda #<0 sta i sta i+1 b1: diff --git a/src/test/ref/examples/multiplexer/simple-multiplexer.asm b/src/test/ref/examples/multiplexer/simple-multiplexer.asm index 449776ef4..0b59051e7 100644 --- a/src/test/ref/examples/multiplexer/simple-multiplexer.asm +++ b/src/test/ref/examples/multiplexer/simple-multiplexer.asm @@ -219,13 +219,13 @@ init: { lda #VIC_DEN|VIC_RSEL|3 sta D011 jsr plexInit - lda #$20 + lda #<$20 sta xp - lda #0 + lda #>$20 sta xp+1 - tax + ldx #0 b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta PLEX_PTR,x txa asl diff --git a/src/test/ref/examples/plasma/plasma-unroll.asm b/src/test/ref/examples/plasma/plasma-unroll.asm index 6ac675a5a..761f2a967 100644 --- a/src/test/ref/examples/plasma/plasma-unroll.asm +++ b/src/test/ref/examples/plasma/plasma-unroll.asm @@ -254,7 +254,7 @@ makecharset: { sta print_char_cursor lda #>print_line_cursor sta print_char_cursor+1 - lda #0 + lda #<0 sta c sta c+1 b1: diff --git a/src/test/ref/examples/plasma/plasma.asm b/src/test/ref/examples/plasma/plasma.asm index 5bdbc6470..f0b03b983 100644 --- a/src/test/ref/examples/plasma/plasma.asm +++ b/src/test/ref/examples/plasma/plasma.asm @@ -190,7 +190,7 @@ makecharset: { sta print_char_cursor lda #>print_line_cursor sta print_char_cursor+1 - lda #0 + lda #<0 sta c sta c+1 b1: diff --git a/src/test/ref/examples/rotate/rotate.asm b/src/test/ref/examples/rotate/rotate.asm index e96371907..89dbfc313 100644 --- a/src/test/ref/examples/rotate/rotate.asm +++ b/src/test/ref/examples/rotate/rotate.asm @@ -27,14 +27,16 @@ main: { rts } anim: { - .label _4 = 7 - .label _6 = 9 + .label _4 = 5 + .label _6 = 5 .label _9 = 5 .label _10 = 5 .label _11 = 5 .label _12 = 5 - .label x = $b - .label y = $c + .label cos_a = $b + .label sin_a = $c + .label x = $d + .label y = $e .label xr = 7 .label yr = 9 .label xpos = 5 @@ -48,6 +50,11 @@ anim: { cmp RASTER bne b2 inc BORDERCOL + ldy angle + lda COS,y + sta cos_a + lda SIN,y + sta sin_a lda #0 sta sprite_msb sta i @@ -58,27 +65,25 @@ anim: { // signed fixed[7.0] lda ys,y sta y - ldy angle - lda COS,y + lda cos_a jsr mulf8u_prepare ldy x jsr mulf8s_prepared - lda mulf8s_prepared.return - sta _4 - lda mulf8s_prepared.return+1 - sta _4+1 - asl xr - rol xr+1 + lda _4 + asl + sta xr + lda _4+1 + rol + sta xr+1 ldy y jsr mulf8s_prepared - lda mulf8s_prepared.return - sta _6 - lda mulf8s_prepared.return+1 - sta _6+1 - asl yr - rol yr+1 - ldy angle - lda SIN,y + lda _6 + asl + sta yr + lda _6+1 + rol + sta yr+1 + lda sin_a jsr mulf8u_prepare ldy y jsr mulf8s_prepared @@ -104,18 +109,16 @@ anim: { adc _12+1 sta yr+1 lda xr+1 + tax + clc + adc #<$18+$95 sta xpos + txa ora #$7f bmi !+ lda #0 !: - sta xpos+1 - lda xpos - clc - adc #$18+$95 - sta xpos - lda xpos+1 - adc #0 + adc #>$18+$95 sta xpos+1 lsr sprite_msb cmp #0 @@ -153,35 +156,44 @@ anim: { // mulf8s_prepared(signed byte register(Y) b) mulf8s_prepared: { .label memA = $fd + .label _8 = $f + .label _12 = $f .label m = 5 .label return = 5 + tya jsr mulf8u_prepared lda memA cmp #0 bpl b1 lda m+1 - sty $ff + sta _8 + tya + eor #$ff sec - sbc $ff + adc _8 sta m+1 b1: cpy #0 bpl b2 lda m+1 + sta _12 + lda memA + eor #$ff sec - sbc memA + adc _12 sta m+1 b2: rts } // Calculate fast multiply with a prepared unsigned byte to a word result // The prepared number is set by calling mulf8u_prepare(byte a) +// mulf8u_prepared(byte register(A) b) mulf8u_prepared: { .label resL = $fe .label memB = $ff .label return = 5 - sty memB - ldx memB + sta memB + tax sec sm1: lda mulf_sqr1_lo,x @@ -218,7 +230,7 @@ init: { sta SPRITES_ENABLE ldx #0 b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta sprites_ptr,x lda #GREEN sta SPRITES_COLS,x @@ -246,7 +258,7 @@ mulf_init: { sta sqr1_lo lda #>mulf_sqr1_lo+1 sta sqr1_lo+1 - lda #0 + lda #<0 sta sqr sta sqr+1 tax diff --git a/src/test/ref/examples/scrolllogo/scrolllogo.asm b/src/test/ref/examples/scrolllogo/scrolllogo.asm index 638b1528c..bd40df77b 100644 --- a/src/test/ref/examples/scrolllogo/scrolllogo.asm +++ b/src/test/ref/examples/scrolllogo/scrolllogo.asm @@ -68,7 +68,7 @@ loop: { .label _1 = 9 .label _5 = 9 .label xpos = 9 - lda #0 + lda #<0 sta xsin_idx sta xsin_idx+1 b1: @@ -109,7 +109,7 @@ loop: { lda xsin_idx cmp #xsin sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 + lda #<0>>$10 sta x+2 + lda #>0>>$10 sta x+3 // u[4.28] b1: @@ -329,21 +332,25 @@ sin16s_gen2: { } // Multiply of two signed words to a signed double word // Fixes offsets introduced by using unsigned multiplication -// mul16s(signed word zeropage($17) a) +// mul16s(signed word zeropage($15) a) mul16s: { .label _9 = $f .label _16 = $f .label m = $b .label return = $b - .label a = $17 + .label a = $15 lda a sta mul16u.a lda a+1 sta mul16u.a+1 lda #sin16s_gen2.ampl - sta mul16u.b+1 + sta mul16u.mb+1 + lda #>$10 + sta mul16u.mb+2 + lda #>sin16s_gen2.ampl>>$10 + sta mul16u.mb+3 jsr mul16u lda a+1 bpl b2 @@ -366,23 +373,19 @@ mul16s: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage($11) a, word zeropage($f) b) +// mul16u(word zeropage($f) a, word zeropage($17) b) mul16u: { - .label mb = $13 - .label a = $11 + .label mb = $11 + .label a = $f .label res = $b .label return = $b - .label b = $f - lda b - sta mb - lda b+1 - sta mb+1 - lda #0 - sta mb+2 - sta mb+3 + .label b = $17 + lda #<0 sta res sta res+1 + lda #<0>>$10 sta res+2 + lda #>0>>$10 sta res+3 b1: lda a @@ -424,17 +427,18 @@ mul16u: { // sin16s(dword zeropage($b) x) sin16s: { .label _4 = $b + .label _20 = $15 .label x = $b - .label return = $17 - .label x1 = $1f - .label x2 = $19 - .label x3 = $19 + .label return = $15 + .label x1 = $1d + .label x2 = $15 + .label x3 = $15 .label x3_6 = $f - .label usinx = $17 - .label x4 = $19 + .label usinx = $1f + .label x4 = $15 .label x5 = $f .label x5_128 = $f - .label sinx = $17 + .label sinx = $15 .label isUpper = 4 lda x+3 cmp #>PI_u4f28>>$10 @@ -580,9 +584,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff @@ -597,19 +609,26 @@ sin16s: { } // 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 -// mulu16_sel(word zeropage($19) v1, word zeropage($f) v2, byte register(X) select) +// mulu16_sel(word zeropage($15) v1, word zeropage($17) v2, byte register(X) select) mulu16_sel: { .label _0 = $b .label _1 = $b - .label v1 = $19 - .label v2 = $f + .label v1 = $15 + .label v2 = $17 .label return = $f - .label return_1 = $19 - .label return_10 = $19 + .label return_1 = $15 + .label return_10 = $15 lda v1 sta mul16u.a lda v1+1 sta mul16u.a+1 + lda mul16u.b + sta mul16u.mb + lda mul16u.b+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u cpx #0 beq !e+ @@ -630,14 +649,14 @@ mulu16_sel: { // 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 div32u16u: { - .label quotient_hi = $11 + .label quotient_hi = $15 .label quotient_lo = $f - .label return = $1b + .label return = $19 lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 sta divr16u.dividend+1 - lda #0 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u diff --git a/src/test/ref/examples/sinplotter/sine-plotter.asm b/src/test/ref/examples/sinplotter/sine-plotter.asm index 76895de72..951d02189 100644 --- a/src/test/ref/examples/sinplotter/sine-plotter.asm +++ b/src/test/ref/examples/sinplotter/sine-plotter.asm @@ -36,7 +36,7 @@ .label sin2 = $1400 .label rem16u = 2 main: { - .const vicSelectGfxBank1_toDd001_return = 3^(>SCREEN)/$40 + .const vicSelectGfxBank1_toDd001_return = 3 .const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f sei // Disable normal interrupt @@ -73,7 +73,7 @@ render_sine: { .label sin2_val = 6 .label xpos = 4 .label sin_idx = 2 - lda #0 + lda #<0 sta xpos sta xpos+1 sta sin_idx @@ -149,7 +149,7 @@ render_sine: { lda xpos cmp #<$140 bne b2 - lda #0 + lda #<0 sta xpos sta xpos+1 b2: @@ -174,33 +174,34 @@ render_sine: { // Plot a single dot in the bitmap // bitmap_plot(word zeropage(4) x, byte register(X) y) bitmap_plot: { - .label _1 = $10 + .label _1 = $15 .label plotter = 6 + .label plotter_1 = $15 .label x = 4 - .label _3 = 6 + .label _4 = 6 lda bitmap_plot_yhi,x - sta _3+1 + sta _4+1 lda bitmap_plot_ylo,x - sta _3 + sta _4 lda x and #<$fff8 sta _1 lda x+1 and #>$fff8 sta _1+1 - lda plotter + lda plotter_1 clc - adc _1 - sta plotter - lda plotter+1 - adc _1+1 - sta plotter+1 + adc plotter + sta plotter_1 + lda plotter_1+1 + adc plotter+1 + sta plotter_1+1 lda x tay lda bitmap_plot_bit,y ldy #0 - ora (plotter),y - sta (plotter),y + ora (plotter_1),y + sta (plotter_1),y rts } // wrap_y(signed word zeropage(6) y) @@ -230,13 +231,13 @@ wrap_y: { sta y+1 jmp b3 b2: - sec lda y - sbc #$c8 + sec + sbc #<$c8 sta y - bcs !+ - dec y+1 - !: + lda y+1 + sbc #>$c8 + sta y+1 jmp b1 } // Generate signed word sinus table - with values in the range min-max. @@ -250,22 +251,24 @@ sin16s_gen2: { .label _5 = $c .label _6 = 6 .label _8 = 6 - .label step = $1b + .label step = $19 .label sintab = 2 .label x = 8 .label i = 4 jsr div32u16u - lda #0 + lda #<0 sta i sta i+1 lda #sin sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 + lda #<0>>$10 sta x+2 + lda #>0>>$10 sta x+3 // u[4.28] b1: @@ -325,21 +328,25 @@ sin16s_gen2: { } // Multiply of two signed words to a signed double word // Fixes offsets introduced by using unsigned multiplication -// mul16s(signed word zeropage($17) a) +// mul16s(signed word zeropage($15) a) mul16s: { .label _9 = 6 .label _16 = 6 .label m = $c .label return = $c - .label a = $17 + .label a = $15 lda a sta mul16u.a lda a+1 sta mul16u.a+1 lda #sin16s_gen2.ampl - sta mul16u.b+1 + sta mul16u.mb+1 + lda #>$10 + sta mul16u.mb+2 + lda #>sin16s_gen2.ampl>>$10 + sta mul16u.mb+3 jsr mul16u lda a+1 bpl b2 @@ -362,23 +369,19 @@ mul16s: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage($10) a, word zeropage(6) b) +// mul16u(word zeropage(6) a, word zeropage($17) b) mul16u: { - .label mb = $12 - .label a = $10 + .label mb = $10 + .label a = 6 .label res = $c .label return = $c - .label b = 6 - lda b - sta mb - lda b+1 - sta mb+1 - lda #0 - sta mb+2 - sta mb+3 + .label b = $17 + lda #<0 sta res sta res+1 + lda #<0>>$10 sta res+2 + lda #>0>>$10 sta res+3 b1: lda a @@ -420,18 +423,19 @@ mul16u: { // sin16s(dword zeropage($c) x) sin16s: { .label _4 = $c + .label _20 = $15 .label x = $c - .label return = $17 - .label x1 = $1f - .label x2 = $19 - .label x3 = $19 + .label return = $15 + .label x1 = $1d + .label x2 = $15 + .label x3 = $15 .label x3_6 = 6 - .label usinx = $17 - .label x4 = $19 + .label usinx = $1f + .label x4 = $15 .label x5 = 6 .label x5_128 = 6 - .label sinx = $17 - .label isUpper = $16 + .label sinx = $15 + .label isUpper = $14 lda x+3 cmp #>PI_u4f28>>$10 bcc b4 @@ -576,9 +580,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff @@ -593,19 +605,26 @@ sin16s: { } // 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 -// mulu16_sel(word zeropage($19) v1, word zeropage(6) v2, byte register(X) select) +// mulu16_sel(word zeropage($15) v1, word zeropage($17) v2, byte register(X) select) mulu16_sel: { .label _0 = $c .label _1 = $c - .label v1 = $19 - .label v2 = 6 + .label v1 = $15 + .label v2 = $17 .label return = 6 - .label return_1 = $19 - .label return_10 = $19 + .label return_1 = $15 + .label return_10 = $15 lda v1 sta mul16u.a lda v1+1 sta mul16u.a+1 + lda mul16u.b + sta mul16u.mb + lda mul16u.b+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u cpx #0 beq !e+ @@ -626,14 +645,14 @@ mulu16_sel: { // 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 div32u16u: { - .label quotient_hi = $10 + .label quotient_hi = $15 .label quotient_lo = 6 - .label return = $1b + .label return = $19 lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 sta divr16u.dividend+1 - lda #0 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u @@ -713,12 +732,12 @@ divr16u: { // Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 - .label y = $16 - .label _3 = 2 + .label y = $14 + .label _4 = 2 lda bitmap_plot_ylo - sta _3 + sta _4 lda bitmap_plot_yhi - sta _3+1 + sta _4+1 lda #0 sta y b1: @@ -742,7 +761,7 @@ bitmap_clear: { } // Initialize bitmap plotting tables bitmap_init: { - .label _3 = $16 + .label _3 = $14 .label yoffs = 2 ldx #0 lda #$80 diff --git a/src/test/ref/examples/sinsprites/sinus-sprites.asm b/src/test/ref/examples/sinsprites/sinus-sprites.asm index 6d699fc87..81a9c2d21 100644 --- a/src/test/ref/examples/sinsprites/sinus-sprites.asm +++ b/src/test/ref/examples/sinsprites/sinus-sprites.asm @@ -228,9 +228,9 @@ gen_sintab: { lda #>f_amp sta setMEMtoFAC.mem+1 jsr setMEMtoFAC - lda #2 + lda #<2 sta setFAC.w - lda #0 + lda #>2 sta setFAC.w+1 jsr setFAC lda #$a + sta mul16u.a+1 + lda #<$a + sta mul16u.mb + lda #>$a + sta mul16u.mb+1 + lda #<$a>>$10 + sta mul16u.mb+2 + lda #>$a>>$10 + sta mul16u.mb+3 + jsr mul16u + lda _0 + sta screen + lda _0+1 + sta screen+1 + lda _0+2 + sta screen+2 + lda _0+3 + sta screen+3 + lda #<$3e8 + sta mul16u.a + lda #>$3e8 + sta mul16u.a+1 + lda #<$3e8 + sta mul16u.mb + lda #>$3e8 + sta mul16u.mb+1 + lda #<$3e8>>$10 + sta mul16u.mb+2 + lda #>$3e8>>$10 + sta mul16u.mb+3 + jsr mul16u + lda _1 + sta screen+1*SIZEOF_DWORD + lda _1+1 + sta screen+1*SIZEOF_DWORD+1 + lda _1+2 + sta screen+1*SIZEOF_DWORD+2 + lda _1+3 + sta screen+1*SIZEOF_DWORD+3 + rts +} +// mul16u(word zeropage(6) a) +mul16u: { + .label return = 2 + .label mb = 2 + .label a = 6 + lda return + clc + adc a + sta return + lda return+1 + adc a+1 + sta return+1 + lda return+2 + adc #0 + sta return+2 + lda return+3 + adc #0 + sta return+3 + rts +} diff --git a/src/test/ref/gfxbank.asm b/src/test/ref/gfxbank.asm new file mode 100644 index 000000000..54c84cffb --- /dev/null +++ b/src/test/ref/gfxbank.asm @@ -0,0 +1,16 @@ +// Test minimization of constants +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // CIA#2 Port A: Serial bus, RS-232, VIC memory bank + .label CIA2_PORT_A = $dd00 + // CIA #2 Port A data direction register. + .label CIA2_PORT_A_DDR = $dd02 +main: { + .const vicSelectGfxBank1_toDd001_return = 3 + lda #3 + sta CIA2_PORT_A_DDR + lda #vicSelectGfxBank1_toDd001_return + sta CIA2_PORT_A + rts +} diff --git a/src/test/ref/halfscii.asm b/src/test/ref/halfscii.asm index 179529db1..b452a7471 100644 --- a/src/test/ref/halfscii.asm +++ b/src/test/ref/halfscii.asm @@ -7,10 +7,11 @@ .label D018 = $d018 .label CHARSET4 = $2800 main: { - .label _1 = 6 - .label _11 = 6 - .label _21 = 6 - .label _30 = 6 + .label _1 = 8 + .label _11 = 8 + .label _21 = 8 + .label _30 = 8 + .label chargen1 = 6 .label charset4 = 4 .label chargen = 2 sei @@ -25,13 +26,19 @@ main: { lda #>CHARGEN sta chargen+1 b1: + lda chargen + clc + adc #1 + sta chargen1 + lda chargen+1 + adc #0 + sta chargen1+1 lda #$60 ldy #0 and (chargen),y sta _1 lda #$60 - ldy #1 - and (chargen),y + and (chargen1),y lsr lsr ora _1 @@ -54,8 +61,7 @@ main: { and (chargen),y sta _11 lda #$18 - ldy #1 - and (chargen),y + and (chargen1),y lsr lsr ora _11 @@ -75,8 +81,7 @@ main: { asl sta _21 lda #6 - ldy #1 - and (chargen),y + and (chargen1),y lsr ora _21 tay @@ -95,8 +100,7 @@ main: { asl sta _30 lda #1 - tay - and (chargen),y + and (chargen1),y ora _30 tay lda bits_count,y diff --git a/src/test/ref/inline-function-if.asm b/src/test/ref/inline-function-if.asm index 8f77a44d9..d5729668a 100644 --- a/src/test/ref/inline-function-if.asm +++ b/src/test/ref/inline-function-if.asm @@ -6,8 +6,8 @@ main: { .const toUpper1_ch = 'c' .const toUpper2_ch = 'm' - .const toUpper1_res = toUpper1_ch+$40 - lda #toUpper1_res + .const toUpper1_return = toUpper1_ch+$40 + lda #toUpper1_return sta screen lda #toUpper2_ch sta screen+1 diff --git a/src/test/ref/inline-kasm-resource.asm b/src/test/ref/inline-kasm-resource.asm index f54a110c8..54b571824 100644 --- a/src/test/ref/inline-kasm-resource.asm +++ b/src/test/ref/inline-kasm-resource.asm @@ -8,7 +8,7 @@ .label SPRITES_XPOS = $d000 .label SPRITES_YPOS = $d001 main: { - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta SCREEN+$3f8 lda #1 sta SPRITES_ENABLE diff --git a/src/test/ref/inline-pointer-0.asm b/src/test/ref/inline-pointer-0.asm new file mode 100644 index 000000000..3e2b5610f --- /dev/null +++ b/src/test/ref/inline-pointer-0.asm @@ -0,0 +1,10 @@ +// Tests creating a literal pointer from two bytes +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = 4*$100 + lda #'a' + sta screen + rts +} diff --git a/src/test/ref/inline-pointer-1.asm b/src/test/ref/inline-pointer-1.asm new file mode 100644 index 000000000..4da10ae54 --- /dev/null +++ b/src/test/ref/inline-pointer-1.asm @@ -0,0 +1,24 @@ +// Tests creating a literal pointer from two bytes +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + ldx #0 + lda #4 + jsr puta + ldx #$18 + lda #5 + jsr puta + rts +} +// puta(byte register(A) ph, byte register(X) pl) +puta: { + .label screen = 2 + .label _2 = 2 + sta _2+1 + stx _2 + lda #'a' + ldy #0 + sta (screen),y + rts +} diff --git a/src/test/ref/inline-pointer-2.asm b/src/test/ref/inline-pointer-2.asm new file mode 100644 index 000000000..32a924a78 --- /dev/null +++ b/src/test/ref/inline-pointer-2.asm @@ -0,0 +1,9 @@ +// Tests creating a literal pointer from two bytes +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + lda #'a' + sta 4*$100+$28 + rts +} diff --git a/src/test/ref/inline-string-3.asm b/src/test/ref/inline-string-3.asm index aaf848ee9..1e2abba8f 100644 --- a/src/test/ref/inline-string-3.asm +++ b/src/test/ref/inline-string-3.asm @@ -7,17 +7,18 @@ main: { .label PTR = $9ffe .label SCREEN = $400 - .label _6 = 2 + .label ptr = 2 + .label _7 = 2 lda #STRING sta PTR+1 lda PTR - sta _6 + sta _7 lda PTR+1 - sta _6+1 + sta _7+1 ldy #0 - lda (_6),y + lda (ptr),y sta SCREEN rts STRING: .text "camelot" diff --git a/src/test/ref/inline-word-0.asm b/src/test/ref/inline-word-0.asm new file mode 100644 index 000000000..d1161c334 --- /dev/null +++ b/src/test/ref/inline-word-0.asm @@ -0,0 +1,13 @@ +// Tests minimal inline word +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = 2*$100+1 + lda #w + sta screen+1 + rts +} diff --git a/src/test/ref/inline-word-1.asm b/src/test/ref/inline-word-1.asm new file mode 100644 index 000000000..bb6135dcc --- /dev/null +++ b/src/test/ref/inline-word-1.asm @@ -0,0 +1,13 @@ +// Tests minimal inline word +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = 1*$100+2 + lda #w + sta screen+1 + rts +} diff --git a/src/test/ref/inline-word-2.asm b/src/test/ref/inline-word-2.asm new file mode 100644 index 000000000..bb6135dcc --- /dev/null +++ b/src/test/ref/inline-word-2.asm @@ -0,0 +1,13 @@ +// Tests minimal inline word +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = 1*$100+2 + lda #w + sta screen+1 + rts +} diff --git a/src/test/ref/inline-word.asm b/src/test/ref/inline-word.asm index 505c1ebc1..7b80c88b1 100644 --- a/src/test/ref/inline-word.asm +++ b/src/test/ref/inline-word.asm @@ -4,6 +4,7 @@ .label SCREEN = $400 main: { .label w = 3 + .label sc = 3 .label h = 2 lda #0 sta h @@ -17,7 +18,7 @@ main: { stx w lda #'*' ldy #0 - sta (w),y + sta (sc),y inx cpx #8 bne b2 diff --git a/src/test/ref/int-literals.asm b/src/test/ref/int-literals.asm index 8f7755754..dc02bae1d 100644 --- a/src/test/ref/int-literals.asm +++ b/src/test/ref/int-literals.asm @@ -10,11 +10,13 @@ .const TYPEID_SIGNED_DWORD = 6 .const RED = 2 .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 main: { .label s = 2 - lda #<$400 + lda #$400 + lda #>SCREEN sta s+1 b1: lda #' ' @@ -25,11 +27,11 @@ main: { inc s+1 !: lda s+1 - cmp #>$400+$3e8 + cmp #>SCREEN+$3e8 bcc b1 bne !+ lda s - cmp #<$400+$3e8 + cmp #$fff8 sta _1+1 - lda plotter + lda plotter_1 clc - adc _1 - sta plotter - lda plotter+1 - adc _1+1 - sta plotter+1 + adc plotter + sta plotter_1 + lda plotter_1+1 + adc plotter+1 + sta plotter_1+1 lda x tay lda bitmap_plot_bit,y ldy #0 - ora (plotter),y - sta (plotter),y + ora (plotter_1),y + sta (plotter_1),y rts } // Initialize the points to be animated // point_init(byte zeropage(2) point_idx) point_init: { + .label _0 = 9 + .label _1 = 3 .label _3 = 7 .label _4 = 3 .label _9 = 3 @@ -120,20 +123,28 @@ point_init: { .label abs16s1_return = 3 .label abs16s2__2 = 5 .label abs16s2_return = 5 - .label x_stepf = 5 + .label x_stepf = 3 .label x_diff = 9 lda point_idx asl - tax + tay + lda x_end,y + sta _0 + lda x_end+1,y + sta _0+1 lda point_idx asl tay + lda x_start,y + sta _1 + lda x_start+1,y + sta _1+1 + lda x_diff sec - lda x_end,x - sbc x_start,y + sbc _1 sta x_diff - lda x_end+1,x - sbc x_start+1,y + lda x_diff+1 + sbc _1+1 sta x_diff+1 ldy point_idx lda y_end,y @@ -229,8 +240,8 @@ point_init: { lda x_diff+1 bmi b4 // x add = 1.0 - ldy point_idx lda #$10 + ldy point_idx sta x_add,y b5: jsr divr16s @@ -278,23 +289,18 @@ point_init: { // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 // divr16s(signed word zeropage(9) divisor, signed word zeropage(7) rem) divr16s: { - .const dividend = 0 .label _10 = 7 .label _13 = 9 - .label resultu = 5 - .label return = 5 + .label _18 = 3 + .label remu = 7 + .label divisoru = 9 + .label resultu = 3 + .label return = 3 .label divisor = 9 .label rem = 7 - .label dividendu = 3 - .label divisoru = 9 - .label remu = 7 lda rem+1 bmi b1 - lda #dividend - sta dividendu - lda #0 - sta dividendu+1 - tay + ldy #0 b2: lda divisor+1 bmi b3 @@ -337,10 +343,6 @@ divr16s: { eor #$ff adc #0 sta _10+1 - lda #-dividend - sta dividendu - lda #0 - sta dividendu+1 ldy #1 jmp b2 } @@ -348,17 +350,19 @@ divr16s: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zeropage(3) dividend, word zeropage(9) divisor, word zeropage(7) rem) +// divr16u(word zeropage(5) dividend, word zeropage(9) divisor, word zeropage(7) rem) divr16u: { .label rem = 7 - .label dividend = 3 - .label quotient = 5 - .label return = 5 + .label dividend = 5 + .label quotient = 3 + .label return = 3 .label divisor = 9 ldx #0 txa sta quotient sta quotient+1 + sta dividend + sta dividend+1 b1: asl rem rol rem+1 @@ -434,11 +438,11 @@ screen_fill: { bitmap_clear: { .label bitmap = 3 .label y = 2 - .label _3 = 3 + .label _4 = 3 lda bitmap_plot_ylo - sta _3 + sta _4 lda bitmap_plot_yhi - sta _3+1 + sta _4+1 lda #0 sta y b1: diff --git a/src/test/ref/linegen.asm b/src/test/ref/linegen.asm index 4cbd79681..825a7fc29 100644 --- a/src/test/ref/linegen.asm +++ b/src/test/ref/linegen.asm @@ -38,7 +38,7 @@ main: { sta lin16u_gen.lintab lda #>lintab3 sta lin16u_gen.lintab+1 - lda #0 + lda #<0 sta lin16u_gen.min sta lin16u_gen.min+1 lda #<$6488 @@ -76,7 +76,7 @@ main: { lda #>str1 sta print_str.str+1 jsr print_str - lda #0 + lda #<0 sta print_word.w sta print_word.w+1 jsr print_word @@ -309,10 +309,11 @@ lin16u_gen: { lda ampl+1 sbc min+1 sta ampl+1 - lda #$14-1 + lda #<$14-1 sta divr16u.divisor - lda #0 + lda #>$14-1 sta divr16u.divisor+1 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u @@ -320,10 +321,11 @@ lin16u_gen: { sta stepi lda divr16u.return+1 sta stepi+1 - lda #$14-1 + lda #<$14-1 sta divr16u.divisor - lda #0 + lda #>$14-1 sta divr16u.divisor+1 + lda #<0 sta divr16u.dividend sta divr16u.dividend+1 jsr divr16u @@ -342,7 +344,7 @@ lin16u_gen: { sta val+2 lda min+1 sta val+3 - lda #0 + lda #<0 sta i sta i+1 b1: diff --git a/src/test/ref/liverange-call-problem.asm b/src/test/ref/liverange-call-problem.asm index ff5e1ea3d..933c49ae1 100644 --- a/src/test/ref/liverange-call-problem.asm +++ b/src/test/ref/liverange-call-problem.asm @@ -8,11 +8,11 @@ .label w2 = 2 main: { .label SCREEN = $400 - lda #0 + lda #<0 sta w1 sta w1+1 jsr incw1 - lda #0 + lda #<0 sta w2 sta w2+1 jsr incw2 diff --git a/src/test/ref/min-fmul-16.asm b/src/test/ref/min-fmul-16.asm index dc431ade4..ef4553748 100644 --- a/src/test/ref/min-fmul-16.asm +++ b/src/test/ref/min-fmul-16.asm @@ -226,7 +226,7 @@ mulf_init: { sta sqr1_lo lda #>mulf_sqr1_lo+1 sta sqr1_lo+1 - lda #0 + lda #<0 sta sqr sta sqr+1 tax diff --git a/src/test/ref/mixed-array-0.asm b/src/test/ref/mixed-array-0.asm new file mode 100644 index 000000000..3e2175924 --- /dev/null +++ b/src/test/ref/mixed-array-0.asm @@ -0,0 +1,15 @@ +// Test an array with mixed byte/number types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + lda msg + sta SCREEN + lda msg+1 + sta SCREEN+1 + lda msg+2 + sta SCREEN+2 + rts + msg: .byte 1, 2, 3 +} diff --git a/src/test/ref/mixed-array-1.asm b/src/test/ref/mixed-array-1.asm new file mode 100644 index 000000000..2d92feb78 --- /dev/null +++ b/src/test/ref/mixed-array-1.asm @@ -0,0 +1,15 @@ +// Test an array with mixed byte/number types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + lda msg + sta SCREEN + lda msg+1 + sta SCREEN+1 + lda msg+2 + sta SCREEN+2 + rts + msg: .byte -1, 0, 1 +} diff --git a/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm b/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm index b3658492e..f9d6d5695 100644 --- a/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm +++ b/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm @@ -167,13 +167,13 @@ init: { lda #VIC_DEN|VIC_RSEL|3 sta D011 jsr plexInit - lda #$20 + lda #<$20 sta xp - lda #0 + lda #>$20 sta xp+1 - tax + ldx #0 b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta PLEX_PTR,x txa asl diff --git a/src/test/ref/number-conversion.asm b/src/test/ref/number-conversion.asm index 17df64b44..412553a64 100644 --- a/src/test/ref/number-conversion.asm +++ b/src/test/ref/number-conversion.asm @@ -11,6 +11,8 @@ .const TYPEID_DWORD = 5 .const RED = 2 .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 main: { ldx #0 lda #TYPEID_SIGNED_BYTE @@ -167,14 +169,14 @@ assertType: { cmp t2 beq b1 lda #RED - sta $d800,x + sta COLS,x b2: tya - sta $400,x + sta SCREEN,x inx rts b1: lda #GREEN - sta $d800,x + sta COLS,x jmp b2 } diff --git a/src/test/ref/operator-lohi-problem.asm b/src/test/ref/operator-lohi-problem.asm index 83e1032ff..332ca079f 100644 --- a/src/test/ref/operator-lohi-problem.asm +++ b/src/test/ref/operator-lohi-problem.asm @@ -9,11 +9,9 @@ .label SCREEN = $400 main: { .const dw = $2000 - .const w1 = dw&$ffff - .const w2 = w1 sta SCREEN+1 lda #$c8 sta xpos+1 - tax + ldx #0 b1: stx position_sprite.spriteno jsr position_sprite diff --git a/src/test/ref/scan-desire-problem.asm b/src/test/ref/scan-desire-problem.asm index 248cffd38..377b83bf5 100644 --- a/src/test/ref/scan-desire-problem.asm +++ b/src/test/ref/scan-desire-problem.asm @@ -172,10 +172,11 @@ mul8u: { .label mb = 6 .label res = 4 .label return = 4 - lda #b + lda #b sta mb+1 + lda #<0 sta res sta res+1 b1: diff --git a/src/test/ref/semi-struct-2.asm b/src/test/ref/semi-struct-2.asm index 0429bcc2f..d54d7ac9c 100644 --- a/src/test/ref/semi-struct-2.asm +++ b/src/test/ref/semi-struct-2.asm @@ -730,10 +730,11 @@ mul8u: { .label mb = 2 .label res = 8 .label return = 8 - lda #SIZEOF_ENTRY + lda #SIZEOF_ENTRY sta mb+1 + lda #<0 sta res sta res+1 b1: diff --git a/src/test/ref/signed-indexed-subtract.asm b/src/test/ref/signed-indexed-subtract.asm index e82d13764..7ca3ce033 100644 --- a/src/test/ref/signed-indexed-subtract.asm +++ b/src/test/ref/signed-indexed-subtract.asm @@ -2,22 +2,25 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .label print_line_cursor = 2 + .label print_line_cursor = 3 .label print_char_cursor = 7 main: { - ldy #0 + .label i = 2 + lda #0 + sta i b1: - tya + lda i ldx #$80 jsr sub - tya + lda i ldx #$40 jsr sub - tya + lda i ldx #$40 jsr sub - iny - cpy #9 + inc i + lda #9 + cmp i bne b1 jsr print_cls lda #<$400 @@ -71,9 +74,9 @@ print_ln: { rts } // Print a signed word as HEX -// print_sword(signed word zeropage(4) w) +// print_sword(signed word zeropage(5) w) print_sword: { - .label w = 4 + .label w = 5 lda w+1 bpl b1 lda #'-' @@ -92,19 +95,21 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(5) w) print_word: { - lda print_sword.w+1 + .label w = 5 + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts } // Print a byte as HEX -// print_byte(byte zeropage(6) b) +// print_byte(byte zeropage(2) b) print_byte: { - .label b = 6 + .label b = 2 lda b lsr lsr @@ -133,7 +138,7 @@ print_char: { } // Clear the screen. Also resets current line/char cursor. print_cls: { - .label sc = 2 + .label sc = 3 lda #<$400 sta sc lda #>$400 @@ -156,16 +161,20 @@ print_cls: { } // sub(byte register(A) idx, byte register(X) s) sub: { + .label _1 = 3 asl + tay + txa + sta _1 + lda #0 + sta _1+1 + lda words,y sec - stx $ff - tax - lda words,x - sbc $ff - sta words,x - bcs !+ - dec words+1,x - !: + sbc _1 + sta words,y + lda words+1,y + sbc _1+1 + sta words+1,y rts } print_hextab: .text "0123456789abcdef" diff --git a/src/test/ref/signed-words.asm b/src/test/ref/signed-words.asm index e85a5777d..9a92c64eb 100644 --- a/src/test/ref/signed-words.asm +++ b/src/test/ref/signed-words.asm @@ -25,21 +25,22 @@ .label yvel_22 = 6 main: { jsr init - lda #$64 + lda #<$64 sta yvel_init - lda #0 + lda #>$64 sta yvel_init+1 - lda #$c8 + lda #<$c8 sta xvel - lda #0 + lda #>$c8 sta xvel+1 + lda #<0 sta ypos sta ypos+1 sta xpos sta xpos+1 - lda #$64 + lda #<$64 sta yvel_12 - lda #0 + lda #>$64 sta yvel_12+1 b1: lda #$ff @@ -64,13 +65,20 @@ anim: { eor #$ff adc #0 sta xvel+1 + lda #$a + sta $fe + ora #$7f + bmi !+ + lda #0 + !: + sta $ff sec lda yvel_init - sbc #$a + sbc $fe sta yvel_init - bcs !+ - dec yvel_init+1 - !: + lda yvel_init+1 + sbc $ff + sta yvel_init+1 lda yvel_init cmp #<-$c8 lda yvel_init+1 @@ -79,16 +87,16 @@ anim: { eor #$80 !: bpl b3 - lda #$c8 + lda #<$c8 sta yvel - lda #0 + lda #>$c8 sta yvel+1 b3: lda yvel sta yvel_22 lda yvel+1 sta yvel_22+1 - lda #0 + lda #<0 sta ypos sta ypos+1 sta xpos @@ -182,7 +190,7 @@ init: { sta SPRITES_YPOS lda #WHITE sta SPRITES_COLS - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta SPRITES_PTR lda #f_i sta setMEMtoFAC.mem+1 jsr setMEMtoFAC - lda #$19 + lda #<$19 sta setFAC.w - lda #0 + lda #>$19 sta setFAC.w+1 jsr setFAC jsr divMEMbyFAC diff --git a/src/test/ref/sinusgen16.asm b/src/test/ref/sinusgen16.asm index f9d538a19..380d92e7c 100644 --- a/src/test/ref/sinusgen16.asm +++ b/src/test/ref/sinusgen16.asm @@ -112,11 +112,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(6) w) print_word: { - lda print_sword.w+1 + .label w = 6 + lda w+1 tax jsr print_byte - lda print_sword.w + lda w tax jsr print_byte rts @@ -178,22 +180,24 @@ print_cls: { // sin16s_gen(signed word* zeropage(2) sintab) sin16s_gen: { .label _1 = 6 - .label step = $1b + .label step = $19 .label sintab = 2 .label x = $a .label i = 4 jsr div32u16u - lda #0 + lda #<0 sta i sta i+1 lda #main.sintab1 sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 + lda #<0>>$10 sta x+2 + lda #>0>>$10 sta x+3 // u[4.28] b1: @@ -252,16 +256,17 @@ sin16s_gen: { // sin16s(dword zeropage($f) x) sin16s: { .label _4 = $f + .label _20 = 6 .label x = $f .label return = 6 - .label x1 = $1f - .label x2 = 8 - .label x3 = 8 - .label x3_6 = $13 - .label usinx = 6 - .label x4 = 8 - .label x5 = $13 - .label x5_128 = $13 + .label x1 = $1d + .label x2 = 6 + .label x3 = 6 + .label x3_6 = 8 + .label usinx = $1f + .label x4 = 6 + .label x5 = 8 + .label x5_128 = 8 .label sinx = 6 .label isUpper = $e lda x+3 @@ -408,9 +413,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff @@ -425,15 +438,15 @@ sin16s: { } // 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 -// mulu16_sel(word zeropage(8) v1, word zeropage($13) v2, byte register(X) select) +// mulu16_sel(word zeropage(6) v1, word zeropage(8) v2, byte register(X) select) mulu16_sel: { .label _0 = $f .label _1 = $f - .label v1 = 8 - .label v2 = $13 - .label return = $13 - .label return_1 = 8 - .label return_10 = 8 + .label v1 = 6 + .label v2 = 8 + .label return = 8 + .label return_1 = 6 + .label return_10 = 6 lda v1 sta mul16u.a lda v1+1 @@ -456,12 +469,12 @@ mulu16_sel: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage($15) a, word zeropage($13) b) +// mul16u(word zeropage($13) a, word zeropage(8) b) mul16u: { - .label mb = $17 - .label a = $15 + .label a = $13 + .label mb = $15 .label res = $f - .label b = $13 + .label b = 8 .label return = $f lda b sta mb @@ -472,7 +485,9 @@ mul16u: { sta mb+3 sta res sta res+1 + lda #<0>>$10 sta res+2 + lda #>0>>$10 sta res+3 b1: lda a @@ -513,12 +528,12 @@ mul16u: { div32u16u: { .label quotient_hi = 8 .label quotient_lo = 6 - .label return = $1b + .label return = $19 lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 sta divr16u.dividend+1 - lda #0 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u diff --git a/src/test/ref/sinusgen16b.asm b/src/test/ref/sinusgen16b.asm index c99639748..b5f324cfa 100644 --- a/src/test/ref/sinusgen16b.asm +++ b/src/test/ref/sinusgen16b.asm @@ -129,11 +129,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(8) w) print_word: { - lda print_sword.w+1 + .label w = 8 + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts @@ -196,23 +198,25 @@ print_cls: { // wavelength - the number of sinus points in a total sinus wavelength (the size of the table) // sin16s_genb(signed word* zeropage(2) sintab) sin16s_genb: { - .label _2 = 8 - .label step = $1d + .label _2 = 6 + .label step = $1b .label sintab = 2 .label x = $d .label i = 4 jsr div32u16u - lda #0 + lda #<0 sta i sta i+1 lda #main.sintab2 sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 + lda #<0>>$10 sta x+2 + lda #>0>>$10 sta x+3 // u[4.28] b1: @@ -266,17 +270,18 @@ sin16s_genb: { // result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff // sin16sb(word zeropage(6) x) sin16sb: { + .label _19 = 6 .label x = 6 - .label return = 8 + .label return = 6 .label x1 = 6 - .label x2 = $b - .label x3 = $b - .label x3_6 = $11 - .label usinx = 8 - .label x4 = $b - .label x5 = $11 - .label x5_128 = $11 - .label sinx = 8 + .label x2 = 8 + .label x3 = 8 + .label x3_6 = $b + .label usinx = $1f + .label x4 = 8 + .label x5 = $b + .label x5_128 = $b + .label sinx = 6 .label isUpper = $a lda x+1 cmp #>PI_u4f12 @@ -388,9 +393,17 @@ sin16sb: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _19 + lda usinx+1 + sta _19+1 sec lda sinx eor #$ff @@ -405,19 +418,19 @@ sin16sb: { } // 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 -// mulu16_sel(word zeropage($b) v1, word zeropage($11) v2, byte register(X) select) +// mulu16_sel(word zeropage(8) v1, word zeropage($b) v2, byte register(X) select) mulu16_sel: { - .label _0 = $15 - .label _1 = $15 - .label v1 = $b - .label v2 = $11 - .label return = $b - .label return_11 = $11 - .label return_14 = $11 - .label return_16 = $11 - .label return_17 = $11 - .label return_18 = $11 - .label return_20 = $11 + .label _0 = $13 + .label _1 = $13 + .label v1 = 8 + .label v2 = $b + .label return = 8 + .label return_11 = $b + .label return_14 = $b + .label return_16 = $b + .label return_17 = $b + .label return_18 = $b + .label return_20 = $b lda v1 sta mul16u.a lda v1+1 @@ -440,13 +453,13 @@ mulu16_sel: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage($13) a, word zeropage($11) b) +// mul16u(word zeropage($11) a, word zeropage($b) b) mul16u: { - .label mb = $19 - .label a = $13 - .label res = $15 - .label b = $11 - .label return = $15 + .label a = $11 + .label mb = $17 + .label res = $13 + .label b = $b + .label return = $13 lda b sta mb lda b+1 @@ -456,7 +469,9 @@ mul16u: { sta mb+3 sta res sta res+1 + lda #<0>>$10 sta res+2 + lda #>0>>$10 sta res+3 b1: lda a @@ -497,12 +512,12 @@ mul16u: { div32u16u: { .label quotient_hi = 8 .label quotient_lo = 6 - .label return = $1d + .label return = $1b lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 sta divr16u.dividend+1 - lda #0 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u @@ -585,22 +600,24 @@ divr16u: { // sin16s_gen(signed word* zeropage(2) sintab) sin16s_gen: { .label _1 = 6 - .label step = $1d + .label step = $1b .label sintab = 2 .label x = $d .label i = 4 jsr div32u16u - lda #0 + lda #<0 sta i sta i+1 lda #main.sintab1 sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 + lda #<0>>$10 sta x+2 + lda #>0>>$10 sta x+3 // u[4.28] b1: @@ -656,19 +673,20 @@ sin16s_gen: { // 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 -// sin16s(dword zeropage($15) x) +// sin16s(dword zeropage($13) x) sin16s: { - .label _4 = $15 - .label x = $15 + .label _4 = $13 + .label _20 = 6 + .label x = $13 .label return = 6 - .label x1 = 8 - .label x2 = $b - .label x3 = $b - .label x3_6 = $11 - .label usinx = 6 - .label x4 = $b - .label x5 = $11 - .label x5_128 = $11 + .label x1 = 6 + .label x2 = 8 + .label x3 = 8 + .label x3_6 = $b + .label usinx = $1f + .label x4 = 8 + .label x5 = $b + .label x5_128 = $b .label sinx = 6 .label isUpper = $a lda x+3 @@ -815,9 +833,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff diff --git a/src/test/ref/sinusgen8.asm b/src/test/ref/sinusgen8.asm index 9c3cdd67e..0c037f3c0 100644 --- a/src/test/ref/sinusgen8.asm +++ b/src/test/ref/sinusgen8.asm @@ -11,6 +11,7 @@ .label print_char_cursor = 5 main: { .label wavelength = $c0 + .label _2 = 4 .label sb = 4 jsr sin8s_gen jsr print_cls @@ -20,9 +21,11 @@ main: { sta print_char_cursor+1 ldx #0 b1: + lda sintabref,x + sta _2 lda sintab2,x sec - sbc sintabref,x + sbc sb sta sb bmi b2 lda #main.sintab2 sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 // u[4.12] @@ -170,6 +175,7 @@ sin8s_gen: { lda x+1 sta sin8s.x+1 jsr sin8s + tya ldy #0 sta (sintab),y inc sintab @@ -297,16 +303,17 @@ sin8s: { bcc b3 dex b3: + txa + tay lda isUpper cmp #0 - beq b14 + beq b4 txa eor #$ff clc adc #1 - rts - b14: - txa + tay + b4: rts } // Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result. diff --git a/src/test/ref/sinusgen8b.asm b/src/test/ref/sinusgen8b.asm index 7ab3110de..e9cafe49a 100644 --- a/src/test/ref/sinusgen8b.asm +++ b/src/test/ref/sinusgen8b.asm @@ -129,8 +129,10 @@ print_char: { rts } // Print a byte as HEX +// print_byte(byte zeropage(4) b) print_byte: { - lda print_sbyte.b + .label b = 4 + lda b lsr lsr lsr @@ -139,7 +141,7 @@ print_byte: { lda print_hextab,y jsr print_char lda #$f - and print_sbyte.b + and b tay lda print_hextab,y jsr print_char @@ -179,17 +181,19 @@ sin16s_gen: { .label x = 7 .label i = 5 jsr div32u16u - lda #0 + lda #<0 sta i sta i+1 lda #main.sintabw sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 + lda #<0>>$10 sta x+2 + lda #>0>>$10 sta x+3 // u[4.28] b1: @@ -248,16 +252,17 @@ sin16s_gen: { // sin16s(dword zeropage($b) x) sin16s: { .label _4 = $b + .label _20 = $f .label x = $b .label return = $f - .label x1 = $20 - .label x2 = $11 - .label x3 = $11 - .label x3_6 = $13 - .label usinx = $f - .label x4 = $11 - .label x5 = $13 - .label x5_128 = $13 + .label x1 = $1a + .label x2 = $f + .label x3 = $f + .label x3_6 = $11 + .label usinx = $20 + .label x4 = $f + .label x5 = $11 + .label x5_128 = $11 .label sinx = $f .label isUpper = 4 lda x+3 @@ -404,9 +409,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff @@ -421,15 +434,15 @@ sin16s: { } // 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 -// mulu16_sel(word zeropage($11) v1, word zeropage($13) v2, byte register(X) select) +// mulu16_sel(word zeropage($f) v1, word zeropage($11) v2, byte register(X) select) mulu16_sel: { .label _0 = $b .label _1 = $b - .label v1 = $11 - .label v2 = $13 - .label return = $13 - .label return_1 = $11 - .label return_10 = $11 + .label v1 = $f + .label v2 = $11 + .label return = $11 + .label return_1 = $f + .label return_10 = $f lda v1 sta mul16u.a lda v1+1 @@ -452,12 +465,12 @@ mulu16_sel: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage($15) a, word zeropage($13) b) +// mul16u(word zeropage($13) a, word zeropage($11) b) mul16u: { - .label mb = $17 - .label a = $15 + .label a = $13 + .label mb = $15 .label res = $b - .label b = $13 + .label b = $11 .label return = $b lda b sta mb @@ -468,7 +481,9 @@ mul16u: { sta mb+3 sta res sta res+1 + lda #<0>>$10 sta res+2 + lda #>0>>$10 sta res+3 b1: lda a @@ -514,7 +529,7 @@ div32u16u: { sta divr16u.dividend lda #>PI2_u4f28>>$10 sta divr16u.dividend+1 - lda #0 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u @@ -601,14 +616,14 @@ sin8s_gen: { .label x = 2 .label i = $11 jsr div16u - lda #0 + lda #<0 sta i sta i+1 lda #main.sintabb sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 // u[4.12] @@ -618,6 +633,7 @@ sin8s_gen: { lda x+1 sta sin8s.x+1 jsr sin8s + tya ldy #0 sta (sintab),y inc sintab @@ -745,25 +761,26 @@ sin8s: { bcc b3 dex b3: + txa + tay lda isUpper cmp #0 - beq b14 + beq b4 txa eor #$ff clc adc #1 - rts - b14: - txa + tay + b4: rts } // 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 -// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($1b) select) +// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($19) select) mulu8_sel: { .label _0 = $13 .label _1 = $13 - .label select = $1b + .label select = $19 tya jsr mul8u ldy select @@ -780,7 +797,7 @@ mulu8_sel: { // Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word // mul8u(byte register(X) a, byte register(A) b) mul8u: { - .label mb = $15 + .label mb = $1a .label res = $13 .label return = $13 sta mb @@ -822,7 +839,7 @@ div16u: { sta divr16u.dividend lda #>PI2_u4f12 sta divr16u.dividend+1 - lda #0 + lda #<0 sta divr16u.rem sta divr16u.rem+1 jsr divr16u diff --git a/src/test/ref/sinusgenscale8.asm b/src/test/ref/sinusgenscale8.asm index 7cbff336f..792e19135 100644 --- a/src/test/ref/sinusgenscale8.asm +++ b/src/test/ref/sinusgenscale8.asm @@ -86,14 +86,14 @@ sin8u_table: { lda #>$400 sta print_line_cursor+1 jsr print_ln - lda #0 + lda #<0 sta i sta i+1 lda #main.sintab sta sintab+1 - lda #0 + lda #<0 sta x sta x+1 // u[4.12] @@ -103,8 +103,7 @@ sin8u_table: { lda x+1 sta sin8s.x+1 jsr sin8s - sta sinx - tay + sty sinx jsr mul8su lda sinx_sc+1 tax @@ -327,7 +326,10 @@ mul8su: { .label return = $f tya tax - lda #b + lda #b + sta mul8u.mb+1 jsr mul8u cpy #0 bpl b1 @@ -344,9 +346,7 @@ mul8u: { .label mb = $b .label res = $f .label return = $f - sta mb - lda #0 - sta mb+1 + lda #<0 sta res sta res+1 b1: @@ -473,16 +473,17 @@ sin8s: { bcc b3 dex b3: + txa + tay lda isUpper cmp #0 - beq b14 + beq b4 txa eor #$ff clc adc #1 - rts - b14: - txa + tay + b4: rts } // Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result. @@ -493,6 +494,9 @@ mulu8_sel: { .label _1 = $f .label select = $11 tya + sta mul8u.mb + lda #0 + sta mul8u.mb+1 jsr mul8u ldy select beq !e+ diff --git a/src/test/ref/sizeof-expr.asm b/src/test/ref/sizeof-expr.asm index 1749feae1..5720d470d 100644 --- a/src/test/ref/sizeof-expr.asm +++ b/src/test/ref/sizeof-expr.asm @@ -6,6 +6,7 @@ .const SIZEOF_BYTE = 1 .const SIZEOF_WORD = 2 .const SIZEOF_POINTER = 2 + .const SIZEOF_NUMBER = $ff main: { .const sz = $f .label b = 2 @@ -15,13 +16,16 @@ main: { sta b sta w sta w+1 - lda #'0'+SIZEOF_BYTE + //byte[] sb = { 'a', 'b', 'c', 0}; + lda #'0'+SIZEOF_NUMBER sta SCREEN + lda #'0'+SIZEOF_BYTE sta SCREEN+1 sta SCREEN+2 sta SCREEN+3 - lda #'0'+SIZEOF_WORD + lda #'0'+SIZEOF_NUMBER sta SCREEN+5 + lda #'0'+SIZEOF_WORD sta SCREEN+6 lda #'0'+SIZEOF_POINTER sta SCREEN+8 @@ -36,7 +40,5 @@ main: { sta SCREEN+$e lda #'0'+8*SIZEOF_BYTE sta SCREEN+$f - lda #'0'+$c*SIZEOF_BYTE - sta SCREEN+$10 rts } diff --git a/src/test/ref/test-comparisons-sword.asm b/src/test/ref/test-comparisons-sword.asm index 426dacc95..7040fecd8 100644 --- a/src/test/ref/test-comparisons-sword.asm +++ b/src/test/ref/test-comparisons-sword.asm @@ -323,11 +323,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage($a) w) print_word: { - lda print_sword.w+1 + .label w = $a + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts diff --git a/src/test/ref/test-division.asm b/src/test/ref/test-division.asm index 6f74de8b7..d7b963748 100644 --- a/src/test/ref/test-division.asm +++ b/src/test/ref/test-division.asm @@ -4,8 +4,8 @@ .pc = $80d "Program" .label print_char_cursor = 8 .label print_line_cursor = 3 - .label rem16u = $a - .label rem16s = $a + .label rem16u = $e + .label rem16s = $e main: { jsr print_cls jsr test_8u @@ -17,7 +17,7 @@ main: { test_16s: { .label dividend = 5 .label divisor = $13 - .label res = $e + .label res = $c .label i = 2 lda #0 sta i @@ -198,7 +198,7 @@ print_str: { // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 // div16s(signed word zeropage(5) dividend, signed word zeropage($13) divisor) div16s: { - .label return = $e + .label return = $c .label dividend = 5 .label divisor = $13 lda dividend @@ -217,25 +217,21 @@ div16s: { // 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 -// divr16s(signed word zeropage(8) dividend, signed word zeropage($c) divisor) +// divr16s(signed word zeropage(8) dividend, signed word zeropage($a) divisor) divr16s: { - .const rem = 0 .label _8 = 8 - .label _13 = $c - .label resultu = $e - .label return = $e - .label dividend = 8 - .label divisor = $c + .label _13 = $a + .label _16 = $e + .label _18 = $c .label dividendu = 8 - .label divisoru = $c - .label remu = $a + .label divisoru = $a + .label resultu = $c + .label return = $c + .label dividend = 8 + .label divisor = $a lda dividend+1 bmi b1 - lda #rem - sta remu - lda #0 - sta remu+1 - tay + ldy #0 b2: lda divisor+1 bmi b3 @@ -287,10 +283,6 @@ divr16s: { eor #$ff adc #0 sta _8+1 - lda #-rem - sta remu - lda #0 - sta remu+1 ldy #1 jmp b2 } @@ -298,17 +290,19 @@ divr16s: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zeropage(8) dividend, word zeropage($c) divisor, word zeropage($a) rem) +// divr16u(word zeropage(8) dividend, word zeropage($a) divisor, word zeropage($e) rem) divr16u: { - .label rem = $a + .label rem = $e .label dividend = 8 - .label quotient = $e - .label return = $e - .label divisor = $c + .label quotient = $c + .label return = $c + .label divisor = $a ldx #0 txa sta quotient sta quotient+1 + sta rem + sta rem+1 b1: asl rem rol rem+1 @@ -446,7 +440,7 @@ div8s: { tay lda neg cmp #0 - beq b9 + beq b5 txa eor #$ff clc @@ -457,7 +451,7 @@ div8s: { clc adc #1 rts - b9: + b5: tya rts b3: @@ -537,8 +531,8 @@ divr8u: { } test_16u: { .label dividend = 5 - .label divisor = $c - .label res = $e + .label divisor = $a + .label res = $c .label i = 2 lda #0 sta i @@ -606,18 +600,15 @@ test_16u: { // Returns the quotient dividend/divisor. // The remainder will be set into the global variable rem16u // Implemented using simple binary division -// div16u(word zeropage(5) dividend, word zeropage($c) divisor) +// div16u(word zeropage(5) dividend, word zeropage($a) divisor) div16u: { - .label return = $e + .label return = $c .label dividend = 5 - .label divisor = $c + .label divisor = $a lda dividend sta divr16u.dividend lda dividend+1 sta divr16u.dividend+1 - lda #0 - sta divr16u.rem - sta divr16u.rem+1 jsr divr16u rts } diff --git a/src/test/ref/test-multiply-16bit.asm b/src/test/ref/test-multiply-16bit.asm index e5701b8c6..e9858cdce 100644 --- a/src/test/ref/test-multiply-16bit.asm +++ b/src/test/ref/test-multiply-16bit.asm @@ -340,7 +340,9 @@ print_sword: { // mulf16s(signed word zeropage(3) a, signed word zeropage(5) b) mulf16s: { .label _9 = 9 + .label _10 = $15 .label _13 = 9 + .label _14 = $15 .label _16 = 9 .label _17 = 9 .label m = $11 @@ -362,12 +364,16 @@ mulf16s: { sta _9 lda m+3 sta _9+1 + lda b + sta _10 + lda b+1 + sta _10+1 lda _16 sec - sbc b + sbc _10 sta _16 lda _16+1 - sbc b+1 + sbc _10+1 sta _16+1 lda _16 sta m+2 @@ -380,12 +386,16 @@ mulf16s: { sta _13 lda m+3 sta _13+1 + lda a + sta _14 + lda a+1 + sta _14+1 lda _17 sec - sbc a + sbc _14 sta _17 lda _17+1 - sbc a+1 + sbc _14+1 sta _17+1 lda _17 sta m+2 @@ -519,21 +529,30 @@ mulf16u: { // mul16s(signed word zeropage(3) a, signed word zeropage(5) b) mul16s: { .label _9 = 9 + .label _10 = $15 .label _13 = 9 + .label _14 = $15 .label _16 = 9 .label _17 = 9 .label m = $19 .label return = $19 .label a = 3 .label b = 5 - lda b - sta mul16u.b - lda b+1 - sta mul16u.b+1 lda a sta mul16u.a lda a+1 sta mul16u.a+1 + lda b + sta mul16u.b + lda b+1 + sta mul16u.b+1 + lda mul16u.b + sta mul16u.mb + lda mul16u.b+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u lda a+1 bpl b1 @@ -541,12 +560,16 @@ mul16s: { sta _9 lda m+3 sta _9+1 + lda b + sta _10 + lda b+1 + sta _10+1 lda _16 sec - sbc b + sbc _10 sta _16 lda _16+1 - sbc b+1 + sbc _10+1 sta _16+1 lda _16 sta m+2 @@ -559,12 +582,16 @@ mul16s: { sta _13 lda m+3 sta _13+1 + lda a + sta _14 + lda a+1 + sta _14+1 lda _17 sec - sbc a + sbc _14 sta _17 lda _17+1 - sbc a+1 + sbc _14+1 sta _17+1 lda _17 sta m+2 @@ -574,23 +601,20 @@ mul16s: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage(9) a, word zeropage($17) b) +// mul16u(word zeropage(9) a, word zeropage($15) b) mul16u: { .label mb = $11 .label a = 9 .label res = $19 + .label b = $15 .label return = $19 - .label b = $17 - lda b - sta mb - lda b+1 - sta mb+1 - lda #0 - sta mb+2 - sta mb+3 + .label b_1 = $17 + lda #<0 sta res sta res+1 + lda #<0>>$10 sta res+2 + lda #>0>>$10 sta res+3 b1: lda a @@ -643,12 +667,14 @@ muls16s: { lda a beq b5 !: - lda #0 + lda #<0 sta j sta j+1 sta m sta m+1 + lda #<0>>$10 sta m+2 + lda #>0>>$10 sta m+3 b3: lda b+1 @@ -682,19 +708,23 @@ muls16s: { bne b3 rts b5: - lda #0 + lda #<0 sta return sta return+1 + lda #<0>>$10 sta return+2 + lda #>0>>$10 sta return+3 rts b6: - lda #0 + lda #<0 sta i sta i+1 sta m sta m+1 + lda #<0>>$10 sta m+2 + lda #>0>>$10 sta m+3 b4: lda b+1 @@ -774,6 +804,13 @@ mul16u_compare: { sta mul16u.a lda a+1 sta mul16u.a+1 + lda mul16u.b_1 + sta mul16u.mb + lda mul16u.b_1+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u jsr mulf16u lda ms @@ -822,7 +859,9 @@ mul16u_compare: { b5: iny cpy #$10 - bne b2 + beq !b2+ + jmp b2 + !b2: inc i lda #$10 cmp i @@ -926,12 +965,14 @@ muls16u: { lda a+1 beq b3 !: - lda #0 + lda #<0 sta i sta i+1 sta m sta m+1 + lda #<0>>$10 sta m+2 + lda #>0>>$10 sta m+3 b2: lda m @@ -959,10 +1000,12 @@ muls16u: { bne b2 rts b3: - lda #0 + lda #<0 sta return sta return+1 + lda #<0>>$10 sta return+2 + lda #>0>>$10 sta return+3 rts } @@ -985,7 +1028,7 @@ mulf_init: { sta sqr1_lo lda #>mulf_sqr1_lo+1 sta sqr1_lo+1 - lda #0 + lda #<0 sta sqr sta sqr+1 tax diff --git a/src/test/ref/test-multiply-8bit.asm b/src/test/ref/test-multiply-8bit.asm index 92b5ae098..5cf013274 100644 --- a/src/test/ref/test-multiply-8bit.asm +++ b/src/test/ref/test-multiply-8bit.asm @@ -267,26 +267,36 @@ print_sbyte: { // Fixes offsets introduced by using unsigned multiplication // mul8s(signed byte zeropage(2) a, signed byte register(Y) b) mul8s: { + .label _9 = $10 + .label _13 = $10 .label m = $c - .label a = 2 .label return = $c - tya + .label a = 2 ldx a + tya + sta mul8u.mb + lda #0 + sta mul8u.mb+1 jsr mul8u lda a cmp #0 bpl b1 lda m+1 - sty $ff + sta _9 + tya + eor #$ff sec - sbc $ff + adc _9 sta m+1 b1: cpy #0 bpl b2 lda m+1 + sta _13 + lda a + eor #$ff sec - sbc a + adc _13 sta m+1 b2: rts @@ -297,9 +307,7 @@ mul8u: { .label mb = 6 .label res = $c .label return = $c - sta mb - lda #0 - sta mb+1 + lda #<0 sta res sta res+1 b1: @@ -331,34 +339,42 @@ mul8u: { mulf8s: { .label return = $e jsr mulf8u_prepare - stx mulf8s_prepared.b + txa + tay jsr mulf8s_prepared rts } // Calculate fast multiply with a prepared unsigned byte to a word result // The prepared number is set by calling mulf8s_prepare(byte a) -// mulf8s_prepared(signed byte zeropage(3) b) +// mulf8s_prepared(signed byte register(Y) b) mulf8s_prepared: { .label memA = $fd + .label _8 = $10 + .label _12 = $10 .label m = $e - .label b = 3 .label return = $e - ldx b + tya + tax jsr mulf8u_prepared lda memA cmp #0 bpl b1 lda m+1 + sta _8 + tya + eor #$ff sec - sbc b + adc _8 sta m+1 b1: - lda b - cmp #0 + cpy #0 bpl b2 lda m+1 + sta _12 + lda memA + eor #$ff sec - sbc memA + adc _12 sta m+1 b2: rts @@ -411,8 +427,8 @@ muls8s: { bmi b6 cmp #1 bmi b5 - lda #0 - tay + ldy #0 + tya sta m sta m+1 b3: @@ -435,13 +451,13 @@ muls8s: { bne b3 rts b5: - lda #0 + lda #<0 sta return sta return+1 rts b6: - lda #0 - tay + ldy #0 + tya sta m sta m+1 b4: @@ -484,6 +500,9 @@ mul8u_compare: { jsr mulf8u ldx a lda b + sta mul8u.mb + lda #0 + sta mul8u.mb+1 jsr mul8u lda ms cmp mf @@ -615,7 +634,7 @@ muls8u: { bne b2 rts b3: - lda #0 + lda #<0 sta return sta return+1 rts @@ -777,7 +796,7 @@ mulf_init: { sta sqr1_lo lda #>mulf_sqr1_lo+1 sta sqr1_lo+1 - lda #0 + lda #<0 sta sqr sta sqr+1 tax diff --git a/src/test/ref/test-scroll-up.asm b/src/test/ref/test-scroll-up.asm index 15c85f776..3f11d2fd0 100644 --- a/src/test/ref/test-scroll-up.asm +++ b/src/test/ref/test-scroll-up.asm @@ -17,7 +17,7 @@ scrollup3: { .label _4 = 7 .label _5 = 9 .label l2_4 = 4 - lda #0 + lda #<0 sta l2 sta l2+1 b1: @@ -111,7 +111,7 @@ scrollup1: { .label line = 2 .label _6 = 7 .label _7 = 4 - lda #0 + lda #<0 sta line sta line+1 b1: diff --git a/src/test/ref/test-signed-word-minus-byte.asm b/src/test/ref/test-signed-word-minus-byte.asm index 7323f8d14..44e686934 100644 --- a/src/test/ref/test-signed-word-minus-byte.asm +++ b/src/test/ref/test-signed-word-minus-byte.asm @@ -22,19 +22,33 @@ main: { lda #>$4d2 sta w1+1 b1: + lda #$5b + sta $fe + ora #$7f + bmi !+ + lda #0 + !: + sta $ff sec lda w1 - sbc #$5b + sbc $fe sta w2 lda w1+1 - sbc #0 + sbc $ff sta w2+1 + lda #$29 + sta $fe + ora #$7f + bmi !+ + lda #0 + !: + sta $ff sec lda w2 - sbc #$29 + sbc $fe sta w1 lda w2+1 - sbc #0 + sbc $ff sta w1+1 lda w1 sta print_sword.w @@ -102,11 +116,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(6) w) print_word: { - lda print_sword.w+1 + .label w = 6 + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts diff --git a/src/test/ref/test-word-size-arrays.asm b/src/test/ref/test-word-size-arrays.asm index 34f29fa59..7a768dfdd 100644 --- a/src/test/ref/test-word-size-arrays.asm +++ b/src/test/ref/test-word-size-arrays.asm @@ -10,7 +10,7 @@ main: { .label _8 = 6 .label _9 = 4 .label _10 = 4 - lda #0 + lda #<0 sta line sta line+1 b1: diff --git a/src/test/ref/true-inline-words.asm b/src/test/ref/true-inline-words.asm index 4dd088582..f8a2b1d7e 100644 --- a/src/test/ref/true-inline-words.asm +++ b/src/test/ref/true-inline-words.asm @@ -8,10 +8,12 @@ main: { .label pos = $501 .label bgcol = $d021 .const w = b*$100 - .const w2 = 1*$100+1+w+0 + .const w2 = 1*$100+1+w + // constant inline words inside expression + .label sc = w2 // implicit cast to (byte*) lda bs+1 - sta w2 + sta sc lda #'m' cmp pos beq b1 diff --git a/src/test/ref/type-inference.asm b/src/test/ref/type-inference.asm new file mode 100644 index 000000000..50476c017 --- /dev/null +++ b/src/test/ref/type-inference.asm @@ -0,0 +1,23 @@ +// Test inference of integer types in expressions +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label b = 2 + lda #0 + sta b + b1: + lax b + axs #-[-$30] + lda b + asl + tay + txa + sta screen,y + inc b + lda #$15 + cmp b + bne b1 + rts +} diff --git a/src/test/ref/type-mix.asm b/src/test/ref/type-mix.asm index 8a32fe08f..f9d20ad6c 100644 --- a/src/test/ref/type-mix.asm +++ b/src/test/ref/type-mix.asm @@ -10,13 +10,20 @@ main: { sta w sta w+1 b1: + lda #$c + sta $fe + ora #$7f + bmi !+ + lda #0 + !: + sta $ff sec lda w - sbc #$c + sbc $fe sta w - bcs !+ - dec w+1 - !: + lda w+1 + sbc $ff + sta w+1 lda w sta SCREEN,x inx diff --git a/src/test/ref/typeid-plus-bytes.asm b/src/test/ref/typeid-plus-bytes.asm index 3678d2e5c..5bd605bdd 100644 --- a/src/test/ref/typeid-plus-bytes.asm +++ b/src/test/ref/typeid-plus-bytes.asm @@ -5,36 +5,125 @@ .const TYPEID_BYTE = 1 .const TYPEID_SIGNED_BYTE = 2 .label SCREEN = $400 + .label SSCREEN = $400 main: { jsr testUnsigned + jsr testUnsignedVals jsr testSigned + jsr testSignedVals + rts +} +testSignedVals: { + .const sbc1 = -$78 + .label sbv1 = 5 + lda #-$78 + sta sbv1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28 + lda #sbc1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1 + lda sbv1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1 + lda #-$46+-$32 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1 + lda #sbc1+-$78 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1 + lda #-$78+sbc1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1 + lda #-$78 + clc + adc sbv1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1 + lda #-$78 + clc + adc sbv1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1 + lda #sbc1 + clc + adc sbv1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1 + lda #sbc1 + clc + adc sbv1 + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1 + lda sbv1 + asl + sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1 rts } testSigned: { - .label sbv1 = 3 - lda #$13 + .label sbv1 = 4 + lda #-$78 sta sbv1 + lda #0 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28 lda #TYPEID_SIGNED_BYTE - sta SCREEN+$28 - sta SCREEN+$29 - sta SCREEN+$2a - sta SCREEN+$2b - sta SCREEN+$2c - sta SCREEN+$2d - sta SCREEN+$2e - sta SCREEN+$2f + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1 + lda #0 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1 + lda #TYPEID_SIGNED_BYTE + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1 + rts +} +testUnsignedVals: { + .const ubc1 = $fa + .label ubv1 = 3 + lda #$fa + sta ubv1 + sta SCREEN+$b+$28 + lda #ubc1 + sta SCREEN+$b+$28+1 + lda ubv1 + sta SCREEN+$b+$28+1+1 + lda #$78+$82 + sta SCREEN+$b+$28+1+1+1 + lda #ubc1+$fa + sta SCREEN+$b+$28+1+1+1+1 + lda #$fa+ubc1 + sta SCREEN+$b+$28+1+1+1+1+1 + lax ubv1 + axs #-[$fa] + stx SCREEN+$b+$28+1+1+1+1+1+1 + lax ubv1 + axs #-[$fa] + stx SCREEN+$b+$28+1+1+1+1+1+1+1 + lda #ubc1 + clc + adc ubv1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1 + lda #ubc1 + clc + adc ubv1 + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1 + lda ubv1 + asl + sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1 rts } testUnsigned: { .label ubv1 = 2 - lda #$5b + lda #$fa sta ubv1 - lda #TYPEID_BYTE + lda #0 sta SCREEN + lda #TYPEID_BYTE sta SCREEN+1 sta SCREEN+2 + lda #0 sta SCREEN+3 + lda #TYPEID_BYTE sta SCREEN+4 sta SCREEN+5 + sta SCREEN+6 + sta SCREEN+7 + sta SCREEN+8 + sta SCREEN+9 + sta SCREEN+$a rts } diff --git a/src/test/ref/uninitialized.asm b/src/test/ref/uninitialized.asm index dd22c0239..24dc22e36 100644 --- a/src/test/ref/uninitialized.asm +++ b/src/test/ref/uninitialized.asm @@ -3,19 +3,14 @@ :BasicUpstart(main) .pc = $80d "Program" .const b = 0 - .const w = 0 - .label ptr = 0 .label SCREEN = $400 main: { lda #b sta SCREEN - lda #w sta SCREEN+3 - lda #ptr sta SCREEN+5 rts } diff --git a/src/test/ref/valuelist-error.asm b/src/test/ref/valuelist-error.asm new file mode 100644 index 000000000..eb9744a46 --- /dev/null +++ b/src/test/ref/valuelist-error.asm @@ -0,0 +1,10 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = -1*$100+-1 + lda #