diff --git a/docs/api/custom-platform.md b/docs/api/custom-platform.md index 5f1ecad8..f41e1b8a 100644 --- a/docs/api/custom-platform.md +++ b/docs/api/custom-platform.md @@ -238,9 +238,13 @@ Default: `main,*` * `d88` - a D88 floppy disk image for PC-88 - * `tap` - a tape disk image for ZX Spectrum + * `tap:XXXX` - a tape image for ZX Spectrum; XXXX is the name of the entry point to the program - * `trscmd` - a chunked loadable executable for TRS-80 Model 1 or 3 running TRS-DOS, also known as the /CMD format + * `tap` – equivalent to `tap:main` + + * `trscmd:XXXX` - a chunked loadable executable for TRS-80 Model 1 or 3 running TRS-DOS, also known as the /CMD format; XXXX is the name of the entry point to the program + + * `trscmd` - equivalent to `trscmd:main` * `format_segment_NAME` – if using the `per_segment` style, overrides the format for the given segment diff --git a/include/platform/coco_rsdos.ini b/include/platform/coco_rsdos.ini index 4e5eec74..42d8df33 100644 --- a/include/platform/coco_rsdos.ini +++ b/include/platform/coco_rsdos.ini @@ -23,7 +23,7 @@ HAS_BITMAP_MODE=1 [output] style=single -format=0,length_be,startaddr_be,allocated,$ff,0,0,startaddr_be +format=0,length_be,startaddr_be,allocated,$ff,0,0,addr_be:main extension=.bin diff --git a/include/platform/z1013.ini b/include/platform/z1013.ini index 6f6114ed..090bdb4c 100644 --- a/include/platform/z1013.ini +++ b/include/platform/z1013.ini @@ -21,7 +21,7 @@ HAS_BITMAP_MODE=0 [output] style=single -format=startaddr,endaddr,startaddr,"DDRDDR",$43,$d3,$d3,$d3,programname-16,allocated +format=startaddr,endaddr,addr:main,"DDRDDR",$43,$d3,$d3,$d3,programname-16,allocated extension=z80 diff --git a/src/main/scala/millfork/Platform.scala b/src/main/scala/millfork/Platform.scala index a4e388bc..b066eab6 100644 --- a/src/main/scala/millfork/Platform.scala +++ b/src/main/scala/millfork/Platform.scala @@ -285,8 +285,10 @@ object Platform { case l if l.startsWith("length_be-") => AllocatedDataLengthBe(-parseNumber(l.stripPrefix("length_be-"))) case "length_be" => AllocatedDataLengthBe(0) case "d88" => D88Output - case "tap" => TapOutput - case "trscmd" => TrsCmdOutput + case "tap" => new TapOutput("main") + case l if l.startsWith("tap:") => new TapOutput(l.stripPrefix("tap:").trim) + case "trscmd" => new TrsCmdOutput("main") + case l if l.startsWith("trscmd:") => new TrsCmdOutput(l.stripPrefix("trscmd:").trim) case n => n.split(":").filter(_.nonEmpty) match { case Array(b, s, e) => BankFragmentOutput(b, parseNumber(s), parseNumber(e)) case Array(s, e) => diff --git a/src/main/scala/millfork/output/TapOutput.scala b/src/main/scala/millfork/output/TapOutput.scala index 9dc1a573..afa05318 100644 --- a/src/main/scala/millfork/output/TapOutput.scala +++ b/src/main/scala/millfork/output/TapOutput.scala @@ -5,7 +5,7 @@ import java.nio.charset.StandardCharsets /** * @author Karol Stasiak */ -object TapOutput extends OutputPackager { +class TapOutput(val symbol: String) extends OutputPackager { def isAlphanum(c: Char): Boolean = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') @@ -15,7 +15,7 @@ object TapOutput extends OutputPackager { val code = b.output.slice(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)) + val loaderDataBlock = new DataBlock(ZxSpectrumBasic.loader("CODE", filteredName, b.start, mem.getAddress(symbol))) val loaderHeaderBlock = new HeaderBlock(0, "LOADER", loaderDataBlock.inputData.length, 10, loaderDataBlock.inputData.length) val result = Array(loaderHeaderBlock, loaderDataBlock, codeHeaderBlock, codeDataBlock).map(_.toArray) result.flatten @@ -86,13 +86,13 @@ object ZxSpectrumBasic { private def quoted(a: Any): Snippet = "\"" + a + "\"" - def loader(filename: String, rem: String, loadAddress: Int): Array[Byte] = { + def loader(filename: String, rem: String, loadAddress: Int, runAddress: Int): Array[Byte] = { Array( line(10, REM, rem), line(20, BORDER, VAL, quoted(7), colon, INK, NOT, PI, colon, PAPER, VAL, quoted(7), colon, CLS), line(30, CLEAR, VAL, quoted(loadAddress - 1)), line(40, LOAD, quoted(filename), CODE), - line(50, CLS, colon, PRINT, AT, NOT, PI, ",", NOT, PI, ";", colon, RANDOMIZE, USR, VAL, quoted(loadAddress)) + line(50, CLS, colon, PRINT, AT, NOT, PI, ",", NOT, PI, ";", colon, RANDOMIZE, USR, VAL, quoted(runAddress)) ).flatten } } \ No newline at end of file diff --git a/src/main/scala/millfork/output/TrsCmdOutput.scala b/src/main/scala/millfork/output/TrsCmdOutput.scala index 70e70710..a642df94 100644 --- a/src/main/scala/millfork/output/TrsCmdOutput.scala +++ b/src/main/scala/millfork/output/TrsCmdOutput.scala @@ -3,10 +3,11 @@ package millfork.output /** * @author Karol Stasiak */ -object TrsCmdOutput extends OutputPackager { +class TrsCmdOutput(symbol: String) extends OutputPackager { override def packageOutput(mem: CompiledMemory, bank: String): Array[Byte] = { val b = mem.banks(bank) val start = b.start + val run = mem.getAddress(symbol) 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 @@ -16,7 +17,7 @@ object TrsCmdOutput extends OutputPackager { // chunk type 2: relocation address // chunk length: for type 2, it's always 2 bytes // relocation address: 2 bytes, little-endian - 2, 2, b.start.toByte, b.start.>>(8).toByte + 2, 2, run.toByte, run.>>(8).toByte ) } }