mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-08 18:37:17 +00:00
Add raw label file format
This commit is contained in:
parent
fc2f0782c5
commit
c9ef5e636b
@ -47,6 +47,8 @@ The extension and the file format are platform-dependent.
|
||||
* `-G sym` – format used by the WLA DX assembler. The extension is `.sym`.
|
||||
|
||||
* `-G fceux` – multi-file format used by the FCEUX emulator. The extension is `.nl`.
|
||||
|
||||
* `-G raw` – Millfork-specific format. The extension is '.labels'. Each row contains bank number, start address, end address (if known), object type, and Millfork-specific object identifier.
|
||||
|
||||
* `-fbreakpoints`, `-fno-breakpoints` –
|
||||
Whether the compiler should use the `breakpoint` macro.
|
||||
|
141
examples/crossplatform/fire.labels
Normal file
141
examples/crossplatform/fire.labels
Normal file
@ -0,0 +1,141 @@
|
||||
00:0000:0000:v:cpu6510_ddr
|
||||
00:0001:0001:v:cpu6510_port
|
||||
00:0043:0044:v:fire$p
|
||||
00:0045:0045:v:fire$noise
|
||||
00:0046:0046:v:fire$column
|
||||
00:0047:0047:v:fire$heat
|
||||
00:0048:0048:v:fire$entropy
|
||||
00:004B:004B:v:fire$row
|
||||
00:004C:004C:v:cls$i
|
||||
00:009E:009E:v:main$i
|
||||
00:00F7:00F7:v:build_reverse_palette$j
|
||||
00:00F8:00F8:v:build_reverse_palette$i
|
||||
00:00F9:00FA:v:rand_seed
|
||||
00:00FB:00FE:v:__reg
|
||||
00:0314:0315:v:irq_pointer
|
||||
00:0315:0315:v:irq_pointer.hi
|
||||
00:0400:07E7:a:screen.array
|
||||
00:0801:080C:A:_basic_loader.array
|
||||
00:080D:083B:F:main
|
||||
00:0824::x:.do__00031
|
||||
00:0832::x:.od__00033
|
||||
00:0838::x:.fp__00037
|
||||
00:083B::x:.ew__00038
|
||||
00:083C:0846:F:wait_frame
|
||||
00:083F::x:.fp__00018
|
||||
00:0846::x:.ew__00019
|
||||
00:0847:08A8:F:fire
|
||||
00:0857::x:.do__00001
|
||||
00:085D::x:.do__00004
|
||||
00:086C::x:.fi__00007
|
||||
00:0886::x:.fi__00008
|
||||
00:0897::x:.od__00006
|
||||
00:08A8::x:.od__00003
|
||||
00:08A9:08F5:F:cls
|
||||
00:08AD::x:.do__00010
|
||||
00:08CF::x:.od__00012
|
||||
00:08D3::x:.do__00013
|
||||
00:08F5::x:.od__00015
|
||||
00:08F6:0928:F:build_reverse_palette
|
||||
00:08FA::x:.do__00020
|
||||
00:0900::x:.wh__00023
|
||||
00:0913::x:.fp__00025
|
||||
00:091F::x:.el__00027
|
||||
00:0921::x:.fi__00028
|
||||
00:0924::x:.ew__00026
|
||||
00:0928::x:.od__00022
|
||||
00:0929:0939:F:rand
|
||||
00:092D::x:__rand_loop
|
||||
00:0934::x:__no_eor
|
||||
00:093A:093E:A:palette.array
|
||||
00:0A00:0AFF:a:reverse_palette.array
|
||||
00:D000:D000:v:vic_spr0_x
|
||||
00:D001:D001:v:vic_spr0_y
|
||||
00:D002:D002:v:vic_spr1_x
|
||||
00:D003:D003:v:vic_spr1_y
|
||||
00:D004:D004:v:vic_spr2_x
|
||||
00:D005:D005:v:vic_spr2_y
|
||||
00:D006:D006:v:vic_spr3_x
|
||||
00:D007:D007:v:vic_spr3_y
|
||||
00:D008:D008:v:vic_spr4_x
|
||||
00:D009:D009:v:vic_spr4_y
|
||||
00:D00A:D00A:v:vic_spr5_x
|
||||
00:D00B:D00B:v:vic_spr5_y
|
||||
00:D00C:D00C:v:vic_spr6_x
|
||||
00:D00D:D00D:v:vic_spr6_y
|
||||
00:D00E:D00E:v:vic_spr7_x
|
||||
00:D00F:D00F:v:vic_spr7_y
|
||||
00:D010:D010:v:vic_spr_hi_x
|
||||
00:D011:D011:v:vic_cr1
|
||||
00:D012:D012:v:vic_raster
|
||||
00:D013:D013:v:vic_lp_x
|
||||
00:D014:D014:v:vic_lp_y
|
||||
00:D015:D015:v:vic_spr_ena
|
||||
00:D016:D016:v:vic_cr2
|
||||
00:D017:D017:v:vic_spr_exp_y
|
||||
00:D018:D018:v:vic_mem
|
||||
00:D019:D019:v:vic_irq
|
||||
00:D01A:D01A:v:vic_irq_ena
|
||||
00:D01B:D01B:v:vic_spr_dp
|
||||
00:D01C:D01C:v:vic_spr_mcolor
|
||||
00:D01D:D01D:v:vic_spr_exp_x
|
||||
00:D01E:D01E:v:vic_spr_ss_col
|
||||
00:D01F:D01F:v:vic_spr_sd_col
|
||||
00:D020:D020:v:vic_border
|
||||
00:D021:D021:v:vic_bg_color0
|
||||
00:D022:D022:v:vic_bg_color1
|
||||
00:D023:D023:v:vic_bg_color2
|
||||
00:D024:D024:v:vic_bg_color3
|
||||
00:D025:D025:v:vic_spr_color1
|
||||
00:D026:D026:v:vic_spr_color2
|
||||
00:D027:D027:v:vic_spr0_color
|
||||
00:D028:D028:v:vic_spr1_color
|
||||
00:D029:D029:v:vic_spr2_color
|
||||
00:D02A:D02A:v:vic_spr3_color
|
||||
00:D02B:D02B:v:vic_spr4_color
|
||||
00:D02C:D02C:v:vic_spr5_color
|
||||
00:D02D:D02D:v:vic_spr6_color
|
||||
00:D02E:D02E:v:vic_spr7_color
|
||||
00:D400:D401:v:sid_v1_freq
|
||||
00:D401:D401:v:sid_v1_freq.hi
|
||||
00:D402:D403:v:sid_v1_pulse
|
||||
00:D403:D403:v:sid_v1_pulse.hi
|
||||
00:D404:D404:v:sid_v1_cr
|
||||
00:D405:D405:v:sid_v1_ad
|
||||
00:D407:D408:v:sid_v2_freq
|
||||
00:D408:D408:v:sid_v2_freq.hi
|
||||
00:D409:D409:v:sid_v1_sr
|
||||
00:D40A:D40A:v:sid_v2_pulse.hi
|
||||
00:D40B:D40B:v:sid_v2_cr
|
||||
00:D40C:D40C:v:sid_v2_ad
|
||||
00:D40D:D40D:v:sid_v2_sr
|
||||
00:D40E:D40F:v:sid_v3_freq
|
||||
00:D40F:D40F:v:sid_v3_freq.hi
|
||||
00:D410:D411:v:sid_v3_pulse
|
||||
00:D411:D411:v:sid_v3_pulse.hi
|
||||
00:D412:D412:v:sid_v3_cr
|
||||
00:D413:D413:v:sid_v3_ad
|
||||
00:D414:D414:v:sid_v3_sr
|
||||
00:D415:D416:v:sid_filt_cutoff
|
||||
00:D416:D416:v:sid_filt_cutoff.hi
|
||||
00:D417:D417:v:sid_filt_cr
|
||||
00:D418:D418:v:sid_filt_mode
|
||||
00:D419:D419:v:sid_paddle_x
|
||||
00:D41A:D41A:v:sid_paddle_y
|
||||
00:D41B:D41B:v:sid_v3_osc_out
|
||||
00:D41C:D41C:v:sid_v3_adsr_out
|
||||
00:D800:DBE7:a:c64_color_ram.array
|
||||
00:DC00:DC00:v:cia1_pra
|
||||
00:DC01:DC01:v:cia1_prb
|
||||
00:DC02:DC02:v:cia1_ddra
|
||||
00:DC03:DC03:v:cia1_ddrb
|
||||
00:DD00:DD00:v:cia2_pra
|
||||
00:DD01:DD01:v:cia2_prb
|
||||
00:DD02:DD02:v:cia2_ddra
|
||||
00:DD03:DD03:v:cia2_ddrb
|
||||
00:FFFA:FFFB:v:nmi_routine_addr
|
||||
00:FFFB:FFFB:v:nmi_routine_addr.hi
|
||||
00:FFFC:FFFD:v:reset_routine_addr
|
||||
00:FFFD:FFFD:v:reset_routine_addr.hi
|
||||
00:FFFE:FFFF:v:irq_routine_addr
|
||||
00:FFFF:FFFF:v:irq_routine_addr.hi
|
@ -6,6 +6,7 @@ package millfork
|
||||
|
||||
object DebugOutputFormat {
|
||||
val map: Map[String, DebugOutputFormat] = Map(
|
||||
"raw" -> RawDebugOutputFormat,
|
||||
"vice" -> ViceDebugOutputFormat,
|
||||
"nesasm" -> NesasmDebugOutputFormat,
|
||||
"fns" -> NesasmDebugOutputFormat,
|
||||
@ -16,7 +17,7 @@ object DebugOutputFormat {
|
||||
|
||||
sealed trait DebugOutputFormat {
|
||||
|
||||
def formatAll(labels: Seq[(String, (Int, Int))], breakpoints: Seq[(Int, Int)]): String = {
|
||||
def formatAll(labels: Seq[(String, Int, Int, Char, Option[Int])], breakpoints: Seq[(Int, Int)]): String = {
|
||||
val labelPart = labelsHeader + labels.map(formatLineTupled).mkString("\n") + "\n"
|
||||
if (breakpoints.isEmpty) {
|
||||
labelPart
|
||||
@ -25,9 +26,10 @@ sealed trait DebugOutputFormat {
|
||||
}
|
||||
}
|
||||
|
||||
final def formatLineTupled(labelAndValue: (String, (Int, Int))): String = formatLine(labelAndValue._1, labelAndValue._2._1, labelAndValue._2._2)
|
||||
final def formatLineTupled(labelAndValue: (String, Int, Int, Char, Option[Int])): String =
|
||||
formatLine(labelAndValue._1, labelAndValue._2, labelAndValue._3, labelAndValue._4, labelAndValue._5)
|
||||
|
||||
def formatLine(label: String, bank: Int, value: Int): String
|
||||
def formatLine(label: String, bank: Int, startValue: Int, category: Char, endValue: Option[Int]): String
|
||||
|
||||
final def formatBreakpointTupled(value: (Int, Int)): Seq[String] = formatBreakpoint(value._1, value._2).toSeq
|
||||
|
||||
@ -45,10 +47,25 @@ sealed trait DebugOutputFormat {
|
||||
def breakpointsHeader: String = ""
|
||||
}
|
||||
|
||||
object RawDebugOutputFormat extends DebugOutputFormat {
|
||||
override def formatLine(label: String, bank: Int, startValue: Int, category: Char, endValue: Option[Int]): String = {
|
||||
f"$bank%02X:$startValue%04X:${endValue.fold("")(_.formatted("%04X"))}%s:$category%s:$label%s"
|
||||
}
|
||||
|
||||
override def fileExtension(bank: Int): String = ".labels"
|
||||
|
||||
override def filePerBank: Boolean = false
|
||||
|
||||
override def addOutputExtension: Boolean = false
|
||||
|
||||
override def formatBreakpoint(bank: Int, value: Int): Option[String] =
|
||||
Some(f"$bank%02X:$value%04X::b:<breakpoint@$value%04X>")
|
||||
}
|
||||
|
||||
object ViceDebugOutputFormat extends DebugOutputFormat {
|
||||
override def formatLine(label: String, bank: Int, value: Int): String = {
|
||||
override def formatLine(label: String, bank: Int, startValue: Int, category: Char, endValue: Option[Int]): String = {
|
||||
val normalized = label.replace('$', '_').replace('.', '_')
|
||||
s"al ${value.toHexString} .$normalized"
|
||||
s"al ${startValue.toHexString} .$normalized"
|
||||
}
|
||||
|
||||
override def fileExtension(bank: Int): String = ".lbl"
|
||||
@ -61,8 +78,8 @@ object ViceDebugOutputFormat extends DebugOutputFormat {
|
||||
}
|
||||
|
||||
object NesasmDebugOutputFormat extends DebugOutputFormat {
|
||||
override def formatLine(label: String, bank: Int, value: Int): String = {
|
||||
label + " = $" + value.toHexString
|
||||
override def formatLine(label: String, bank: Int, startValue: Int, category: Char, endValue: Option[Int]): String = {
|
||||
label + " = $" + startValue.toHexString
|
||||
}
|
||||
|
||||
override def fileExtension(bank: Int): String = ".fns"
|
||||
@ -75,8 +92,8 @@ object NesasmDebugOutputFormat extends DebugOutputFormat {
|
||||
}
|
||||
|
||||
object SymDebugOutputFormat extends DebugOutputFormat {
|
||||
override def formatLine(label: String, bank: Int, value: Int): String = {
|
||||
f"$bank%02x:$value%04x $label%s"
|
||||
override def formatLine(label: String, bank: Int, startValue: Int, category: Char, endValue:Option[Int]): String = {
|
||||
f"$bank%02x:$startValue%04x $label%s"
|
||||
}
|
||||
|
||||
override def fileExtension(bank: Int): String = ".sym"
|
||||
@ -93,8 +110,8 @@ object SymDebugOutputFormat extends DebugOutputFormat {
|
||||
}
|
||||
|
||||
object FceuxDebugOutputFormat extends DebugOutputFormat {
|
||||
override def formatLine(label: String, bank: Int, value: Int): String = {
|
||||
f"$$$value%04x#$label%s#"
|
||||
override def formatLine(label: String, bank: Int, startValue: Int, category: Char, endValue: Option[Int]): String = {
|
||||
f"$$$startValue%04x#$label%s#"
|
||||
}
|
||||
|
||||
override def fileExtension(bank: Int): String = if (bank == 0xff) ".ram.nl" else s".$bank.nl"
|
||||
|
@ -119,14 +119,22 @@ object Main {
|
||||
else if (l.startsWith("__")) 7
|
||||
else 0
|
||||
}
|
||||
val sortedLabels = result.labels.groupBy(_._2).values.map(_.minBy(a => labelUnimportance(a._1) -> a._1)).toSeq.sortBy(_._2)
|
||||
val sortedLabels: Seq[(String, Int, Int, Char, Option[Int])] =
|
||||
result.labels.groupBy(_._2).values
|
||||
.map(_.minBy(a => labelUnimportance(a._1) -> a._1)).toSeq.sortBy(_._2)
|
||||
.map { case (l, (b, s)) =>
|
||||
result.endLabels.get(l) match {
|
||||
case Some((c, e)) => (l, b, s, c, Some(e))
|
||||
case _ => (l, b, s, 'x', None)
|
||||
}
|
||||
}
|
||||
val sortedBreakpoints = result.breakpoints
|
||||
val format = c.outputLabelsFormatOverride.getOrElse(platform.outputLabelsFormat)
|
||||
val basename = if (format.addOutputExtension) output + platform.fileExtension else output
|
||||
if (format.filePerBank) {
|
||||
val banks = sortedLabels.map(_._2._1).toSet ++ sortedBreakpoints.map(_._2).toSet
|
||||
val banks: Set[Int] = sortedLabels.map(_._2).toSet ++ sortedBreakpoints.map(_._1).toSet
|
||||
banks.foreach{ bank =>
|
||||
val labels = sortedLabels.filter(_._2._1.==(bank))
|
||||
val labels = sortedLabels.filter(_._2.==(bank))
|
||||
val breakpoints = sortedBreakpoints.filter(_._1.==(bank))
|
||||
val labelOutput = basename + format.fileExtension(bank)
|
||||
val path = Paths.get(labelOutput)
|
||||
@ -429,7 +437,7 @@ object Main {
|
||||
p.toLowerCase(Locale.ROOT),
|
||||
errorReporting.fatal("Invalid label file format: " + p))
|
||||
c.copy(outputLabels = true, outputLabelsFormatOverride = Some(f))
|
||||
}.description("Generate also the label file in the given format. Available options: vice, nesasm, sym.")
|
||||
}.description("Generate also the label file in the given format. Available options: vice, nesasm, sym, raw.")
|
||||
|
||||
boolean("-fbreakpoints", "-fno-breakpoints").action((c,v) =>
|
||||
c.changeFlag(CompilationFlag.EnableBreakpoints, v)
|
||||
|
@ -118,6 +118,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
allocators: Map[String, VariableAllocator],
|
||||
options: CompilationOptions,
|
||||
onEachVariable: (String, (Int, Int)) => Unit,
|
||||
onEachVariableEnd: (String, (Char, Int)) => Unit,
|
||||
pass: Int,
|
||||
forZpOnly: Boolean): Unit = {
|
||||
if (forZpOnly && !options.platform.hasZeroPage) {
|
||||
@ -184,6 +185,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
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)
|
||||
onEachVariableEnd(m.name, (if (m.isInstanceOf[MfArray])'a' else 'v') -> (addr + m.sizeInBytes - 1))
|
||||
List(
|
||||
ConstantThing(m.name.stripPrefix(prefix) + "`", NumericConstant(addr, 2), p)
|
||||
)
|
||||
@ -207,6 +209,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
case Some(addr) =>
|
||||
if (log.traceEnabled) log.trace("addr $" + addr.toHexString)
|
||||
onEachVariable(m.name, bank0.index -> addr)
|
||||
onEachVariableEnd(m.name, (if (m.isInstanceOf[MfArray])'a' else 'v') -> (addr + m.sizeInBytes - 1))
|
||||
List(
|
||||
ConstantThing(m.name.stripPrefix(prefix) + "`", NumericConstant(addr, 2), p)
|
||||
)
|
||||
@ -218,6 +221,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
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)
|
||||
onEachVariableEnd(m.name, (if (m.isInstanceOf[MfArray])'a' else 'v') -> (addr + m.sizeInBytes - 1))
|
||||
List(
|
||||
ConstantThing(graveName, NumericConstant(addr, 2), p)
|
||||
)
|
||||
@ -225,7 +229,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
}
|
||||
}
|
||||
case f: NormalFunction =>
|
||||
f.environment.allocateVariables(Some(f), mem, callGraph, allocators, options, onEachVariable, pass, forZpOnly)
|
||||
f.environment.allocateVariables(Some(f), mem, callGraph, allocators, options, onEachVariable, onEachVariableEnd, pass, forZpOnly)
|
||||
Nil
|
||||
case _ => Nil
|
||||
}.toList
|
||||
|
@ -19,7 +19,7 @@ import scala.collection.mutable.ArrayBuffer
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
|
||||
case class AssemblerOutput(code: Map[String, Array[Byte]], asm: Array[String], labels: List[(String, (Int, Int))], breakpoints: List[(Int, Int)])
|
||||
case class AssemblerOutput(code: Map[String, Array[Byte]], asm: Array[String], labels: List[(String, (Int, Int))], endLabels: Map[String, (Char, Int)], breakpoints: List[(Int, Int)])
|
||||
|
||||
abstract class AbstractAssembler[T <: AbstractCode](private val program: Program,
|
||||
private val rootEnv: Environment,
|
||||
@ -34,6 +34,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
protected val log: Logger = rootEnv.log
|
||||
|
||||
val labelMap: mutable.Map[String, (Int, Int)] = mutable.Map()
|
||||
val endLabelMap: mutable.Map[String, (Char, Int)] = mutable.Map()
|
||||
val unimportantLabelMap: mutable.Map[String, (Int, Int)] = mutable.Map()
|
||||
val mem = new CompiledMemory(platform.bankNumbers.toList, platform.bankFill, platform.isBigEndian, labelMap, log)
|
||||
val breakpointSet: mutable.Set[(Int, Int)] = mutable.Set()
|
||||
@ -251,6 +252,9 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
m.occupied(i + n.toInt) = true
|
||||
}
|
||||
labelMap.put(tim.name, m.index -> n.toInt)
|
||||
endLabelMap.put(tim.name,
|
||||
(if (tim.isInstanceOf[InitializedMemoryVariable]) 'V' else 'v') ->
|
||||
(n.toInt + tim.typ.size - 1))
|
||||
case _ =>
|
||||
}
|
||||
case arr: MfArray =>
|
||||
@ -261,15 +265,18 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
m.occupied(i + n.toInt) = true
|
||||
}
|
||||
labelMap.put(arr.name, m.index -> n.toInt)
|
||||
endLabelMap.put(arr.name,
|
||||
(if (arr.isInstanceOf[InitializedArray]) 'A' else 'a') ->
|
||||
(n.toInt + arr.sizeInBytes - 1))
|
||||
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)
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, endLabelMap.put, 1, forZpOnly = true)
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, endLabelMap.put, 2, forZpOnly = true)
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, endLabelMap.put, 3, forZpOnly = true)
|
||||
|
||||
var inlinedFunctions = Map[String, List[T]]()
|
||||
val compiledFunctions = mutable.Map[String, CompiledFunction[T]]()
|
||||
@ -396,6 +403,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
case NormalCompiledFunction(_, functionCode, _, _, _) =>
|
||||
labelMap(f.name) = bank0.index -> index
|
||||
val end = outputFunction(bank, functionCode, index, assembly, options)
|
||||
endLabelMap(f.name) = 'F' -> (end - 1)
|
||||
for (i <- index until end) {
|
||||
bank0.occupied(index) = true
|
||||
bank0.initialized(index) = true
|
||||
@ -444,6 +452,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
val bank0 = mem.banks(bank)
|
||||
val index = codeAllocators(bank).allocateBytes(bank0, options, size, initialized = true, writeable = false, location = AllocationLocation.High, alignment = alignment)
|
||||
labelMap(name) = bank0.index -> index
|
||||
endLabelMap(name) = 'F' -> (index + size - 1)
|
||||
justAfterCode += bank -> outputFunction(bank, functionCode, index, assembly, options)
|
||||
case _ =>
|
||||
}
|
||||
@ -529,6 +538,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
val bank0 = mem.banks(bank)
|
||||
var index = codeAllocators(bank).allocateBytes(bank0, options, thing.sizeInBytes, initialized = true, writeable = true, location = AllocationLocation.High, alignment = alignment)
|
||||
labelMap(name) = bank0.index -> index
|
||||
endLabelMap(name) = 'A' -> (index + thing.sizeInBytes - 1)
|
||||
if (!readOnlyPass) {
|
||||
rwDataStart = rwDataStart.min(index)
|
||||
rwDataEnd = rwDataEnd.max(index + thing.sizeInBytes)
|
||||
@ -559,6 +569,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
val bank0 = mem.banks(bank)
|
||||
var index = codeAllocators(bank).allocateBytes(bank0, options, typ.alignedSize, initialized = true, writeable = true, location = AllocationLocation.High, alignment = alignment)
|
||||
labelMap(name) = bank0.index -> index
|
||||
endLabelMap(name) = 'V' -> (index + typ.size - 1)
|
||||
if (!readOnlyPass) {
|
||||
rwDataStart = rwDataStart.min(index)
|
||||
rwDataEnd = rwDataEnd.max(index + typ.alignedSize)
|
||||
@ -632,8 +643,8 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
variableAllocators("default").notifyAboutEndOfData(rwDataEnd)
|
||||
}
|
||||
variableAllocators.foreach { case (b, a) => a.notifyAboutEndOfCode(justAfterCode(b)) }
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, 2, forZpOnly = false)
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, 3, forZpOnly = false)
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, endLabelMap.put, 2, forZpOnly = false)
|
||||
env.allocateVariables(None, mem, callGraph, variableAllocators, options, labelMap.put, endLabelMap.put, 3, forZpOnly = false)
|
||||
|
||||
val defaultBank = mem.banks("default").index
|
||||
if (platform.freeZpBytes.nonEmpty) {
|
||||
@ -695,6 +706,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
val holes = (b.start to b.end).count(i => !b.occupied(i))
|
||||
val size = b.end - b.start + 1
|
||||
log.info(f"Segment ${bank}%s: $$${b.start}%04x-$$${b.end}%04x, size: $size%d B ($holes%d B unused)")
|
||||
// TODO: report holes:
|
||||
}
|
||||
}
|
||||
if (platform.cpuFamily == CpuFamily.M6502) {
|
||||
@ -706,7 +718,12 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
|
||||
val allLabelList = labelMap.toList ++ unimportantLabelMap.toList
|
||||
allLabelList.sorted.foreach { case (l, (_, v)) =>
|
||||
assembly += f"$l%-30s = $$$v%04X"
|
||||
endLabelMap.get(l) match {
|
||||
case Some((category, end)) =>
|
||||
assembly += f"$l%-30s = $$$v%04X ;-$$$end%04X $category%s"
|
||||
case _ =>
|
||||
assembly += f"$l%-30s = $$$v%04X"
|
||||
}
|
||||
}
|
||||
allLabelList.sortBy { case (a, (_, v)) => v -> a }.foreach { case (l, (_, v)) =>
|
||||
assembly += f" ; $$$v%04X = $l%s"
|
||||
@ -729,7 +746,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
}
|
||||
}
|
||||
}
|
||||
AssemblerOutput(code, assembly.toArray, labelMap.toList, breakpointSet.toList.sorted)
|
||||
AssemblerOutput(code, assembly.toArray, labelMap.toList, endLabelMap.toMap, breakpointSet.toList.sorted)
|
||||
}
|
||||
|
||||
private def printArrayToAssemblyOutput(assembly: ArrayBuffer[String], name: String, elementType: Type, items: Seq[Expression]): Unit = {
|
||||
|
@ -154,7 +154,7 @@ class EmuM6809Run(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimizat
|
||||
println(";;; compiled: -----------------")
|
||||
output.asm.takeWhile(s => !(s.startsWith(".") && s.contains("= $"))).filterNot(_.contains("; DISCARD_")).foreach(println)
|
||||
println(";;; ---------------------------")
|
||||
assembler.labelMap.foreach { case (l, (_, addr)) => println(f"$l%-15s $$$addr%04x") }
|
||||
assembler.labelMap.foreach { case (l, (_, addr)) => println(f"$l%-15s $$$addr%04x${assembler.endLabelMap.get(l)match{case Some((c,e)) => f"-$$$e%04x $c%s"; case _ => ""}}%s") }
|
||||
|
||||
val optimizedSize = assembler.mem.banks("default").initialized.count(identity).toLong
|
||||
if (unoptimizedSize == optimizedSize) {
|
||||
|
@ -260,7 +260,7 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
|
||||
println(";;; compiled: -----------------")
|
||||
output.asm.takeWhile(s => !(s.startsWith(".") && s.contains("= $"))).filterNot(_.contains("; DISCARD_")).foreach(println)
|
||||
println(";;; ---------------------------")
|
||||
assembler.labelMap.foreach { case (l, (_, addr)) => println(f"$l%-15s $$$addr%04x") }
|
||||
assembler.labelMap.foreach { case (l, (_, addr)) => println(f"$l%-15s $$$addr%04x${assembler.endLabelMap.get(l)match{case Some((c,e)) => f"-$$$e%04x $c%s"; case _ => ""}}%s") }
|
||||
|
||||
val optimizedSize = assembler.mem.banks("default").initialized.count(identity).toLong
|
||||
if (unoptimizedSize == optimizedSize) {
|
||||
|
@ -155,7 +155,7 @@ class EmuZ80Run(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimizatio
|
||||
println(";;; compiled: -----------------")
|
||||
output.asm.takeWhile(s => !(s.startsWith(".") && s.contains("= $"))).filterNot(_.contains("////; DISCARD_")).foreach(println)
|
||||
println(";;; ---------------------------")
|
||||
assembler.labelMap.foreach { case (l, (_, addr)) => println(f"$l%-15s $$$addr%04x") }
|
||||
assembler.labelMap.foreach { case (l, (_, addr)) => println(f"$l%-15s $$$addr%04x${assembler.endLabelMap.get(l)match{case Some((c,e)) => f"-$$$e%04x $c%s"; case _ => ""}}%s") }
|
||||
|
||||
val optimizedSize = assembler.mem.banks("default").initialized.count(identity).toLong
|
||||
if (unoptimizedSize == optimizedSize) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user