Skip to content

Commit

Permalink
Make all constants referring to segments match their equivalents from…
Browse files Browse the repository at this point in the history
… the platform definition (see #87)
  • Loading branch information
KarolS committed Jan 13, 2021
1 parent 499e650 commit c1959b3
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 10 deletions.
6 changes: 6 additions & 0 deletions docs/lang/predefined_constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@

* `pointer segment.N.start` – the value of `segment_N_start` from the platform definition

* `pointer segment.N.codeend` – the value of `segment_N_codeend` from the platform definition

* `pointer segment.N.datastart` – the value of `segment_N_datastart` from the platform definition

* `pointer segment.N.end` – the value of `segment_N_end` from the platform definition

* `pointer segment.N.heapstart` – the address of the first byte in the `N` segment that was not automatically allocated

* `word segment.N.length` – the number of byte locations between `segment_N_start` and `segment_N_end`, inclusive

* `byte segment.N.bank` – the value of `segment_N_bank` from the platform definition

* `byte segment.N.fill` – the value of `segment_N_fill` from the platform definition
6 changes: 6 additions & 0 deletions docs/lang/suffixes.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ These suffixes can be applied to variables, arrays, or functions:

* `.segment.start` – returns the start address of the segment the object is in

* `.segment.codeend` – returns the last address of code in the segment the object is in

* `.segment.datastart` – returns the start address of data in the segment the object is in

* `.segment.heapstart` – returns the start address of uninitialized data in the segment the object is in

* `.segment.end` – returns the last address of the segment the object is in

* `.segment.fill` – returns the byte value used to fill gaps and other unused space in the segment the object is in
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/millfork/env/Environment.scala
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
}
for(segment <- options.platform.bankNumbers.keys) {
addUnexpandedPointerConstant(s"segment.$segment.start")
addUnexpandedPointerConstant(s"segment.$segment.codeend")
addUnexpandedPointerConstant(s"segment.$segment.datastart")
addUnexpandedPointerConstant(s"segment.$segment.heapstart")
addUnexpandedPointerConstant(s"segment.$segment.end")
addUnexpandedWordConstant(s"segment.$segment.length")
Expand Down Expand Up @@ -1443,6 +1445,8 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
addThing(ConstantThing(thing.name + ".segment.fill", NumericConstant(bankFill, 1), b), position)
}
addThing(ConstantThing(thing.name + ".segment.start", UnexpandedConstant(s"segment.$segment.start", 2), ptr), position)
addThing(ConstantThing(thing.name + ".segment.codeend", UnexpandedConstant(s"segment.$segment.codeend", 2), ptr), position)
addThing(ConstantThing(thing.name + ".segment.datastart", UnexpandedConstant(s"segment.$segment.datastart", 2), ptr), position)
addThing(ConstantThing(thing.name + ".segment.heapstart", UnexpandedConstant(s"segment.$segment.heapstart", 2), ptr), position)
addThing(ConstantThing(thing.name + ".segment.end", UnexpandedConstant(s"segment.$segment.end", 2), ptr), position)
addThing(ConstantThing(thing.name + ".segment.length", UnexpandedConstant(s"segment.$segment.length", 2), w), position)
Expand Down
13 changes: 8 additions & 5 deletions src/main/scala/millfork/output/AbstractAssembler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,14 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
unimportantLabelMap += "__rwdata_end" -> (defaultBank -> rwDataEnd)
unimportantLabelMap += "__heap_start" -> (defaultBank -> variableAllocators("default").heapStart)
for (segment <- platform.bankNumbers.keys) {
val allocator = options.platform.variableAllocators(segment)
unimportantLabelMap += s"segment.$segment.start" -> (defaultBank -> allocator.startAt)
unimportantLabelMap += s"segment.$segment.end" -> (defaultBank -> (allocator.endBefore - 1))
unimportantLabelMap += s"segment.$segment.heapstart" -> (defaultBank -> allocator.heapStart)
unimportantLabelMap += s"segment.$segment.length" -> (defaultBank -> (allocator.endBefore - allocator.startAt))
val variableAllocator = options.platform.variableAllocators(segment)
val codeAllocator = options.platform.codeAllocators(segment)
unimportantLabelMap += s"segment.$segment.start" -> (defaultBank -> codeAllocator.startAt)
unimportantLabelMap += s"segment.$segment.codeend" -> (defaultBank -> (codeAllocator.endBefore - 1))
unimportantLabelMap += s"segment.$segment.datastart" -> (defaultBank -> variableAllocator.startAt)
unimportantLabelMap += s"segment.$segment.heapstart" -> (defaultBank -> variableAllocator.heapStart)
unimportantLabelMap += s"segment.$segment.end" -> (defaultBank -> (variableAllocator.endBefore - 1))
unimportantLabelMap += s"segment.$segment.length" -> (defaultBank -> (variableAllocator.endBefore - codeAllocator.startAt))
unimportantLabelMap += s"segment.$segment.bank" -> (defaultBank -> platform.bankNumbers(segment))
unimportantLabelMap += s"segment.$segment.fill" -> (defaultBank -> platform.bankFill(segment))
}
Expand Down
15 changes: 10 additions & 5 deletions src/main/scala/millfork/output/VariableAllocator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,23 @@ class VariableAllocator(zpBytes: List[Int], private val bytes: ByteAllocator) {
case AllocationLocation.High =>
val a = bytes.findFreeBytes(mem, count, options, alignment)
if (a < 0) {
options.log.fatal("Out of high memory")
options.log.fatal("Out of high memory in bank ${mem.index}")
}
a
case AllocationLocation.Either =>
var a = zeropage.findFreeBytes(mem, count, options, alignment)
if (a < 0) {
a = bytes.findFreeBytes(mem, count, options, alignment)
if (a < 0) {
options.log.fatal("Out of high memory")
options.log.fatal("Out of high memory in bank ${mem.index}")
}
}
a
}
} else {
val a = bytes.findFreeBytes(mem, count, options, alignment)
if (a < 0) {
options.log.fatal("Out of high memory")
options.log.fatal(s"Out of high memory in bank ${mem.index}")
}
a
}
Expand All @@ -188,8 +188,13 @@ class VariableAllocator(zpBytes: List[Int], private val bytes: ByteAllocator) {

//TODO: Everything about the three methods below is ugly and wrong. Fix later.

def notifyAboutEndOfCode(org: Int): Unit = bytes.notifyAboutEndOfCode(org)
def notifyAboutEndOfData(org: Int): Unit = heapStart = heapStart max org
def notifyAboutEndOfCode(org: Int): Unit = {
heapStart = heapStart max org
bytes.notifyAboutEndOfCode(org)
}
def notifyAboutEndOfData(org: Int): Unit = {
heapStart = heapStart max org
}

def notifyAboutHole(mem: MemoryBank, addr: Int, size: Int): Unit = {
if (Math.abs(addr - heapStart) <= 1) {
Expand Down
9 changes: 9 additions & 0 deletions src/test/scala/millfork/test/SegmentSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class SegmentSuite extends FunSuite with Matchers {
| byte output @$c000
| volatile byte output2 @$c001
| volatile byte output3 @$c002
| volatile pointer output4 @$c006
| volatile pointer output5 @$c008
| volatile pointer output6 @$c00a
| void main() {
| output = 0
| if a1.addr.hi & $e0 == $80 { output += 1 }
Expand All @@ -31,11 +34,17 @@ class SegmentSuite extends FunSuite with Matchers {
| output2 = a1.segment.bank ^ main.segment.bank
| output2 ^= segment.second.bank ^ segment.default.bank
| output3 = lo(main.segment.start)
| output4 = segment.default.start
| output5 = segment.default.datastart
| output6 = segment.default.heapstart
| }
""".stripMargin
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(source) { m =>
m.readByte(0xc000) should equal(source.count(_ == '+'))
m.readByte(0xc001) should equal(0)
m.readWord(0xc006) should equal(0x200)
m.readWord(0xc008) should be >(0x200)
m.readWord(0xc00a) should be >(0x200)
}
}
}

0 comments on commit c1959b3

Please sign in to comment.