Compare commits

...

3 Commits

Author SHA1 Message Date
Stephen Heumann 850952d612 Treat ORG records as giving a signed offset from the current location.
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.
2022-09-26 21:32:28 -05:00
Stephen Heumann 9f232e883a Avoid spurious errors when evaluating EQU/GEQU expressions.
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.
2022-09-25 21:49:01 -05:00
Stephen Heumann da13b94a43 Properly evaluate non-constant expressions in EQU/GEQU records.
Previously, the values of such expressions were essentially ignored, resulting in incorrect output.

This affected code like the following example:

test1   start
        lda     >p
        rtl
        end

D1      data
p       gequ    val
        end

val     data
        dc      i'123'
        end

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.
2022-09-25 21:42:20 -05:00
5 changed files with 26 additions and 31 deletions

View File

@ -727,6 +727,7 @@ addr dc a'EndExp' $00 End
* shiftFlag - 1 if the value is shifted, else 0
* shiftValue - expression result before shifting
* shiftCount - shift counter
* symbolRelocatable - non-zero if sym is relocatable
* returns the value of the expression
*
****************************************************************

View File

@ -10,6 +10,14 @@ Updated 2022
2. A load segment is now flagged as position-independent only if
all the constituent object segments have that attribute set.
3. Fixed bug that caused EQU or GEQU expressions with non-constant
operands to be evaluated incorrectly.
4. The numeric value in an ORG record is now treated as a signed
offset from the current location, consistent with its
definition in the GS/OS Reference. However, negative offset
values are not supported and will produce an error.
2.0.6 1. The linker could give a spurious error about the relative
address calculation for a BRL instruction if it branched
forward or backward more than 32 KB. Since the address
@ -66,7 +74,9 @@ Updated 2022
-- Documentation Update -----------------------------------------------------
No changes.
ORCA/M Manual, p. 492
The operand in an ORG record is a signed offset from the current location, not an absolute address. (This is consistent with the definition in the GS/OS Reference, and with the behavior of ORCA/M and other assemblers and linkers.)
-- Changes introduced in ORCA/Linker 2.1.0 ----------------------------------

View File

@ -137,13 +137,12 @@ DoOrg private
sta r0
ldy #3
lda [sp],Y
sta r2+2
sta r2
add4 sp,#5
sub4 r0,loadOrg get the disp from the segment start
cmpl pc,r0
bge lb1 if the disp is greater than the pc then
move4 r0,pc update the pc
lda r2
bmi lb1 if the disp is positive
add4 pc,r0 update the pc
lb1 anop
rts
end

View File

@ -643,13 +643,12 @@ DoOrg private
ldy #1 get the value
lda [sp],Y
sta r4
sta r0
ldy #3
lda [sp],Y
sta r6
sta r2
add4 sp,#5 skip the op code & operand
sub4 pc,r4,r0 calculate the space to insert
lda r2 if space < 0 then
lda r2 if disp < 0 then
bpl lb1
ph4 #0 Error(NULL,3)
ph2 #3

View File

@ -845,15 +845,10 @@ gb3 ldy #symPriv if sym^.symPriv then
sv1 ldy #symExp if the value is an expression then
lda [sym],Y
jeq sv2
ph2 copiedExpression save volitile variables
ph2 copiedExpression save volatile variables
ph4 shiftCount
ph2 shiftFlag
ph4 shiftValue
ph2 symbolCount
ph2 symbolLength
ph2 symbolRelocatable
ph2 symbolType
ph4 symbolValue
ldy #symVal+2 evaluate the expression
lda [sym],Y
pha
@ -864,23 +859,14 @@ sv1 ldy #symExp if the value is an expression then
jsr Evaluate
sta symbolValue save the value
stx symbolValue+2
lda shiftFlag if the value is shifted then
beq sv1a
ph4 name flag the error
ph2 #2
jsr Error
sv1a lda symbolRelocatable if the symbol is relocatable then
beq sv1c
jsr CheckSegment check for errors
ldy #symSeg set the expression file
lda [sym],Y
sta expSegment
sv1c pl4 symbolValue restore volitile variables
pl2 symbolType
pl2 symbolRelocatable
pl2 symbolLength
pl2 symbolCount
pl4 shiftValue
lda shiftFlag if the value is shifted then
beq sv1c
ph4 name flag the error
ph2 #2
jsr Error
sv1c pl4 shiftValue restore volatile variables
pl2 shiftFlag
pl4 shiftCount
pl2 copiedExpression