diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index b77b78376..f6c9fd6b7 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -1033,38 +1033,38 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, private fun funcMkword(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) { val reg = resultRegister ?: RegisterOrPair.AY - var needAsave = asmgen.needAsaveForExpr(fcall.args[0]) - if(!needAsave) { + var needAsaveForArg0 = asmgen.needAsaveForExpr(fcall.args[0]) + if(!needAsaveForArg0) { val mr0 = fcall.args[0] as? PtMemoryByte val mr1 = fcall.args[1] as? PtMemoryByte if (mr0 != null) - needAsave = mr0.address !is PtNumber + needAsaveForArg0 = mr0.address !is PtNumber if (mr1 != null) - needAsave = needAsave or (mr1.address !is PtNumber) + needAsaveForArg0 = needAsaveForArg0 or (mr1.address !is PtNumber) } when(reg) { RegisterOrPair.AX -> { asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A) // lsb - if(needAsave) + if(needAsaveForArg0) asmgen.out(" pha") asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.X) // msb - if(needAsave) + if(needAsaveForArg0) asmgen.out(" pla") } RegisterOrPair.AY -> { asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A) // lsb - if(needAsave) + if(needAsaveForArg0) asmgen.out(" pha") asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.Y) // msb - if(needAsave) + if(needAsaveForArg0) asmgen.out(" pla") } RegisterOrPair.XY -> { asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.A) // lsb - if(needAsave) + if(needAsaveForArg0) asmgen.out(" pha") asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.Y) // msb - if(needAsave) + if(needAsaveForArg0) asmgen.out(" pla") asmgen.out(" tax") } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt index 8d28165f0..b0c820ca0 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt @@ -159,12 +159,22 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as 2 -> { if(params[0].type.isByteOrBool && params[1].type.isByteOrBool) { // 2 byte params, second in Y, first in A - argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A) - if(asmgen.needAsaveForExpr(args[1])) - asmgen.out(" pha") - argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y) - if(asmgen.needAsaveForExpr(args[1])) - asmgen.out(" pla") + if(asmgen.needAsaveForExpr(args[0]) && !asmgen.needAsaveForExpr(args[1])) { + // first 0 then 1 + argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A) + argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y) + } else if(!asmgen.needAsaveForExpr(args[0]) && asmgen.needAsaveForExpr(args[1])) { + // first 1 then 0 + argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y) + argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A) + } else { + argumentViaRegister(sub, IndexedValue(0, params[0]), args[0], RegisterOrPair.A) + if (asmgen.needAsaveForExpr(args[1])) + asmgen.out(" pha") + argumentViaRegister(sub, IndexedValue(1, params[1]), args[1], RegisterOrPair.Y) + if (asmgen.needAsaveForExpr(args[1])) + asmgen.out(" pla") + } } else { throw AssemblyError("cannot use registers for word+byte") } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 29631b116..61722db11 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -3695,7 +3695,9 @@ $endLabel""") RegisterOrPair.XY -> asmgen.out(" ldx #0 | ldy #0") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") in Cx16VirtualRegisters -> { - asmgen.out(" stz cx16.${target.register.toString().lowercase()} | stz cx16.${target.register.toString().lowercase()}+1") + asmgen.out(" stz cx16.${target.register.toString().lowercase()}") + if(target.datatype.isWord) + asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1") } else -> throw AssemblyError("weird register") } @@ -3734,10 +3736,12 @@ $endLabel""") RegisterOrPair.FAC1, RegisterOrPair.FAC2 -> throw AssemblyError("expected typecasted byte to float") in Cx16VirtualRegisters -> { asmgen.out(" lda #${byte.toHex()} | sta cx16.${target.register.toString().lowercase()}") - if(asmgen.isTargetCpu(CpuType.CPU65c02)) - asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1\n") - else - asmgen.out(" lda #0 | sta cx16.${target.register.toString().lowercase()}+1\n") + if(target.datatype.isWord) { + if (asmgen.isTargetCpu(CpuType.CPU65c02)) + asmgen.out(" stz cx16.${target.register.toString().lowercase()}+1\n") + else + asmgen.out(" lda #0 | sta cx16.${target.register.toString().lowercase()}+1\n") + } } else -> throw AssemblyError("weird register") } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e351f7a52..1e846412a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,9 @@ TODO ==== +return mkword(attrs[cx16.r2L], object[cx16.r2L]) same as the explode() above; push pops unneeded? + + - add paypal donation button as well? - announce prog8 on the 6502.org site? @@ -83,8 +86,6 @@ Optimizations - word offset = (row as uword) * 128 + col*2 inefficient code for col*2 (rockrunner) - if magicwall_enabled and (jiffy_counter & 3 == 1) sounds.magicwall() -> generates shortcut jump to another jump, why not immediately after the if -- explode(x, y+1) pushes x on the stack and pops it, could simply load it in reverse order and not use the stack.normal -- return mkword(attrs[cx16.r2L], object[cx16.r2L]) same as the explode() above - if cx16.r0L>=97 and cx16.r0L<=122 {...} -> treats the boolean condition as a byte 0/1 result , can't it somehow just act on the carry bit alone? same with if x1!=x2 or y1!=y2..... but it's because of the way boolean expressions are handled... can this be optimized? diff --git a/examples/test.p8 b/examples/test.p8 index 03377c5bd..09d5aa8bf 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,31 +3,18 @@ %zeropage basicsafe main { + ubyte[4] attrs + ubyte[4] object + sub start() { - ubyte @shared bb0, bb1, bb2, bb3, bb4 - uword @shared ww0, ww1, ww2, ww3, ww4 + cx16.r0 = mkword(attrs[cx16.r2L], object[cx16.r2L]) + cx16.r1 = mkword(attrs[cx16.r2L], 22) + cx16.r2 = mkword(22,attrs[cx16.r2L]) + explode(1, attrs[2]+2) + explode(attrs[2]+2, 1) + } - bb4 = 100 - ww4 = 100 - - bb0 = min(bb1+10, 100) - bb0 = min(100, bb1+10) -; bb0 = min(bb1, bb4) -; bb2 = min(bb1+bb2, bb3+bb4) -; -; bb0 = max(bb1, 100) -; bb0 = max(100, bb1) -; bb0 = max(bb1, bb4) -; bb2 = max(bb1+bb2, bb3+bb4) -; -; ww0 = min(ww1, 100) -; ww0 = min(100, ww1) -; ww0 = min(ww1, ww4) -; ww2 = min(ww1+ww2, ww3+ww4) -; -; ww0 = max(ww1, 100) -; ww0 = max(100, ww1) -; ww0 = max(ww1, ww4) -; ww2 = max(ww1+ww2, ww3+ww4) + sub explode(ubyte a1, ubyte a2) -> uword { + return mkword(attrs[cx16.r2L], object[cx16.r2L]) } }