Skip to content

Commit

Permalink
check that block address leaves room for program startup logic
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Oct 3, 2024
1 parent 51279a9 commit d1ddf05
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 51 deletions.
3 changes: 1 addition & 2 deletions compiler/res/prog8lib/cx16/syslib.p8
Original file line number Diff line number Diff line change
Expand Up @@ -1238,11 +1238,10 @@ sub search_x16edit() -> ubyte {
str @shared signature = petscii:"x16edit"
for cx16.r1L in 31 downto 0 {
cx16.rombank(cx16.r1L)
cx16.r2 = $fff0
%asm {{
ldy #0
- lda signature,y
cmp (cx16.r2),y
cmp $fff0,y
bne +
iny
cpy #7
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/prog8/compiler/Compiler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
)
}

determineProgramLoadAddress(program, compilationOptions, args.errors)
args.errors.report()
postprocessAst(program, args.errors, compilationOptions)
args.errors.report()

// println("*********** COMPILER AST BEFORE ASSEMBLYGEN *************")
// printProgram(program)

determineProgramLoadAddress(program, compilationOptions, args.errors)
args.errors.report()

if (args.writeAssembly) {

// re-initialize memory areas with final compilationOptions
Expand Down
9 changes: 7 additions & 2 deletions compiler/src/prog8/compiler/astprocessing/AstChecker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,13 @@ internal class AstChecker(private val program: Program,
errors.err("identifiers cannot start with an underscore", block.position)

val addr = block.address
if(addr!=null && addr>65535u) {
errors.err("block memory address must be valid integer 0..\$ffff", block.position)
if (addr!=null) {
if (addr > 65535u)
errors.err("block address must be valid integer 0..\$ffff", block.position)
if(compilerOptions.loadAddress!=0u) {
if (addr < compilerOptions.loadAddress + 20u)
errors.err("block address must be at least program load address + 20 (to allow for startup logic)", block.position)
}
}

for (statement in block.statements) {
Expand Down
26 changes: 26 additions & 0 deletions compiler/test/codegeneration/TestVariousCodeGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,32 @@ main {
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
}

test("block start address must be greater than program load address") {
val src = """
%output raw
%launcher none
%address ${'$'}2000
main $2000 {
sub start() {
sys.clear_carry()
}
}
otherblock ${'$'}2013 {
%option force_output
}
thirdblock ${'$'}2014 {
%option force_output
}"""
val errors = ErrorReporterForTests()
compileText(C64Target(), false, src, writeAssembly = false, errors = errors) shouldBe null
errors.errors.size shouldBe 2
errors.errors[0] shouldContain "6:1: block address must be at least program load address + 20"
errors.errors[1] shouldContain "12:1: block address must be at least program load address + 20"
}

test("for loops with just 1 iteration") {
val src="""
main {
Expand Down
56 changes: 12 additions & 44 deletions examples/test.p8
Original file line number Diff line number Diff line change
@@ -1,50 +1,18 @@
%zeropage basicsafe
%option no_sysinit

main {
sub func() -> ubyte {
cx16.r0++
return cx16.r0L
}
; EXAMPLE external command source code

sub start() {
bool[256] @shared cells
word starw
byte bb
uword uw
ubyte ub

starw = (240-64 as word) + func()
%launcher none
%option no_sysinit
%zeropage basicsafe
%encoding iso
%import textio
%address $4000

for starw in 50 downto 10 {
cx16.r0++
}
for starw in cx16.r0L downto 10 {
cx16.r0++
}

for ub in 0 to len(cells)-1 {
cx16.r0++
}
for ub in cx16.r0L to len(cells)-1 {
cx16.r0++
}
for bb in 50 downto 10 {
cx16.r0++
}
for bb in cx16.r0sL downto 10 {
cx16.r0++
}
main $4030 {
%option force_output

for starw in 500 downto 10 {
cx16.r0++
}
for uw in 50 downto 10 {
cx16.r0++
}
for uw in 500 downto 10 {
cx16.r0++
}
sub start() {
txt.print("external command\n")
sys.exit(0)
}
}

0 comments on commit d1ddf05

Please sign in to comment.