diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index 155be54d8..dabf23af6 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -162,18 +162,18 @@ internal class ProgramAndVarsGen( } private fun memorySlabs() { - asmgen.out("; memory slabs") + asmgen.out("; memory slabs\n .section slabs_BSS") asmgen.out("prog8_slabs\t.block") for(slab in symboltable.allMemorySlabs) { if(slab.align>1u) asmgen.out("\t.align ${slab.align.toHex()}") asmgen.out("${slab.name}\t.fill ${slab.size}") } - asmgen.out("\t.bend") + asmgen.out("\t.bend\n .send slabs_BSS") } private fun footer() { - // program end + asmgen.out("; bss sections\n .dsection BSS\n .dsection slabs_BSS") asmgen.out("prog8_program_end\t; end of program label for progend()") } @@ -468,20 +468,52 @@ internal class ProgramAndVarsGen( } } - private fun nonZpVariables2asm(variables: List) { + private fun nonZpVariables2asm(variables2: List) { asmgen.out("") - asmgen.out("; non-zeropage variables") - val (stringvars, othervars) = variables.sortedBy { it.name }.partition { it.dt==DataType.STR } - stringvars.forEach { - outputStringvar(it.name, it.onetimeInitializationStringValue!!.second, it.onetimeInitializationStringValue!!.first) + val (varsNoInit, varsWithInit) = variables2.partition { it.uninitialized } + if(varsNoInit.isNotEmpty()) { + asmgen.out("; non-zeropage variables without initialization value") + asmgen.out(" .section BSS") + varsNoInit.sortedWith(compareBy { it.name }.thenBy { it.dt }).forEach { + uninitializedVariable2asm(it) + } + asmgen.out(" .send BSS") } - othervars.sortedBy { it.type }.forEach { - staticVariable2asm(it) + + if(varsWithInit.isNotEmpty()) { + asmgen.out("; non-zeropage variables") + val (stringvars, othervars) = varsWithInit.sortedBy { it.name }.partition { it.dt == DataType.STR } + stringvars.forEach { + outputStringvar( + it.name, + it.onetimeInitializationStringValue!!.second, + it.onetimeInitializationStringValue!!.first + ) + } + othervars.sortedBy { it.type }.forEach { + staticVariable2asm(it) + } + } + } + + private fun uninitializedVariable2asm(variable: StStaticVariable) { + when (variable.dt) { + DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ?") + DataType.BYTE -> asmgen.out("${variable.name}\t.char ?") + DataType.UWORD -> asmgen.out("${variable.name}\t.word ?") + DataType.WORD -> asmgen.out("${variable.name}\t.sint ?") + DataType.FLOAT -> asmgen.out("${variable.name}\t.fill ${compTarget.machine.FLOAT_MEM_SIZE}") + in ArrayDatatypes -> { + val numbytes = compTarget.memorySize(variable.dt, variable.length!!) + asmgen.out("${variable.name}\t.fill $numbytes") + } + else -> { + throw AssemblyError("weird dt") + } } } private fun staticVariable2asm(variable: StStaticVariable) { - val name = variable.name val initialValue: Number = if(variable.onetimeInitializationNumericValue!=null) { if(variable.dt== DataType.FLOAT) @@ -491,22 +523,22 @@ internal class ProgramAndVarsGen( } else 0 when (variable.dt) { - DataType.UBYTE -> asmgen.out("$name\t.byte ${initialValue.toHex()}") - DataType.BYTE -> asmgen.out("$name\t.char $initialValue") - DataType.UWORD -> asmgen.out("$name\t.word ${initialValue.toHex()}") - DataType.WORD -> asmgen.out("$name\t.sint $initialValue") + DataType.UBYTE -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}") + DataType.BYTE -> asmgen.out("${variable.name}\t.char $initialValue") + DataType.UWORD -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}") + DataType.WORD -> asmgen.out("${variable.name}\t.sint $initialValue") DataType.FLOAT -> { if(initialValue==0) { - asmgen.out("$name\t.byte 0,0,0,0,0 ; float") + asmgen.out("${variable.name}\t.byte 0,0,0,0,0 ; float") } else { val floatFill = compTarget.machine.getFloatAsmBytes(initialValue) - asmgen.out("$name\t.byte $floatFill ; float $initialValue") + asmgen.out("${variable.name}\t.byte $floatFill ; float $initialValue") } } DataType.STR -> { throw AssemblyError("all string vars should have been interned into prog") } - in ArrayDatatypes -> arrayVariable2asm(name, variable.dt, variable.onetimeInitializationArrayValue, variable.length) + in ArrayDatatypes -> arrayVariable2asm(variable.name, variable.dt, variable.onetimeInitializationArrayValue, variable.length) else -> { throw AssemblyError("weird dt") } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 170255b6c..82d1c7b13 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,16 +3,10 @@ TODO For next minor release ^^^^^^^^^^^^^^^^^^^^^^ -- BSS. - 64tass can put variables into a section with .section BSS .send BSS - and then putting .dsection BSS where it should output the BSS - Define vars in BSS with .fill rather than .byte otherwise they STILL take up space! - -- BSS in 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with uninitialized=true. - Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE if possible. - Note that 'uninitialized' can still be true for variables that were moved into zeropage, so have to check that! -- BSS subroutine parameters don't have to be set to 0. -- when putting BSS in specific memory block ($a000-$bfff, $c000-$cfff) add a .cerror check for overflow! +- cleanup handling of noreinit +- BSS: initialize BSS block (without slabs!) to zeros on start, using 1 loop instead of all those initialization assignments +- BSS subroutine parameters don't have to be set to 0. But meh, the loop should be super fast anyway. +- allow putting BSS in specific upper memory block ($a000-$bfff, $c000-$cfff on C64) add a .cerror check for overflow! ... diff --git a/examples/test.p8 b/examples/test.p8 index 7b650a7b9..256b10302 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -21,6 +21,8 @@ main { ubyte[10] filledarray = [1,2,3,4,5,6,7,8,9,10] float[3] floatarray uword[3] wordarray + uword slab1 = memory("slab1",400, 0) + uword slab2 = memory("slab2",200, $1000) txt.print("**subroutine scope**\n") txt.print("uninit wordvar=") @@ -103,5 +105,9 @@ main { txt.print_ub(b_filledarray[2]) txt.print("\n\nrun again to see effect of re-init.\n") + txt.print_uwhex(slab1, true) + txt.nl() + txt.print_uwhex(slab2, true) + txt.nl() } }