Skip to content

REL File Format

ksherlock edited this page May 31, 2020 · 12 revisions
  • File Type: $F8 (User #8)
  • Aux Type: (offset of relocation table)

Relocatable intermediate files are generated via the REL pseudo op. OMF object files may also be converted to REL format with the CON command (via the editor command box).

The file is assembled, and all expressions are evaluated, with an origin of $8000. External labels are given an address of $8000

Bytes 0 -- (aux type-1) are the assembled data. This is followed by 0 or more relation records, a 0 byte, 0 or more label entries, and a 0 byte.

Relocation Records

Relocation records are 4 bytes long. The first bytes is a flag byte. This is followed by a 16-bit offset, and an 8-bit operand byte. For external references, the operand byte is the external symbol number. For local references, the operand byte is the low 8-bits of the assembled operand.

Flag Byte

  • bits 0-3 always populated ($0f)
  • bit 4 ($10) indicates an external label
  • bit 7 ($80) indicates a 2-byte relocation
  • bit 6 ($40) indicates a 1-byte relocation with an 8-bit shift
  • bit 5 ($20) indicates a 3-byte relocation
  • bit 7 and 5 ($a0) indicates a 2-byte, byte swapped relocation (DDB).
  • $ff indicates a shift (see below)

This is followed by the 16-bit offset to patch.

For external symbols, the 4th bytes is the symbol number (which starts at 0). For local symbols, the 4th byte is the low byte of the operand at the offset.

Shifting

Shifts (16 bit or 8 bit only) use two relocation records. The first record uses a flag byte of $ff. This is followed by the offset and operand/symbol number as above.

Following the $ff record is the shift record.

  • $d0 is the shift operand.
  • bit 2 is the external ($04) / internal flag.
  • $d0 is a 16-bit, 1-byte shift (n.b. due to 24-bit address space, high byte of a 16-bit shift is always 0).
  • $d1 is an 8-bit, 2-byte shift
  • $d3 is an 8-bit, 1-byte shift

Other shift sizes are not supported.

This is followed by a 3-byte address of the value before shifting (as always, assuming an origin of $8000)

$4F Shifting

There is also a 1-relocation record shift available. This is 1-byte, 8-bit shift to an internal label.

The flag byte is $4f. The value is split, with the MSB inline and the LSB in the relocation record.

Labels

The label type and length are encoded in the first byte.

  • bits 0-4 ($1f) are the label length.
  • bit 5 ($20) indicates an absolute label (ie, exporting an EQU)
  • bit 6 ($40) indicates a local (ENTry) label.
  • bit 7 ($80) indicates an EXTernal label.

This is followed by the label and a 3-byte address.

For local and EQU labels, this is the label address (based on the $8000 origin).

For external labels, this is the external label number + $8000. For external direct page labels (EXD), this is the external label number.

References

  • Merlin 8/16 User's Manual
  • Merlin 16+ source code
  • Quick Asm source code
  • Empirical testing
Clone this wiki locally