Binary Relocatable Format
BRF code is a stream of eight-bit bytes and can be stored on any data medium (tape, file etc). The information can be divided into the following three basic types:
- Control information: A single byte, the control number. This is interpreted as a linker command.
- Programmed information: Two bytes containing a 16-bit word, called a P-group
- Symbolic information in either four bytes for MAC or NPL, or six bytes for BRF produced by compilers (e.g. FORTRAN). This is called an S-group and contains a symbol of one to seven packed six-bit characters.
BRF code are sequences of BRF groups, where each BRF group is a a combination of the three basic types. A BRF group can take one of the following four forms:
<control number byte> <control number byte><P-group><P-group> <control number byte><S-group> <control number byte><S-group><P-group>
BRF Control Numbers
The possible values and meaning of the control numbers are described in the following table. 'Words' are 16-bits words in big endian format.
| Control Number | Mnemonic | Argument size in words | Interpretation |
|---|---|---|---|
| 08 | FEED | 0 | Ignored |
| 18 | LF | 1 | W1 -> ((CLC)), (CLC)+1 -> (CLC) |
| 28 | LR | 1 | W1+(PB) -> ((CLC)),(CLC)+1 -> (CLC) |
| 38 | LC | 1 | W1+(CDB) -> ((CLC)),(CLC)+1 -> (CLC) |
| 48 | AFF | 2 | W1+(W2)->(W2) |
| 58 | ARF | 2 | W1+(PB)+(W2) -> (W2) |
| 68 | AFR | 2 | W1+(W2+(PB)) -> (W2+(PB)) |
| 78 | ARR | 2 | W1+(PB)+(W2+(PB)) -> (W2+(PB)) |
| 108 | SFL | 1 | W1 -> (CLC) |
| 118 | AFL | 1 | W1+(CLC) -> (CLC), fill zeroes |
| 128 | SRL | 1 | W1+(PB) -> (CLC) |
| 138 | - | Not used | |
| 148 | MAIN | 2 (3) | Symbol in S-group will become the main entry. Size of S-group depends on LONG control number. |
| 158 | LIBR | 2 (3) | Symbol in S-group will be conditionally loaded |
| 168 | ENTR | 2 (3) | Symbol in the S-group is assigned value of CLC |
| 178 | BEG | 0 | (CLC) -> (PB) First control byte of a unit. Linker-managed counters reset. |
| 208 | REF | 2 (3) | Symbol in S-group is referenced in CLC |
| 218 | END | 1 | W1 contains the BRF checksum |
| 228 | INHB | 1 | Warns that compilation errors have occured |
| 238 | EOF | 0 | End of loading |
| 248 | LNF | 1+W1 | W2,W3....,Wn -> (CLC),....,(CLC+W1-1) |
| 258 | RT | 1 | W1 contains real time priority |
| 268 | ASF | 3 (4) | <symbol>,<number> Defines common length. Value of symbol in loader table = common start address. |
| 278 | ADS | 2 (3) | <symbol> + (CLC-1) -> (CLC-1) Adds common address |
| 308 | MSG | 1+W1 | W1 contains length of message in words: W1 is followed by W1*2 ASCII character bytes |
| 318 | - | Not used | |
| 328 | LONG | 0 | Flags a six-byte S-group (see MAIN,LIBR,ENTR,REF,ASF,ADS,INC,DBC,RLC,CXC) |
| 338 | - | Not used | |
| 348 | INL | 2 | W2 -> (W1+(PB)) |
| 358 | DBL | 3 | Wi -> (W1+(BP)+i-2) (i = 2 to 3) |
| 368 | RLL | 4 | Wi -> (W1+(PB)+i-2) (i = 2 to 4) |
| 378 | CLX | 7 | Wi -> (W1+(PB)+i-2) (i = 2 to 7) |
| 408 * | INC | 4 (5) | W5 -> (W4 + ADR) |
| 418 * | DBC | 5 (6) | Wi -> (W4 + ADR + i-5) (i = 5 to 6) |
| 428 * | RLC | 6 (7) | Wi -> (W4 + ADR + i-5) (i = 5 to 7) |
| 438 * | CXC | 9 (10) | Wi -> W4 + ADR + i-5) (i = 5 to 10) |
| 448 | BYL | 2 | W2(bit 0-7) -> (W1+(PB))(bit 0-7) if W2 bit 15=1 ** |
| W2(bit 0-7) -> (W1+(PB))(bit 8-15) if W2 bit 15=0 ** | |||
| 458 * | BYC | 5 | W5(bit 0-7) -> (W4+(ADR))(bit 0-7) if W5 bit 15=1 ** |
| W5(bit 0-7) -> (W4+(ADR))(bit 8-15) if W5 bit 15=0 ** | |||
| 468 | NWL | 1 | W1 contains line number. (Not in use.) |
| 478 | DBG | 0 | Indicates start/stop of Debug information |
| 508 | PMO | 0 | Indicates start of program bank mode |
| 518 | DMO | 0 | Indicates start of data bank mode |
| 528 | LRP | 1 | Same as LR but PB of program bank |
| 538 | LRD | 1 | Same as LR but PB of data bank |
| 548 | DIC | - | Dictionary table follows. Each element contains name (3 words) and byte pointer (2 words). End of table marked by -1 |
| * The W1, W2, and W3 contains a common block name. At load time the symbol must be defined. Its value is referred to as ADR. | |||
| ** The documentation says the opposite (bit 0-7 if bit 15=0), but the documentation appears to be incorrect here. | |||
BRF decoding example
The BRF Linker can also be used to inspect BRF code. The example below shows how to look at a single library function, "5STOP" (an internal Fortran function) from the Fortran-100 2-bank library file FORTRAN-2BANK:BRF. The BRF Linker command LIST-BRF-CODE is used to show the library entry. The columns are interpreted as follows:
- Current location counter (octal)
- BRF control number (octal)
- BRF control number mnemonic
- Either:
- Symbolic names (LIBR, ENTR, MAIN etc.), or
- Binary information (octal)
- Disassembled instruction (if program mode, e.g. set by PMO)
- Other values (octal), if relevant
- BRF Linker - 210721C01
Brl: list-brf-code
Input file :fortran-2bank
First unit :5stop
Last unit :5stop
Output file:
1 17 BEG *** new BRF - unit ***
1 32 LONG
1 51 DMO
1 15 LIBR 5STOP
1 50 PMO
1 16 ENTR 5STOP
1 24 LNF 3
1 146147 COPY SL DX
2 135024 JPL I * 24
3 0 STZ *
4 20 REF 5STACK
5 24 LNF 21
5 600 STZ ,B - 200
6 1 STZ * 1
7 0 STZ *
10 146157 COPY SA DX
11 46000 LDA ,X 0
12 4606 STA ,B - 172
13 46001 LDA ,X 1
14 4607 STA ,B - 171
15 44606 LDA ,B - 172
16 4406 STA ,B 6
17 44607 LDA ,B - 171
20 4407 STA ,B 7
21 44602 LDA ,B - 176
22 172406 AAA 6
23 171002 SAT 2
24 135003 JPL I * 3
25 135003 JPL I * 3
26 20 REF 5INIT
27 20 REF 5MSTOP
30 20 REF 5LEAV
31 51 DMO
1 50 PMO
31 6 AFR 2,3
31 6 AFR 210,20
31 6 AFR 210,16
31 51 DMO
1 50 PMO
31 21 END checksum : 27512
Brl:
Note that the disassembled code may not be the final instruction as will be seen in the linked PROG file. In the example above the three AFR entries are used to modify the values of earlier fields (see AFR description in the table of control numbers). Here the location PB+3, which is 0+3, i.e. location counter 3 in the listing (0 STZ * is changed to 2, which is STZ * 2, and locations 208 and 168 are added with 2108, resulting in instructions STA ,B - 161 and STA ,B - 162 respectively.
References
- Norsk Data Document ND–60.196.01 BRF-LINKER USER MANUAL Chapter 6