diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index 852a31fab..f6a803e98 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -91,6 +91,7 @@ internal class ProgramAndVarsGen( OutputType.RAW -> { asmgen.out("; ---- raw assembler program ----") asmgen.out("* = ${options.loadAddress.toHex()}") + asmgen.out("prog8_program_start\t; start of program label") asmgen.out(" cld") asmgen.out(" tsx ; save stackpointer for sys.exit()") asmgen.out(" stx prog8_lib.orig_stackpointer") @@ -106,6 +107,7 @@ internal class ProgramAndVarsGen( } asmgen.out("; ---- basic program with sys call ----") asmgen.out("* = ${options.loadAddress.toHex()}") + asmgen.out("prog8_program_start\t; start of program label") val year = LocalDate.now().year asmgen.out(" .word (+), $year") asmgen.out(" .null $9e, format(' %d ', prog8_entrypoint), $3a, $8f, ' prog8'") @@ -122,6 +124,7 @@ internal class ProgramAndVarsGen( // this is the same as RAW asmgen.out("; ---- program without basic sys call ----") asmgen.out("* = ${options.loadAddress.toHex()}") + asmgen.out("prog8_program_start\t; start of program label") asmgen.out(" cld") asmgen.out(" tsx ; save stackpointer for sys.exit()") asmgen.out(" stx prog8_lib.orig_stackpointer") @@ -134,6 +137,7 @@ internal class ProgramAndVarsGen( OutputType.XEX -> { asmgen.out("; ---- atari xex program ----") asmgen.out("* = ${options.loadAddress.toHex()}") + asmgen.out("prog8_program_start\t; start of program label") asmgen.out(" cld") asmgen.out(" tsx ; save stackpointer for sys.exit()") asmgen.out(" stx prog8_lib.orig_stackpointer") diff --git a/compiler/res/prog8lib/atari/syslib.p8 b/compiler/res/prog8lib/atari/syslib.p8 index 07e6d638e..433312f87 100644 --- a/compiler/res/prog8lib/atari/syslib.p8 +++ b/compiler/res/prog8lib/atari/syslib.p8 @@ -336,6 +336,13 @@ save_SCRATCH_ZPWORD2 .word 0 }} } + inline asmsub progstart() -> uword @AY { + %asm {{ + lda #prog8_program_start + }} + } + inline asmsub push(ubyte value @A) { %asm {{ pha diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index 6a22bebbc..411cdf6e0 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -887,6 +887,13 @@ _no_msb_size }} } + inline asmsub progstart() -> uword @AY { + %asm {{ + lda #prog8_program_start + }} + } + inline asmsub push(ubyte value @A) { %asm {{ pha diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 385e9c4df..21c6e14a5 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -903,6 +903,13 @@ _no_msb_size }} } + inline asmsub progstart() -> uword @AY { + %asm {{ + lda #prog8_program_start + }} + } + inline asmsub push(ubyte value @A) { %asm {{ pha diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index 3459f2518..5623bef75 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -1822,6 +1822,13 @@ save_SCRATCH_ZPWORD2 .word 0 }} } + inline asmsub progstart() -> uword @AY { + %asm {{ + lda #prog8_program_start + }} + } + inline asmsub push(ubyte value @A) { %asm {{ pha diff --git a/compiler/res/prog8lib/neo/syslib.p8 b/compiler/res/prog8lib/neo/syslib.p8 index 281db83d8..d05807fa3 100644 --- a/compiler/res/prog8lib/neo/syslib.p8 +++ b/compiler/res/prog8lib/neo/syslib.p8 @@ -270,6 +270,13 @@ save_SCRATCH_ZPWORD2 .word 0 }} } + inline asmsub progstart() -> uword @AY { + %asm {{ + lda #prog8_program_start + }} + } + inline asmsub push(ubyte value @A) { %asm {{ pha diff --git a/compiler/res/prog8lib/pet32/syslib.p8 b/compiler/res/prog8lib/pet32/syslib.p8 index dbcd04650..6da0dd4ec 100644 --- a/compiler/res/prog8lib/pet32/syslib.p8 +++ b/compiler/res/prog8lib/pet32/syslib.p8 @@ -435,6 +435,13 @@ save_SCRATCH_ZPWORD2 .word 0 }} } + inline asmsub progstart() -> uword @AY { + %asm {{ + lda #prog8_program_start + }} + } + inline asmsub push(ubyte value @A) { %asm {{ pha diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index f561ccf30..b99ab680a 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -330,6 +330,11 @@ sys (part of syslib) Returns the last address of the program in memory + 1. This means: the memory address directly after all the program code and variables, including the uninitialized ones ("BSS" variables) and the uninitialized memory blocks reserved by the `memory()` function. Can be used to load dynamic data after the program, instead of hardcoding something. + On the assembly level: it returns the address of the symbol "``prog8_program_end``". + +``progstart ()`` + Returns the first address of the program in memory. This usually is $0801 on the C64 and the X16, for example. + On the assembly level: it returns the address of the symbol "``prog8_program_start``". ``wait (uword jiffies)`` wait approximately the given number of jiffies (1/60th seconds) diff --git a/examples/test.p8 b/examples/test.p8 index 6e6ec6451..eebff9d94 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,19 +1,12 @@ -%import math %import textio %option no_sysinit %zeropage basicsafe main { sub start() { - uword v0 = 4000 - uword v1 = 60000 - - for cx16.r1 in 65400 to 65535 { - txt.print_uw(cx16.r1) - txt.spc() - txt.spc() - txt.print_uw(math.lerpw(v0, v1, cx16.r1)) - txt.nl() - } + txt.print_uwhex(sys.progstart(), true) + txt.spc() + txt.print_uwhex(sys.progend(), true) + txt.nl() } }