diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 8c1205889..7a21a9e34 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -400,7 +400,7 @@ class AsmGen6502Internal ( } else { return if (allocator.isZpVar((target as PtNamedNode).scopedName)) { // pointervar is already in the zero page, no need to copy - out(" ldy #0 | lda ($sourceName),y") + loadAFromZpPointerVar(sourceName, true) sourceName } else { out(""" @@ -448,18 +448,26 @@ class AsmGen6502Internal ( } } - internal fun storeAIntoZpPointerVar(zpPointerVar: String) { + internal fun storeAIntoZpPointerVar(zpPointerVar: String, keepY: Boolean) { if (isTargetCpu(CpuType.CPU65c02)) out(" sta ($zpPointerVar)") - else - out(" ldy #0 | sta ($zpPointerVar),y") + else { + if(keepY) + out(" sty P8ZP_SCRATCH_REG | ldy #0 | sta ($zpPointerVar),y | ldy P8ZP_SCRATCH_REG") + else + out(" ldy #0 | sta ($zpPointerVar),y") + } } - internal fun loadAFromZpPointerVar(zpPointerVar: String) { + internal fun loadAFromZpPointerVar(zpPointerVar: String, keepY: Boolean) { if (isTargetCpu(CpuType.CPU65c02)) out(" lda ($zpPointerVar)") - else - out(" ldy #0 | lda ($zpPointerVar),y") + else { + if(keepY) + out(" sty P8ZP_SCRATCH_REG | ldy #0 | lda ($zpPointerVar),y | php | ldy P8ZP_SCRATCH_REG | plp") + else + out(" ldy #0 | lda ($zpPointerVar),y") + } } private fun fixNameSymbols(name: String): String { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 73b3c30d3..9039fb424 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -129,7 +129,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, SourceStorageKind.MEMORY -> { fun assignViaExprEval(expression: PtExpression) { assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD) - asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2") + asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false) assignRegisterByte(assign.target, CpuRegister.A, false, true) } @@ -2037,7 +2037,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, fun assignViaExprEval(addressExpression: PtExpression) { asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD) - asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2") + asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false) asmgen.out(" ldy #0") assignRegisterpairWord(target, RegisterOrPair.AY) } @@ -3880,14 +3880,14 @@ internal class AssignmentAsmGen(private val program: PtProgram, when(addressExpr) { is PtNumber, is PtIdentifier -> { assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD) - asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false) } else -> { // same as above but we need to save the A register asmgen.out(" pha") assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD) asmgen.out(" pla") - asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false) } } } @@ -3989,7 +3989,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, lda (P8ZP_SCRATCH_W2),y eor #255""") } - asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false) } } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index 316abf146..d63370121 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -957,7 +957,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, "<", "<=", ">", ">=" -> TODO("byte-var-to-pointer comparisons") else -> throw AssemblyError("invalid operator for in-place modification $operator") } - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } private fun inplacemodificationBytePointerWithLiteralval(pointervar: PtIdentifier, operator: String, value: Int) { @@ -971,7 +971,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } else { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" clc | adc #$value") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } } "-" -> { @@ -982,7 +982,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } else { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" sec | sbc #$value") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } } "*" -> { @@ -991,50 +991,50 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, asmgen.out(" jsr math.mul_byte_${value}") else asmgen.out(" ldy #$value | jsr math.multiply_bytes") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "/" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) if(value==0) throw AssemblyError("division by zero") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "%" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) if(value==0) throw AssemblyError("division by zero") asmgen.out(" ldy #$value | jsr math.divmod_ub_asm") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "<<" -> { if (value > 0) { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) repeat(value) { asmgen.out(" asl a") } - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } } ">>" -> { if (value > 0) { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) repeat(value) { asmgen.out(" lsr a") } - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } } "&" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" and #$value") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "|"-> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" ora #$value") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "^" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" eor #$value") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "==" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) @@ -1045,7 +1045,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, beq ++ + lda #1 +""") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } "!=" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) @@ -1056,7 +1056,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, beq ++ + lda #1 +""") - asmgen.storeAIntoZpPointerVar(sourceName) + asmgen.storeAIntoZpPointerVar(sourceName, false) } // pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?: "<", "<=", ">", ">=" -> TODO("byte-litval-to-pointer comparisons")