diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt index 2f0ce3c6f..31f7dbd2c 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt @@ -279,8 +279,8 @@ $endLabel inx""") sta $loopLabel+1 sty $loopLabel+2 $loopLabel lda ${65535.toHex()} ; modified - beq $endLabel""") - asmgen.out(" sta ${asmgen.asmIdentifierName(stmt.loopVar)}") + beq $endLabel + sta ${asmgen.asmIdentifierName(stmt.loopVar)}""") asmgen.translate(stmt.body) asmgen.out(""" inc $loopLabel+1 @@ -290,60 +290,64 @@ $loopLabel lda ${65535.toHex()} ; modified $endLabel""") } DataType.ARRAY_UB, DataType.ARRAY_B -> { - // TODO: optimize loop code when the length of the array is 255 or less instead of 256 val length = decl.arraysize!!.size()!! - val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if len >= 16 - val modifiedLabel = asmgen.makeLabel("for_modified") + val indexVar = asmgen.makeLabel("for_index") // TODO allocate dynamically, zero page preferred if length >= 16 asmgen.out(""" - lda #<$iterableName - ldy #>$iterableName - sta $modifiedLabel+1 - sty $modifiedLabel+2 ldy #0 -$loopLabel sty $counterLabel -$modifiedLabel lda ${65535.toHex()},y ; modified""") - asmgen.out(" sta ${asmgen.asmIdentifierName(stmt.loopVar)}") +$loopLabel sty $indexVar + lda $iterableName,y + sta ${asmgen.asmIdentifierName(stmt.loopVar)}""") asmgen.translate(stmt.body) + if(length<=255) { + asmgen.out(""" + ldy $indexVar + iny + cpy #$length + beq $endLabel + bne $loopLabel""") + } else { + // length is 256 + asmgen.out(""" + ldy $indexVar + iny + bne $loopLabel + beq $endLabel""") + } asmgen.out(""" - ldy $counterLabel - iny - cpy #${length and 255} - beq $endLabel - bne $loopLabel -$counterLabel .byte 0 +$indexVar .byte 0 $endLabel""") } DataType.ARRAY_W, DataType.ARRAY_UW -> { - // TODO: optimize loop code when the length of the array is 255 or less instead of 256 val length = decl.arraysize!!.size()!! * 2 - val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if len >= 16 - val modifiedLabel = asmgen.makeLabel("for_modified") - val modifiedLabel2 = asmgen.makeLabel("for_modified2") + val indexVar = asmgen.makeLabel("for_index") // todo allocate dynamically, zero page preferred if length >= 16 val loopvarName = asmgen.asmIdentifierName(stmt.loopVar) asmgen.out(""" - lda #<$iterableName - ldy #>$iterableName - sta $modifiedLabel+1 - sty $modifiedLabel+2 - lda #<$iterableName+1 - ldy #>$iterableName+1 - sta $modifiedLabel2+1 - sty $modifiedLabel2+2 ldy #0 -$loopLabel sty $counterLabel -$modifiedLabel lda ${65535.toHex()},y ; modified +$loopLabel sty $indexVar + lda $iterableName,y sta $loopvarName -$modifiedLabel2 lda ${65535.toHex()},y ; modified + lda $iterableName+1,y sta $loopvarName+1""") asmgen.translate(stmt.body) + if(length<=127) { + asmgen.out(""" + ldy $indexVar + iny + iny + cpy #$length + beq $endLabel + bne $loopLabel""") + } else { + // length is 128 words, 256 bytes + asmgen.out(""" + ldy $indexVar + iny + iny + bne $loopLabel + beq $endLabel""") + } asmgen.out(""" - ldy $counterLabel - iny - iny - cpy #${length and 255} - beq $endLabel - bne $loopLabel -$counterLabel .byte 0 +$indexVar .byte 0 $endLabel""") } DataType.ARRAY_F -> { diff --git a/examples/test.p8 b/examples/test.p8 index 08c9043eb..fdbaae2cd 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,51 +6,48 @@ main { sub start() { -; byte[] data = [11,22,33,44,55,66] -; word[] dataw = [1111,2222,3333,4444,5555,6666] -; -; byte d -; word w -; -; for d in data { -; c64scr.print_b(d) -; c64.CHROUT(',') -; } -; c64.CHROUT('\n') -; for w in dataw { -; c64scr.print_w(w) -; c64.CHROUT(',') -; } -; c64.CHROUT('\n') + byte[] data = [11,22,33,44,55,66] + ubyte[256] data256 = 1 + word[] dataw = [1111,2222,3333,4444,5555,6666] + uword[128] dataw128 = 1 + ubyte u + byte d + word w + uword uw - ubyte bb - ubyte from = 10 - ubyte end = 20 - - for bb in from to end step 3 { - c64scr.print_ub(bb) - c64.CHROUT(',') - } - c64.CHROUT('\n') - for bb in end to from step -3 { - c64scr.print_ub(bb) + for u in "hello" { + c64scr.print_ub(u) c64.CHROUT(',') } c64.CHROUT('\n') - word ww - word fromw = -10 - word endw = 21 - - for ww in fromw to endw step 3 { - c64scr.print_w(ww) + for d in data { + c64scr.print_b(d) c64.CHROUT(',') } - c64.CHROUT('\n') - for ww in endw to fromw step -3 { - c64scr.print_w(ww) + + data256[0]=0 + data256[254]=254 + data256[255]=255 + for u in data256 { + c64scr.print_ub(u) + c64.CHROUT(',') + } + c64.CHROUT('\n') + + for w in dataw { + c64scr.print_w(w) + c64.CHROUT(',') + } + c64.CHROUT('\n') + + dataw128[0] = 0 + dataw128[126] =126 + dataw128[127] =127 + for uw in dataw128 { + c64scr.print_uw(uw) c64.CHROUT(',') } c64.CHROUT('\n')