diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 5d159bcbf..35557b8ed 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -22,7 +22,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge is DirectMemoryRead -> translateDirectMemReadExpression(expression, true) is NumericLiteralValue -> translateExpression(expression) is IdentifierReference -> translateExpression(expression) - is FunctionCall -> translateExpression(expression) + is FunctionCall -> translateFunctionCallResultOntoStack(expression) is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array literal value assignment - should have been replaced by a variable") is RangeExpr -> throw AssemblyError("range expression should have been changed into array values") } @@ -942,7 +942,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } - private fun translateExpression(expression: FunctionCall) { + private fun translateFunctionCallResultOntoStack(expression: FunctionCall) { val functionName = expression.target.nameInSource.last() val builtinFunc = BuiltinFunctions[functionName] if (builtinFunc != null) { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index 9dd64d183..88c381efc 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -125,14 +125,18 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen is TypecastExpression -> assignTypeCastedValue(assign.target, value.type, value.expression, assign) is FunctionCall -> { if(value.target.targetSubroutine(program.namespace)?.isAsmSubroutine==true) { - // TODO handle asmsub functioncalls specifically, without shoving stuff on the estack - asmgen.translateExpression(value) - assignStackValue(assign.target) - val sub = value.target.targetSubroutine(program.namespace) - if(sub!=null && sub.asmReturnvaluesRegisters.any { it.statusflag != null }) { - // the expression translation will have generated a 'php' instruction earlier. - asmgen.out(" plp\t; restore status flags from call") + // handle asmsub functioncalls specifically, without shoving stuff on the estack + val sub = value.target.targetSubroutine(program.namespace)!! + val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null } + asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall) + when((sub.asmReturnvaluesRegisters.single { it.registerOrPair!=null }).registerOrPair) { + RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A) + RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X) + RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y) + else -> throw AssemblyError("should be just one register byte result value") } + if(preserveStatusRegisterAfterCall) + asmgen.out(" plp\t; restore status flags from call") } else { // regular subroutine, return values are (for now) always done via the stack... TODO optimize this asmgen.translateExpression(value) diff --git a/examples/test.p8 b/examples/test.p8 index 891937b54..14f7fcd97 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -18,12 +18,13 @@ main { return -; ; TODO make this work as well, with the same warning: -; ubyte status2 = c64.OPEN() ; open 1,8,0,"$" + ; TODO make this work as well, with the same warning: + ubyte status2 = c64.OPEN() ; open 1,8,0,"$" if_cs return - + txt.print_ub(status) + txt.print_ub(status2) txt.print(planet_name) txt.chrout('\n')