diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index 14de30269..6da28dbcd 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -173,7 +173,11 @@ internal class ProgramAndVarsGen( } private fun footer() { - asmgen.out("; bss sections\n .dsection BSS\n .dsection slabs_BSS") + asmgen.out("; bss sections") + asmgen.out("prog8_bss_section_start") + asmgen.out(" .dsection BSS") + asmgen.out("prog8_bss_section_size = * - prog8_bss_section_start") + asmgen.out(" .dsection slabs_BSS") asmgen.out("prog8_program_end\t; end of program label for progend()") } @@ -205,7 +209,9 @@ internal class ProgramAndVarsGen( if (initializers.isNotEmpty()) { asmgen.out("prog8_init_vars\t.block") initializers.forEach { assign -> - asmgen.translate(assign) + if((assign.value as? PtNumber)?.number != 0.0 || allocator.isZpVar(assign.target.identifier!!.name)) + asmgen.translate(assign) + // the other variables that should be set to zero are done so as part of the BSS section. } asmgen.out(" rts\n .bend") } @@ -363,7 +369,21 @@ internal class ProgramAndVarsGen( private fun entrypointInitialization() { asmgen.out("; program startup initialization") - asmgen.out(" cld") + asmgen.out(" cld | tsx | stx prog8_lib.orig_stackpointer ; required for sys.exit()") + // set full BSS area to zero + asmgen.out(""" + .if prog8_bss_section_size>0 + ; reset all variables in BSS section to zero + lda #prog8_bss_section_start + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + ldx #prog8_bss_section_size + lda #0 + jsr prog8_lib.memset + .endif""") + blockVariableInitializers.forEach { if (it.value.isNotEmpty()) asmgen.out(" jsr ${it.key.name}.prog8_init_vars") @@ -414,8 +434,7 @@ internal class ProgramAndVarsGen( arrayVariable2asm(varname, it.alloc.dt, it.value, null) } - asmgen.out("""+ tsx - stx prog8_lib.orig_stackpointer ; required for sys.exit() + asmgen.out("""+ ldx #255 ; init estack ptr clv clc""") diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 86b40731f..2a0a50453 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -890,7 +890,8 @@ sizeof(name) memory(name, size, alignment) Returns the address of the first location of a statically "reserved" block of memory of the given size in bytes, - with the given name. If you specify an alignment value >1, it means the block of memory will + with the given name. The block is uninitialized memory, it is *not* set to zero! + If you specify an alignment value >1, it means the block of memory will be aligned to such a dividable address in memory, for instance an alignment of $100 means the memory block is aligned on a page boundary, and $2 means word aligned (even addresses). Requesting the address of such a named memory block again later with diff --git a/docs/source/todo.rst b/docs/source/todo.rst index ec03f3669..b570348be 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,7 @@ TODO For next minor release ^^^^^^^^^^^^^^^^^^^^^^ -- 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. +- subroutine parameters don't have to be initialized to 0 in prog8_init_vars() - option to put BSS in specific upper memory block ($a000-$bfff, $c000-$cfff on C64) add a .cerror check for overflow! - document bss stuff in the manual diff --git a/examples/test.p8 b/examples/test.p8 index 59ced2ac0..bf6e22760 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,8 +6,8 @@ main { uword b_wordvar - uword b_initwordvar = 12345 ; TODO FIX THIS INIT VALUE FOR noreinit=true - ubyte b_bb =123 ; TODO FIX THIS INIT VALUE FOR noreinit=true + uword b_initwordvar = 12345 + ubyte b_bb =123 float b_fl ubyte[10] b_emptyarray ubyte[10] b_filledarray = [1,2,3,4,5,6,7,8,9,10]