diff --git a/examples/c64/multifile.ini b/examples/c64/multifile.ini index 481895e2..29ebfc06 100644 --- a/examples/c64/multifile.ini +++ b/examples/c64/multifile.ini @@ -37,6 +37,7 @@ HAS_BITMAP_MODE=1 ; every segment should land in its own file: style=per_segment format=startaddr,allocated +format_segment_extra=startaddr,allocated,$ea,$ea,$ea,$ea,$ea,$ea,$ea,$ea,$ea,$ea,$ea extension=prg diff --git a/src/main/scala/millfork/Platform.scala b/src/main/scala/millfork/Platform.scala index 045c80bb..459dcc94 100644 --- a/src/main/scala/millfork/Platform.scala +++ b/src/main/scala/millfork/Platform.scala @@ -25,7 +25,8 @@ class Platform( val defaultCodec: TextCodec, val screenCodec: TextCodec, val features: Map[String, Long], - val outputPackager: OutputPackager, + val outputPackagers: Map[String, OutputPackager], + val defaultOutputPackager: OutputPackager, val codeAllocators: Map[String, UpwardByteAllocator], val variableAllocators: Map[String, VariableAllocator], val zpRegisterSize: Int, @@ -247,7 +248,7 @@ object Platform { })) val os = conf.getSection("output") - val outputPackager = SequenceOutput(os.get(classOf[String], "format", "").split("[, \n\t\r]+").filter(_.nonEmpty).map { + def parseOutputPackager(s: String): OutputPackager = SequenceOutput(s.split("[, \n\t\r]+").filter(_.nonEmpty).map { case "startaddr" => StartAddressOutput(0) case "startaddr_be" => StartAddressOutputBe(0) case "startpage" => StartPageOutput @@ -279,6 +280,15 @@ object Platform { case x => log.fatal(s"Invalid output format: `$x`") } }.toList) + val outputPackagers = banks.flatMap{ b => + val f = os.get(classOf[String], "format_segment_" + b, null) + if (f eq null) { + None + } else { + Some(b -> parseOutputPackager(f)) + } + }.toMap + val defaultOutputPackager = parseOutputPackager(os.get(classOf[String], "format", "")) val fileExtension = os.get(classOf[String], "extension", ".bin") val generateBbcMicroInfFile = os.get(classOf[Boolean], "bbc_inf", false) val generateGameBoyChecksums = os.get(classOf[Boolean], "gb_checksum", false) @@ -288,6 +298,9 @@ object Platform { case "lunix" => OutputStyle.LUnix case x => log.fatal(s"Invalid output style: `$x`") } + if (outputStyle != OutputStyle.PerBank && outputPackagers.nonEmpty) { + log.error("Different output formats per segment are allowed only if style=per_segment") + } val debugOutputFormatName = os.get(classOf[String], "labels", "vice") val debugOutputFormat = DebugOutputFormat.map.getOrElse( debugOutputFormatName.toLowerCase(Locale.ROOT), @@ -331,7 +344,8 @@ object Platform { codec, srcCodec, builtInFeatures ++ definedFeatures, - outputPackager, + outputPackagers, + defaultOutputPackager, codeAllocators.toMap, variableAllocators.toMap, zpRegisterSize, diff --git a/src/main/scala/millfork/output/AbstractAssembler.scala b/src/main/scala/millfork/output/AbstractAssembler.scala index 2c51e2bd..c2ad0a1e 100644 --- a/src/main/scala/millfork/output/AbstractAssembler.scala +++ b/src/main/scala/millfork/output/AbstractAssembler.scala @@ -678,7 +678,10 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program val code = (platform.outputStyle match { case OutputStyle.Single | OutputStyle.LUnix => List("default") case OutputStyle.PerBank => platform.bankNumbers.keys.toList - }).map(b => b -> platform.outputPackager.packageOutput(mem, b)).toMap + }).map{b => + val outputPackager = platform.outputPackagers.getOrElse(b, platform.defaultOutputPackager) + b -> outputPackager.packageOutput(mem, b) + }.toMap AssemblerOutput(code, assembly.toArray, labelMap.toList, breakpointSet.toList.sorted) } diff --git a/src/test/scala/millfork/test/emu/EmuPlatform.scala b/src/test/scala/millfork/test/emu/EmuPlatform.scala index 34fdaf6b..29b940c1 100644 --- a/src/test/scala/millfork/test/emu/EmuPlatform.scala +++ b/src/test/scala/millfork/test/emu/EmuPlatform.scala @@ -17,6 +17,7 @@ object EmuPlatform { TextCodec.Ascii, TextCodec.Ascii, Platform.builtInCpuFeatures(cpu), + Map(), CurrentBankFragmentOutput(0, 0xffff), Map( "default" -> (if (cpu == Cpu.Intel8086) new UpwardByteAllocator(0x100, 0xb000) else new UpwardByteAllocator(0x200, 0xb000)),