diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index 2534bff38..27ef34b55 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -604,6 +604,45 @@ class AsmGen(private val program: Program, } } + internal fun storeAIntoPointerVar(pointervar: IdentifierReference) { + val sourceName = asmVariableName(pointervar) + val vardecl = pointervar.targetVarDecl(program)!! + val scopedName = vardecl.scopedName.joinToString(".") + if (isTargetCpu(CpuType.CPU65c02)) { + if (isZpVar(scopedName)) { + // pointervar is already in the zero page, no need to copy + out(" sta ($sourceName)") + } else { + out(""" + ldy $sourceName + sty P8ZP_SCRATCH_W2 + ldy $sourceName+1 + sty P8ZP_SCRATCH_W2+1 + sta (P8ZP_SCRATCH_W2)""") + } + } else { + if (isZpVar(scopedName)) { + // pointervar is already in the zero page, no need to copy + out(" ldy #0 | sta ($sourceName),y") + } else { + out(""" + ldy $sourceName + sty P8ZP_SCRATCH_W2 + ldy $sourceName+1 + sty P8ZP_SCRATCH_W2+1 + ldy #0 + sta (P8ZP_SCRATCH_W2),y""") + } + } + } + + internal fun storeAIntoZpPointerVar(zpPointerVar: String) { + if (isTargetCpu(CpuType.CPU65c02)) + out(" sta ($zpPointerVar)") + else + out(" ldy #0 | sta ($zpPointerVar),y") + } + private fun fixNameSymbols(name: String): String { val name2 = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names return name2.replace("prog8_lib.P8ZP_SCRATCH_", "P8ZP_SCRATCH_") // take care of the 'hooks' to the temp vars diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index a90e410c1..1d6c98aef 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -2140,52 +2140,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen when(addressExpr) { is NumericLiteralValue, is IdentifierReference -> { assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - if (asmgen.isTargetCpu(CpuType.CPU65c02)) - asmgen.out(" sta (P8ZP_SCRATCH_W2)") - else - asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") } else -> { // same as above but we need to save the A register asmgen.out(" pha") assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.out(" pla") - if (asmgen.isTargetCpu(CpuType.CPU65c02)) - asmgen.out(" sta (P8ZP_SCRATCH_W2)") - else - asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y") - } - } - } - - fun storeAIntoPointerVar(pointervar: IdentifierReference) { - val sourceName = asmgen.asmVariableName(pointervar) - val vardecl = pointervar.targetVarDecl(program)!! - val scopedName = vardecl.scopedName.joinToString(".") - if (asmgen.isTargetCpu(CpuType.CPU65c02)) { - if (asmgen.isZpVar(scopedName)) { - // pointervar is already in the zero page, no need to copy - asmgen.out(" sta ($sourceName)") - } else { - asmgen.out(""" - ldy $sourceName - sty P8ZP_SCRATCH_W2 - ldy $sourceName+1 - sty P8ZP_SCRATCH_W2+1 - sta (P8ZP_SCRATCH_W2)""") - } - } else { - if (asmgen.isZpVar(scopedName)) { - // pointervar is already in the zero page, no need to copy - asmgen.out(" ldy #0 | sta ($sourceName),y") - } else { - asmgen.out(""" - ldy $sourceName - sty P8ZP_SCRATCH_W2 - ldy $sourceName+1 - sty P8ZP_SCRATCH_W2+1 - ldy #0 - sta (P8ZP_SCRATCH_W2),y""") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") } } } @@ -2195,7 +2157,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen asmgen.out(" sta ${addressLv.number.toHex()}") } addressExpr is IdentifierReference -> { - storeAIntoPointerVar(addressExpr) + asmgen.storeAIntoPointerVar(addressExpr) } addressExpr is BinaryExpression -> { if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true)) diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt index b440dd25d..02865abf8 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -372,9 +372,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, // note: ** (power) operator requires floats. "+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1") "-" -> asmgen.out(" sec | sbc P8ZP_SCRATCH_B1") - "*" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.multiply_bytes | ldy #0") - "/" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | tya | ldy #0") - "%" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | ldy #0") + "*" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.multiply_bytes") + "/" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm | tya") + "%" -> asmgen.out(" ldy P8ZP_SCRATCH_B1 | jsr math.divmod_ub_asm") "<<" -> { asmgen.out(""" ldy P8ZP_SCRATCH_B1 @@ -398,8 +398,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1") else -> throw AssemblyError("invalid operator for in-place modification $operator") } + // TODO THIS IS WRONG:???? val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } private fun inplaceModification_byte_variable_to_pointer(pointervar: IdentifierReference, operator: String, value: IdentifierReference) { @@ -410,9 +411,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, // note: ** (power) operator requires floats. "+" -> asmgen.out(" clc | adc $otherName") "-" -> asmgen.out(" sec | sbc $otherName") - "*" -> asmgen.out(" ldy $otherName | jsr math.multiply_bytes | ldy #0") - "/" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | tya | ldy #0") - "%" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | ldy #0") + "*" -> asmgen.out(" ldy $otherName | jsr math.multiply_bytes") + "/" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm | tya") + "%" -> asmgen.out(" ldy $otherName | jsr math.divmod_ub_asm") "<<" -> { asmgen.out(""" ldy $otherName @@ -436,7 +437,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "^", "xor" -> asmgen.out(" eor $otherName") else -> throw AssemblyError("invalid operator for in-place modification $operator") } - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } private fun inplaceModification_byte_litval_to_pointer(pointervar: IdentifierReference, operator: String, value: Int) { @@ -445,63 +446,63 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "+" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" clc | adc #$value") - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } "-" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" sec | sbc #$value") - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } "*" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) if(value in asmgen.optimizedByteMultiplications) asmgen.out(" jsr math.mul_byte_${value}") else - asmgen.out(" ldy #$value | jsr math.multiply_bytes | ldy #0") - asmgen.out(" sta ($sourceName),y") + asmgen.out(" ldy #$value | jsr math.multiply_bytes") + asmgen.storeAIntoZpPointerVar(sourceName) } "/" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) if(value==0) throw AssemblyError("division by zero") - asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya | ldy #0") - asmgen.out(" sta ($sourceName),y") + asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya") + asmgen.storeAIntoZpPointerVar(sourceName) } "%" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) if(value==0) throw AssemblyError("division by zero") - asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | ldy #0") - asmgen.out(" sta ($sourceName),y") + asmgen.out(" ldy #$value | jsr math.divmod_ub_asm") + asmgen.storeAIntoZpPointerVar(sourceName) } "<<" -> { if (value > 0) { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) - repeat(value) { asmgen.out(" asl a") } - asmgen.out(" sta ($sourceName),y") + repeat(value) { asmgen.out(" asl a") } + asmgen.storeAIntoZpPointerVar(sourceName) } } ">>" -> { if (value > 0) { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) - repeat(value) { asmgen.out(" lsr a") } - asmgen.out(" sta ($sourceName),y") + repeat(value) { asmgen.out(" lsr a") } + asmgen.storeAIntoZpPointerVar(sourceName) } } "&", "and" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" and #$value") - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } "|", "or" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" ora #$value") - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } "^", "xor" -> { val sourceName = asmgen.loadByteFromPointerIntoA(pointervar) asmgen.out(" eor #$value") - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } else -> throw AssemblyError("invalid operator for in-place modification $operator") } @@ -1811,7 +1812,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, beq + lda #1 + eor #1""") - asmgen.out(" sta ($sourceName),y") + asmgen.storeAIntoZpPointerVar(sourceName) } else -> { asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope) @@ -1820,8 +1821,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, lda (P8ZP_SCRATCH_W2),y beq + lda #1 -+ eor #1 - sta (P8ZP_SCRATCH_W2),y""") ++ eor #1""") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") } } } @@ -1942,8 +1943,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, asmgen.out(""" ldy #0 lda (P8ZP_SCRATCH_W2),y - eor #255 - sta (P8ZP_SCRATCH_W2),y""") + eor #255""") + asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2") } } } diff --git a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt index 8d3d21ea9..6f32aa964 100644 --- a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt +++ b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt @@ -73,6 +73,7 @@ X = BinExpr X = LeftExpr // ) } + // TODO breaks imageviewer EHB palette if(binExpr.right.isSimple) { val firstAssign = Assignment(assignment.target.copy(), binExpr.left, binExpr.left.position) val targetExpr = assignment.target.toExpression() diff --git a/docs/source/todo.rst b/docs/source/todo.rst index cf98e7348..c6d80dfa9 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,10 @@ TODO For next compiler release (7.5) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +BUG: imageviewer.p8 iff loader: winterqueen.iff (EHB image) is not displayed correctly! + --> make_ehb_palette() is wrong with optimizations, ok without. + --> caused by splitBinaryExpressions() + ... diff --git a/examples/test.p8 b/examples/test.p8 index 309068578..cc244151a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,15 +3,41 @@ main { + ubyte[64*3] palette + sub start() { - uword scrpos = $0400 - repeat 256 { - @(scrpos) = 81 - scrpos++ + ubyte i + for i in 0 to len(palette)-1 { + palette[i] = 15 } - txt.print_uw(scrpos) + for i in 0 to len(palette)-1 { + txt.print_ubhex(palette[i], false) + } + txt.nl() + make_ehb_palette() + for i in 0 to len(palette)-1 { + txt.print_ubhex(palette[i], false) + } txt.nl() } + + sub make_ehb_palette() { + ; generate 32 additional Extra-Halfbrite colors in the cmap + uword palletteptr = &palette + uword ehbptr = palletteptr + 32*3 + repeat 32 { + @(ehbptr) = @(palletteptr)>>1 + ehbptr++ + palletteptr++ + @(ehbptr) = @(palletteptr)>>1 + ehbptr++ + palletteptr++ + @(ehbptr) = @(palletteptr)>>1 + ehbptr++ + palletteptr++ + } + } + }