From df1d5421be378f02ea20115be17e4ac725c68686 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Fri, 3 Jan 2020 23:08:54 +0100 Subject: [PATCH] Do not allocate variables on top of fixed-address vairables and arrays (fixes #26) --- src/main/scala/millfork/env/Environment.scala | 7 ++++++ .../millfork/output/AbstractAssembler.scala | 24 +++++++++++++++++++ .../scala/millfork/test/BasicSymonTest.scala | 15 ++++++++++++ 3 files changed, 46 insertions(+) diff --git a/src/main/scala/millfork/env/Environment.scala b/src/main/scala/millfork/env/Environment.scala index f7d2150c..e76bf416 100644 --- a/src/main/scala/millfork/env/Environment.scala +++ b/src/main/scala/millfork/env/Environment.scala @@ -131,8 +131,12 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa Nil case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 1 && options.platform.cpuFamily == CpuFamily.I80 => Nil + case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 1 && options.platform.cpuFamily == CpuFamily.M6809 => + Nil case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 2 && options.platform.cpuFamily == CpuFamily.I80 => Nil + case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 2 && options.platform.cpuFamily == CpuFamily.M6809 => + Nil case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 3 && options.platform.cpuFamily == CpuFamily.I80 => Nil case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 4 && options.platform.cpuFamily == CpuFamily.I80 => @@ -171,6 +175,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa if (forZpOnly || !options.platform.hasZeroPage) { val addr = allocators(bank).allocateBytes(bank0, callGraph, vertex, options, m.sizeInBytes, initialized = false, writeable = true, location = AllocationLocation.Zeropage, alignment = m.alignment) + if (log.traceEnabled) log.trace("addr $" + addr.toHexString) onEachVariable(m.name, bank0.index -> addr) List( ConstantThing(m.name.stripPrefix(prefix) + "`", NumericConstant(addr, 2), p) @@ -187,6 +192,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa allocators(bank).tryAllocateZeropageBytes(bank0, callGraph, vertex, options, m.sizeInBytes, alignment = m.alignment) match { case None => Nil case Some(addr) => + if (log.traceEnabled) log.trace("addr $" + addr.toHexString) onEachVariable(m.name, bank0.index -> addr) List( ConstantThing(m.name.stripPrefix(prefix) + "`", NumericConstant(addr, 2), p) @@ -197,6 +203,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa Nil } else { val addr = allocators(bank).allocateBytes(bank0, callGraph, vertex, options, m.sizeInBytes, initialized = false, writeable = true, location = AllocationLocation.Either, alignment = m.alignment) + if (log.traceEnabled) log.trace("addr $" + addr.toHexString) onEachVariable(m.name, bank0.index -> addr) List( ConstantThing(graveName, NumericConstant(addr, 2), p) diff --git a/src/main/scala/millfork/output/AbstractAssembler.scala b/src/main/scala/millfork/output/AbstractAssembler.scala index e824567f..01725dda 100644 --- a/src/main/scala/millfork/output/AbstractAssembler.scala +++ b/src/main/scala/millfork/output/AbstractAssembler.scala @@ -223,6 +223,30 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program val potentiallyInlineable: Map[String, Int] = inliningResult.potentiallyInlineableFunctions var functionsThatCanBeCalledFromInlinedFunctions: Set[String] = inliningResult.nonInlineableFunctions + for(th <- env.things.values) { + th match { + case tim: VariableInMemory => + tim.toAddress match { + case NumericConstant(n, _) => + val m = mem.banks(tim.bank(options)) + for (i <- 0 until tim.typ.size) { + m.occupied(i + n.toInt) = true + } + case _ => + } + case arr: MfArray => + arr.toAddress match { + case NumericConstant(n, _) => + val m = mem.banks(arr.bank(options)) + for (i <- 0 until arr.sizeInBytes) { + m.occupied(i + n.toInt) = true + } + case _ => + } + case _ => + } + } + env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, 1, forZpOnly = true) env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, 2, forZpOnly = true) env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, 3, forZpOnly = true) diff --git a/src/test/scala/millfork/test/BasicSymonTest.scala b/src/test/scala/millfork/test/BasicSymonTest.scala index e1a45b56..58e79334 100644 --- a/src/test/scala/millfork/test/BasicSymonTest.scala +++ b/src/test/scala/millfork/test/BasicSymonTest.scala @@ -191,6 +191,21 @@ class BasicSymonTest extends FunSuite with Matchers { } } + test("Allocation test 2") { + EmuUnoptimizedCrossPlatformRun(Cpu.Mos)( + """ + | #use ZPREG_SIZE + | array _crap[$100-ZPREG_SIZE] @$00 + | word output @$c000 + | word data + | void main () { + | output = data.addr + | } + """.stripMargin){ m => + m.readWord(0xc000) should be >=(0x100) + } + } + test("Preprocessor test") { EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)( """