From 0e87db9eb7c40aa5fab29400d9a54aa9ba0d6f3a Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 23 Jan 2022 13:00:01 +0100 Subject: [PATCH] fix invalid size copied when initializing arrays in Zeropage --- .../codegen/target/cpu6502/codegen/AsmGen.kt | 13 +++++----- .../src/prog8/compilerinterface/Zeropage.kt | 4 +-- docs/source/todo.rst | 2 -- examples/test.p8 | 25 ++++++++----------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt index b95259935..edfd66161 100644 --- a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt @@ -124,16 +124,16 @@ class AsmGen(private val program: Program, .sortedBy { options.compTarget.memorySize(it.first.datatype) } // allocate the smallest DT first for ((vardecl, scopedname) in varsRequiringZp) { - val arraySize: Int? = when(vardecl.datatype) { + val numElements: Int? = when(vardecl.datatype) { DataType.STR -> { (vardecl.value as StringLiteralValue).value.length } in ArrayDatatypes -> { - vardecl.arraysize!!.constIndex() // TODO wrong size for non-byte arrays??????? or does datatype get taken into account below + vardecl.arraysize!!.constIndex() } else -> null } - val result = zeropage.allocate(scopedname, vardecl.datatype, arraySize, vardecl.position, errors) + val result = zeropage.allocate(scopedname, vardecl.datatype, numElements, vardecl.position, errors) result.fold( success = { varsInZeropage.add(vardecl) }, failure = { errors.err(it.message!!, vardecl.position) } @@ -1193,7 +1193,8 @@ class AsmGen(private val program: Program, jsr prog8_lib.strcpy""") } arrayVarsInZp.forEach { - val numelements = (it.value as ArrayLiteralValue).value.size // TODO wrong size for word/float arrays!??? + val numelements = (it.value as ArrayLiteralValue).value.size + val size = numelements * program.memsizer.memorySize(ArrayToElementTypes.getValue(it.datatype)) out(""" lda #<${it.name}_init_value ldy #>${it.name}_init_value @@ -1203,8 +1204,8 @@ class AsmGen(private val program: Program, ldy #>${it.name} sta cx16.r1L sty cx16.r1H - lda #<$numelements - ldy #>$numelements + lda #<$size + ldy #>$size jsr sys.memcopy""") } out(" jmp +") diff --git a/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt b/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt index 1d8780faa..f1086486e 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt @@ -40,7 +40,7 @@ abstract class Zeropage(protected val options: CompilationOptions) { return free.windowed(2).any { it[0] == it[1] - 1u } } - fun allocate(name: List, datatype: DataType, arraySize: Int?, position: Position?, errors: IErrorReporter): Result, ZeropageAllocationError> { + fun allocate(name: List, datatype: DataType, numElements: Int?, position: Position?, errors: IErrorReporter): Result, ZeropageAllocationError> { require(name.isEmpty() || !allocations.values.any { it.first==name } ) {"name can't be allocated twice"} if(options.zeropage== ZeropageType.DONTUSE) @@ -50,7 +50,7 @@ abstract class Zeropage(protected val options: CompilationOptions) { when (datatype) { in IntegerDatatypes -> options.compTarget.memorySize(datatype) DataType.STR, in ArrayDatatypes -> { - val memsize = arraySize!! * options.compTarget.memorySize(ArrayToElementTypes.getValue(datatype)) + val memsize = numElements!! * options.compTarget.memorySize(ArrayToElementTypes.getValue(datatype)) if(position!=null) errors.warn("allocating a large value in zeropage; str/array $memsize bytes", position) else diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 1d7178336..623d5dbf1 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- check/fix allocateAllZeropageVariables() for wrong array byte size? -- check/fix entrypointInitialization() for non-byte arrays in ZP, memcopy size wrong? - Fix compiler stack overflow crash: sub sprite_y_for_row(ubyte row) -> word { return (8-row as byte) diff --git a/examples/test.p8 b/examples/test.p8 index 3fb8f7940..408417803 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,21 +1,18 @@ %import textio -%zeropage basicsafe +%import floats main { + ubyte[4] @shared @requirezp arr1 = [1,2,3,4] + uword[2] @shared @requirezp arr2 = [111,222] + float[2] @shared @requirezp arr3 = [1.111, 2.222] sub start() { - word[3] @shared sprites_x ; = sprites.sprites_x - sprites_x = sprites.sprites_x - word[3] @shared sprites_y ; = sprites.sprites_y - sprites_y = sprites.sprites_y - - txt.print_w(sprites.sprites_x[2]) - txt.nl() - txt.print_w(sprites.sprites_y[2]) - txt.nl() - txt.print_w(sprites_x[2]) - txt.nl() - txt.print_w(sprites_y[2]) - txt.nl() + txt.print_ub(arr1[3]) + txt.spc() + txt.print_uw(arr2[1]) + txt.spc() + floats.print_f(arr3[1]) + repeat { + } } }