check that block address leaves room for program startup logic

This commit is contained in:
Irmen de Jong 2024-10-03 21:16:11 +02:00
parent 51279a98b3
commit d1ddf05e38
5 changed files with 49 additions and 51 deletions

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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 {

View File

@ -1,50 +1,18 @@
%zeropage basicsafe
; EXAMPLE external command source code
%launcher none
%option no_sysinit
%zeropage basicsafe
%encoding iso
%import textio
%address $4000
main {
sub func() -> ubyte {
cx16.r0++
return cx16.r0L
}
sub start() {
bool[256] @shared cells
word starw
byte bb
uword uw
ubyte ub
main $4030 {
%option force_output
starw = (240-64 as word) + func()
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++
}
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)
}
}