diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index 0a59c6441..d62586ed0 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -193,7 +193,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir: programAst.processAstBeforeAsmGeneration(errors) errors.handle() - // printAst(programAst) + printAst(programAst) val assembly = CompilationTarget.asmGenerator( programAst, diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index ac6c35745..49736c76c 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -448,7 +448,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } private fun funcMkword(fcall: IFunctionCall, func: FSignature) { - translateFunctionArguments(fcall.args, func) + // trick: push the args in reverse order (msb first, lsb second) this saves some instructions + asmgen.translateExpression(fcall.args[1]) + asmgen.translateExpression(fcall.args[0]) asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta $ESTACK_HI_PLUS1_HEX,x") } diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 6ce5dfe21..8da01a253 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -63,7 +63,7 @@ val BuiltinFunctions = mapOf( "all" to FSignature(true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAll) }, "lsb" to FSignature(true, listOf(FParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x and 255 }}, "msb" to FSignature(true, listOf(FParam("value", setOf(DataType.UWORD, DataType.WORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { x: Int -> x ushr 8 and 255}}, - "mkword" to FSignature(true, listOf(FParam("lsb", setOf(DataType.UBYTE)), FParam("msb", setOf(DataType.UBYTE))), DataType.UWORD, ::builtinMkword), + "mkword" to FSignature(true, listOf(FParam("msb", setOf(DataType.UBYTE)), FParam("lsb", setOf(DataType.UBYTE))), DataType.UWORD, ::builtinMkword), "rnd" to FSignature(true, emptyList(), DataType.UBYTE), "rndw" to FSignature(true, emptyList(), DataType.UWORD), "rndf" to FSignature(true, emptyList(), DataType.FLOAT), @@ -323,9 +323,9 @@ private fun builtinLen(args: List, position: Position, program: Prog private fun builtinMkword(args: List, position: Position, program: Program): NumericLiteralValue { if (args.size != 2) - throw SyntaxError("mkword requires lsb and msb arguments", position) - val constLsb = args[0].constValue(program) ?: throw NotConstArgumentException() - val constMsb = args[1].constValue(program) ?: throw NotConstArgumentException() + throw SyntaxError("mkword requires msb and lsb arguments", position) + val constMsb = args[0].constValue(program) ?: throw NotConstArgumentException() + val constLsb = args[1].constValue(program) ?: throw NotConstArgumentException() val result = (constMsb.number.toInt() shl 8) or constLsb.number.toInt() return NumericLiteralValue(DataType.UWORD, result, position) } diff --git a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt index 38046e555..f3b8e9aab 100644 --- a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt @@ -586,10 +586,10 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() } else if (amount >= 8) { val lsb = TypecastExpression(expr.left, DataType.UBYTE, true, expr.position) if (amount == 8) { - return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(NumericLiteralValue.optimalInteger(0, expr.position), lsb), expr.position) + return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position) } val shifted = BinaryExpression(lsb, "<<", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position) - return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(NumericLiteralValue.optimalInteger(0, expr.position), shifted), expr.position) + return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(shifted, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position) } } else -> { diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 8133da761..28982614e 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -748,8 +748,9 @@ msb(x) sgn(x) Get the sign of the value. Result is -1, 0 or 1 (negative, zero, positive). -mkword(lsb, msb) - Efficiently create a word value from two bytes (the lsb and the msb). Avoids multiplication and shifting. +mkword(msb, lsb) + Efficiently create a word value from two bytes (the msb and the lsb). Avoids multiplication and shifting. + So mkword($80, $22) results in $8022. any(x) 1 ('true') if any of the values in the array value x is 'true' (not zero), else 0 ('false') diff --git a/examples/cube3d-sprites.p8 b/examples/cube3d-sprites.p8 index 1bf101898..ab9d0c9d4 100644 --- a/examples/cube3d-sprites.p8 +++ b/examples/cube3d-sprites.p8 @@ -159,7 +159,7 @@ main { ubyte sx = rotatedx[i] / persp + width/2 as ubyte + 20 ubyte sy = rotatedy[i] / persp + height/2 as ubyte + 40 - c64.SPXYW[i] = mkword(sx, sy) + c64.SPXYW[i] = mkword(sy, sx) if(zc < 30*128) c64.SPRPTR[i] = $2000/64 +1 ; large ball diff --git a/examples/hello.p8 b/examples/hello.p8 index 01b7e5061..60f3c2ef2 100644 --- a/examples/hello.p8 +++ b/examples/hello.p8 @@ -27,7 +27,7 @@ main { c64.CHROUT(bye[char]) - float clock_seconds = ((mkword(c64.TIME_LO, c64.TIME_MID) as float) + (c64.TIME_HI as float)*65536.0) / 60 + float clock_seconds = ((mkword(c64.TIME_MID, c64.TIME_LO) as float) + (c64.TIME_HI as float)*65536.0) / 60 float hours = floor(clock_seconds / 3600) clock_seconds -= hours*3600 float minutes = floor(clock_seconds / 60) diff --git a/examples/test.p8 b/examples/test.p8 index 67d3ca972..f923ae4ae 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,19 +8,14 @@ main { sub start() { ubyte ub - uword uw - word w - byte b - float f + uword uw = $ee44 + ubyte vlsb = $11 + ubyte vmsb = $ff - - ub = 4 | ub | 2 - ub = ub | 2 | 7 - ub = 4 | 2 | ub - - ub = 4 + ub + 2 - ub = ub + 2 + 7 - ub = 4 + 2 + ub + uw = mkword(vmsb, vlsb) ; todo flip the order of the operands , MSB first + c64scr.print_uwhex(uw, 1) + uw = mkword($ee, $22) ; todo flip the order of the operands , MSB first + c64scr.print_uwhex(uw, 1) } } diff --git a/examples/wizzine.p8 b/examples/wizzine.p8 index c6d925b10..e164f8c11 100644 --- a/examples/wizzine.p8 +++ b/examples/wizzine.p8 @@ -47,18 +47,17 @@ irq { ubyte angle sub irq() { - c64.EXTCOL-- angle++ c64.MSIGX=0 ubyte @zp spri for spri in 7 downto 0 { + c64.EXTCOL++ uword @zp x = sin8u(angle*2-spri*16) as uword + 50 ubyte @zp y = cos8u(angle*3-spri*16) / 2 + 70 - c64.SPXYW[spri] = mkword(lsb(x), y) + c64.SPXYW[spri] = mkword(y, lsb(x)) c64.MSIGX <<= 1 if msb(x) c64.MSIGX++ - c64.EXTCOL++ } - c64.EXTCOL-=7 + c64.EXTCOL-=8 } }