mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
check that block address leaves room for program startup logic
This commit is contained in:
parent
51279a98b3
commit
d1ddf05e38
@ -1238,11 +1238,10 @@ sub search_x16edit() -> ubyte {
|
|||||||
str @shared signature = petscii:"x16edit"
|
str @shared signature = petscii:"x16edit"
|
||||||
for cx16.r1L in 31 downto 0 {
|
for cx16.r1L in 31 downto 0 {
|
||||||
cx16.rombank(cx16.r1L)
|
cx16.rombank(cx16.r1L)
|
||||||
cx16.r2 = $fff0
|
|
||||||
%asm {{
|
%asm {{
|
||||||
ldy #0
|
ldy #0
|
||||||
- lda signature,y
|
- lda signature,y
|
||||||
cmp (cx16.r2),y
|
cmp $fff0,y
|
||||||
bne +
|
bne +
|
||||||
iny
|
iny
|
||||||
cpy #7
|
cpy #7
|
||||||
|
@ -107,14 +107,14 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
determineProgramLoadAddress(program, compilationOptions, args.errors)
|
||||||
|
args.errors.report()
|
||||||
postprocessAst(program, args.errors, compilationOptions)
|
postprocessAst(program, args.errors, compilationOptions)
|
||||||
|
args.errors.report()
|
||||||
|
|
||||||
// println("*********** COMPILER AST BEFORE ASSEMBLYGEN *************")
|
// println("*********** COMPILER AST BEFORE ASSEMBLYGEN *************")
|
||||||
// printProgram(program)
|
// printProgram(program)
|
||||||
|
|
||||||
determineProgramLoadAddress(program, compilationOptions, args.errors)
|
|
||||||
args.errors.report()
|
|
||||||
|
|
||||||
if (args.writeAssembly) {
|
if (args.writeAssembly) {
|
||||||
|
|
||||||
// re-initialize memory areas with final compilationOptions
|
// re-initialize memory areas with final compilationOptions
|
||||||
|
@ -280,8 +280,13 @@ internal class AstChecker(private val program: Program,
|
|||||||
errors.err("identifiers cannot start with an underscore", block.position)
|
errors.err("identifiers cannot start with an underscore", block.position)
|
||||||
|
|
||||||
val addr = block.address
|
val addr = block.address
|
||||||
if(addr!=null && addr>65535u) {
|
if (addr!=null) {
|
||||||
errors.err("block memory address must be valid integer 0..\$ffff", block.position)
|
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) {
|
for (statement in block.statements) {
|
||||||
|
@ -384,6 +384,32 @@ main {
|
|||||||
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
|
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") {
|
test("for loops with just 1 iteration") {
|
||||||
val src="""
|
val src="""
|
||||||
main {
|
main {
|
||||||
|
@ -1,50 +1,18 @@
|
|||||||
%zeropage basicsafe
|
; EXAMPLE external command source code
|
||||||
|
|
||||||
|
%launcher none
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
%zeropage basicsafe
|
||||||
|
%encoding iso
|
||||||
|
%import textio
|
||||||
|
%address $4000
|
||||||
|
|
||||||
main {
|
|
||||||
sub func() -> ubyte {
|
|
||||||
cx16.r0++
|
|
||||||
return cx16.r0L
|
|
||||||
}
|
|
||||||
|
|
||||||
sub start() {
|
main $4030 {
|
||||||
bool[256] @shared cells
|
%option force_output
|
||||||
word starw
|
|
||||||
byte bb
|
|
||||||
uword uw
|
|
||||||
ubyte ub
|
|
||||||
|
|
||||||
starw = (240-64 as word) + func()
|
sub start() {
|
||||||
|
txt.print("external command\n")
|
||||||
for starw in 50 downto 10 {
|
sys.exit(0)
|
||||||
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++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user