Skip to content

SymbolAddressOutput emits wrong data (bank end instead of symbol address) #145

@zbyti

Description

@zbyti

When using the addr:symbol format specifier in a platform .ini file, the emitted bytes are not the little‑endian address of the symbol, but rather the little‑endian representation of the bank's end address (b.end).

How to reproduce:

  1. Define a platform with output format containing addr:vbl (where vbl is a valid label).
  2. Compile a program for that platform.
  3. Observe that instead of 0C 02 (for address $020C), the output contains e.g. 11 02 (if bank ends at $0211).

Cause:
In OutputPackager.scala, the SymbolAddressOutput class incorrectly references b.end instead of the resolved symbol address x.

Current (buggy) code:

case class SymbolAddressOutput(symbol: String, bonus: Int) extends OutputPackager {
  def packageOutput(flc: FileLayoutCollector, mem: CompiledMemory, bank: String): Array[Byte] = {
    val b = mem.banks(bank)
    val x = mem.getAddress(symbol) + bonus
    Array(b.end.toByte, b.end.>>(8).toByte)   // <-- WRONG: uses b.end
  }
}

Expected behavior:
It should use x (the resolved address) and emit it in little‑endian order.

Fix:

case class SymbolAddressOutput(symbol: String, bonus: Int) extends OutputPackager {
  def packageOutput(flc: FileLayoutCollector, mem: CompiledMemory, bank: String): Array[Byte] = {
    val b = mem.banks(bank)
    val x = mem.getAddress(symbol) + bonus
    Array(x.toByte, x.>>(8).toByte)           // <-- CORRECT
  }
}

Affected files:
src/main/scala/millfork/output/OutputPackager.scala (line approx. 135)

Workaround:
Use addr_be:symbol and manually swap the two bytes in the resulting binary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions