1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-09 16:29:34 +00:00

Warn about data not being included in the output

This commit is contained in:
Karol Stasiak 2021-02-24 02:22:38 +01:00
parent 521b73d0d3
commit 4ff6120702
8 changed files with 56 additions and 2 deletions

View File

@ -12,4 +12,28 @@ object MathUtils {
def lcm(a: Int, b: Int): Int =
(a.toLong * b.toLong / gcd(a, b)).toInt
def collapseConsecutiveInts(nums :Seq[Int], format: Int=>String): String = {
val result = Seq.newBuilder[String]
var lastIntervalStart = -2
var lastIntervalEnd = -2
def flushInterval(): Unit = {
if (lastIntervalEnd >= 0) {
if (lastIntervalStart == lastIntervalEnd) {
result += format(lastIntervalEnd)
} else {
result += format(lastIntervalStart) + "-" + format(lastIntervalEnd)
}
}
}
for(n <- nums) {
if (n != lastIntervalEnd + 1) {
flushInterval()
lastIntervalStart = n
}
lastIntervalEnd = n
}
flushInterval()
result.result().mkString(",")
}
}

View File

@ -604,6 +604,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
unimportantLabelMap += "__rwdata_size" -> (ib.index -> size)
for (i <- 0 until size) {
ib.output(ivAddr + i) = db.output(rwDataStart + i)
db.outputted(rwDataStart + i) = true
}
val debugArray = Array.fill[Option[Constant]](size)(None)
bytesToWriteLater ++= bytesToWriteLater.flatMap{
@ -704,6 +705,13 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
val outputPackager = platform.outputPackagers.getOrElse(b, platform.defaultOutputPackager)
b -> outputPackager.packageOutput(mem, b)
}.toMap
for (bank <- mem.banks.keys.toSeq.sorted) {
val missing = mem.banks(bank).initializedNotOutputted
if (missing.nonEmpty) {
val missingFormatted = MathUtils.collapseConsecutiveInts(missing, i => f"$$$i%04x")
log.warn(s"Fragments of segment ${bank} are not contained in any output: $missingFormatted")
}
}
AssemblerOutput(code, assembly.toArray, labelMap.toList, breakpointSet.toList.sorted)
}

View File

@ -56,9 +56,14 @@ class MemoryBank(val index: Int, val isBigEndian: Boolean) {
val initialized: Array[Boolean] = Array.fill(1 << 16)(false)
val readable: Array[Boolean] = Array.fill(1 << 16)(false)
val writeable: Array[Boolean] = Array.fill(1 << 16)(false)
val outputted: Array[Boolean] = Array.fill(1 << 16)(false)
var start: Int = 0
var end: Int = 0
def markAsOutputted(start: Int, pastEnd: Int): Unit = for (i <- start until pastEnd) outputted(i) = true
def initializedNotOutputted: Seq[Int] = (0 until 0x10000).filter(i => initialized(i) && !outputted(i))
def dump(startAddr: Int, count: Int)(dumper: String => Any): Unit = {
(0 until count).map(i => (i + startAddr) -> output(i + startAddr)).grouped(16).zipWithIndex.map { case (c, i) => f"${c.head._1}%04X: " + c.map(i => f"${i._2}%02x").mkString(" ") }.foreach(dumper)
}

View File

@ -58,7 +58,10 @@ object D88Output extends OutputPackager {
val sizeInPages = size.|(0xff).+(1).>>(8)
addSector(bootloader(b.start, sizeInPages))
for (page <- 0 until sizeInPages) {
addSector(b.output.slice(b.start + (page << 8), b.start + (page << 8) + 0x100))
val pageStart = b.start + (page << 8)
val pagePastEnd = pageStart + 0x100
b.markAsOutputted(pageStart, pagePastEnd)
addSector(b.output.slice(pageStart, pagePastEnd))
}
header.totalSize = trackOffset
sectors.map(_.toArray).foldLeft(header.toArray ++ trackList.toArray)(_ ++ _)

View File

@ -29,6 +29,7 @@ case class ConstOutput(byte: Byte) extends OutputPackager {
case class CurrentBankFragmentOutput(start: Int, end: Int) extends OutputPackager {
def packageOutput(mem: CompiledMemory, bank: String): Array[Byte] = {
val b = mem.banks(bank)
b.markAsOutputted(start, end + 1)
b.output.slice(start, end + 1)
}
}
@ -36,6 +37,7 @@ case class CurrentBankFragmentOutput(start: Int, end: Int) extends OutputPackage
case class BankFragmentOutput(alwaysBank: String, start: Int, end: Int) extends OutputPackager {
def packageOutput(mem: CompiledMemory, bank: String): Array[Byte] = {
val b = mem.banks(alwaysBank)
b.markAsOutputted(start, end + 1)
b.output.slice(start, end + 1)
}
}
@ -120,6 +122,7 @@ object PageCountOutput extends OutputPackager {
object AllocatedDataOutput extends OutputPackager {
def packageOutput(mem: CompiledMemory, bank: String): Array[Byte] = {
val b = mem.banks(bank)
b.markAsOutputted(b.start, b.end + 1)
b.output.slice(b.start, b.end + 1)
}
}

View File

@ -13,6 +13,7 @@ class TapOutput(val symbol: String) extends OutputPackager {
val filteredName: String = mem.programName.filter(isAlphanum)
val b = mem.banks(bank)
val code = b.output.slice(b.start, b.end + 1)
b.markAsOutputted(b.start, b.end + 1)
val codeDataBlock = new DataBlock(code)
val codeHeaderBlock = new HeaderBlock(3, "CODE", code.length, b.start, 32768)
val loaderDataBlock = new DataBlock(ZxSpectrumBasic.loader("CODE", filteredName, b.start, mem.getAddress(symbol)))

View File

@ -8,6 +8,7 @@ class TrsCmdOutput(symbol: String) extends OutputPackager {
val b = mem.banks(bank)
val start = b.start
val run = mem.getAddress(symbol)
b.markAsOutputted(start, b.end + 1)
b.output.slice(start, b.end + 1).grouped(256).zipWithIndex.flatMap{ case (chunk, index) =>
// chunk type 1: data
// chunk length: 1 byte, includes the load address, goes 3-258

View File

@ -1,7 +1,7 @@
package millfork.test
import millfork.MathUtils
import millfork.MathUtils.gcd
import millfork.MathUtils.{collapseConsecutiveInts, gcd}
import org.scalatest.{AppendedClues, FunSuite, Matchers}
/**
@ -20,4 +20,13 @@ class MathUtilsSuite extends FunSuite with Matchers with AppendedClues {
gcd(12, 9) should equal(3)
}
test("Collapse consecutive ints") {
collapseConsecutiveInts(Seq(1), _.toString) should equal("1")
collapseConsecutiveInts(Seq(1,2), _.toString) should equal("1-2")
collapseConsecutiveInts(Seq(1,2,3), _.toString) should equal("1-3")
collapseConsecutiveInts(Seq(1,2,3,6), _.toString) should equal("1-3,6")
collapseConsecutiveInts(Seq(1,3,6), _.toString) should equal("1,3,6")
collapseConsecutiveInts(Seq(1,3,4,5,6), _.toString) should equal("1,3-6")
}
}