This is the way they are defined in the GS/OS Reference, as well as the way they seem to be used by all assemblers and all other linkers that I could check (ORCA/M, MPW AsmIIGS, Apple LinkIIGS, old ORCA/APW LINKED, 8-bit ORCA linker).
Previously, this linker treated ORG records as giving an absolute address to ORG to (but with a bug in the address computation). The OMF spec in appendix B of the ORCA/M manual defines them this way, but this is inconsistent with the spec in the GS/OS Reference and with the way ORG records are generated by ORCA/M itself (for an ORG *+expression directive). Therefore, I think this is just an error and the specification in the GS/OS Reference should be regarded as correct.
We still do not support going backward (using a negative ORG operand). Trying to do so will just give an error.
Shifting is now prohibited only for relocatable expressions. It is fine if a shift operator is used with constant operands, simply producing another constant.
Also, spurious errors about using multiple load segments in an expression are no longer reported just because of the load segment "containing" the EQU/GEQU record. Since it does not actually translate to anything in the load file, that segment does not matter.
Previously, the values of such expressions were essentially ignored, resulting in incorrect output.
This affected code like the following example:
p gequ val
Note that the EQU/GEQU expression is evaluated within the context of the location that references it, not the location where it is defined. This affects the value of the location counter, as well as the symbol search behavior. The references for the OMF format do not clearly define which way this should be done, but the current behavior can cause problems with certain object files produced by ORCA/M.
Previously, the position-independent attribute bit would be set in a load segment if it was set on the first constituent object segment. Now it is only set in the load segment if it is set in all the constituent object segments. This is consistent with the ORCA linker's general approach of conservatively combining the flags from the object segments.
This is a new feature where the linker will automatically divide the code into load segments, creating as many segments as necessary to fit it. This relieves the programmer from the need to manually figure out how a large program can be divided into segments.
Auto-segmentation is triggered by the use of the special load segment name AUTOSEG~~~. Using this approach (rather than a flag in the OMF header) allows auto-segmentation to be used with all existing languages that provide a mechanism for specifying load segment names.
Previously, the high 16 bits were being ignored. Therefore, the valid alignment value $10000 was rejected, but values that were not a power of 2 may have been accepted. The new code properly enforces that the alignment is a power of 2, and is <= $10000.
The error "Alignment factor must not exceed segment align factor" is now given when an ALIGN record with greater alignment than its segment is encountered. (This is the error that was given erroneously in other circumstances before the last commit.)
This would happen if a later object segment had a more restrictive alignment than previous object segments that contribute to the same load segment, as in the following example:
These alignment requirements can be satisfied by just giving the load segment the most restrictive alignment of any object segment (since all alignments are powers of 2) and inserting space as necessary to align the code from each object segment.
Previously, the linker gave an error if the relative displacement was more than + or - 32 KB. But 2-byte RELEXPR records are typically used for the operand of the BRL instruction, and since its address calculation wraps around within the program bank, it can effectively address + or - 64KB (i.e. any location within the program bank). Similar reasoning applies to PER, the other instruction using long relative addressing.
This would give an error in code like the following:
ds 33000 ; realistic examples would have actual code here
(This currently also gives an assembler error due to similar logic in ORCA/M, but the output file can be linked anyway.)
This issue can affect very large functions compiled with ORCA/C or ORCA/Pascal, which may sometimes have branches that go more than 32 KB forward or back.
This enables the linker to work correctly with object files with either extension case (or a mix), so it can work with objects from any of the ORCA languages even on a case-sensitive filesystem.
If two object files differ only in the case of their extension, the one with the lower-case extension will be used, and the one with the upper-case extension will be ignored.