qlinkgs - implement the len/pos linker opcodes

len [label]

sets label = size of most recently linked/imported file

  pos [label]

sets label = size of current segment.  If no label, resets the position variable to 0.

label is added to the symbol table as an absolute entry.

Testing in merlin 16+, these are absolute entry labels, not gequ labels
Merlin does not include any ds fill in the len/pos, but that decision
seems questionable. these do include a ds fill for both.
This commit is contained in:
Kelvin Sherlock 2021-04-27 23:53:54 -04:00
parent b6826d0df4
commit 59925b3a08
5 changed files with 155 additions and 2 deletions

View File

@ -252,6 +252,9 @@ linksymnum ds 2
linknextlbl ds 4 linknextlbl ds 4
linkpos ds 4 ; pos / len
linklen ds 2
opmask ds 2 ;EVAL variables opmask ds 2 ;EVAL variables
number ds 2 number ds 2
bracevalid ds 2 bracevalid ds 2

View File

@ -1092,8 +1092,93 @@ zipop lda passnum
clc clc
rts ;return error from newsegment rts ;return error from newsegment
posop ;I don't know what these do
lenop clc ;or how Merlin uses them so....????? * read label from operand into labstr.
getlabel
stz labstr
sep $20
ldy #0
ldx #0
]flush lda (lineptr),y
and #$7f
cmp #' '
blt :done
bne :first
iny
bra ]flush
:first cmp #';'
beq :done
cmp #'*'
beq :done
cmp #':'+1
blt :bad
cmp #']'
beq :bad
sta labstr+1
inx
]lup iny
lda (lineptr),y
and #$7f
cmp #' '+1
blt :done
cpx #lab_size
bcs ]lup
sta labstr+1,x
inx
bra ]lup
:done txa
sta labstr
rep $30
clc
rts
:bad rep $30
sec
lda #badlable.$80
rts
* len label
* set label = length of last lnk
lenop bit passnum
bpl :equ
:rts clc
rts
:equ jsr getlabel
bcc :ok
rts
:ok lda labstr
and #$ff
beq :rts
lda linklen
sta labval
stz labval+2
lda #linkentrybit.linkabsbit
jmp insertlable
* pos label
* set label = current linker offset.
* resets offset to 0 if no label.
posop bit passnum
bpl :equ
clc
rts
:equ jsr getlabel
bcc :ok
rts
:ok lda labstr
and #$ff
beq :zero
lda linkpos
sta labval
lda linkpos+2
sta labval+2
lda #linkentrybit.linkabsbit
jmp insertlable
:zero stz linkpos
stz linkpos+2
clc
rts rts
extop bit passnum extop bit passnum
@ -1484,6 +1569,15 @@ impop sec
lda #$00 lda #$00
adc reloffset+2 adc reloffset+2
sta reloffset+2 sta reloffset+2
lda :aux
sta linklen
clc
adc linkpos
sta linkpos
lda #$00
adc linkpos+2
sta linkpos+2
:l psl :handle :l psl :handle
_HUnlock _HUnlock
lda #$00 lda #$00
@ -1676,6 +1770,15 @@ lnkop sec
lda #$00 lda #$00
adc reloffset+2 adc reloffset+2
sta reloffset+2 sta reloffset+2
lda :aux
sta linklen
clc
adc linkpos
sta linkpos
lda #$00
adc linkpos+2
sta linkpos+2
bit :errvalid bit :errvalid
bpl :l bpl :l
lda :rel+2 lda :rel+2
@ -3579,6 +3682,9 @@ savop lda #$00
stz :ct stz :ct
stz rellength stz rellength
stz rellength+2 stz rellength+2
stz linklen
stz linkpos
stz linkpos+2
psl #:str psl #:str
_QADrawString _QADrawString

15
testdata/3013-len-pos-1.S vendored Normal file
View File

@ -0,0 +1,15 @@
rel
ext my_pos_0
ext my_len_1,my_pos_1
ext my_len_2,my_pos_2
lda #my_len_1
lda #my_len_2
ldx #my_pos_1
ldx #my_pos_2
ldy #my_pos_0
rtl
sav 3013-len-pos-1.L

5
testdata/3013-len-pos-2.S vendored Normal file
View File

@ -0,0 +1,5 @@
rel
* make sure ds adjusts len/pos appropriately.
ds \
sav 3013-len-pos-2.L

24
testdata/3013-len-pos-link.S vendored Normal file
View File

@ -0,0 +1,24 @@
ovr all
asm 3013-len-pos-1.S
asm 3013-len-pos-2.S
lnk 3013-len-pos-1.L
len my_len_1
pos my_pos_1
lnk 3013-len-pos-2.L
len my_len_2
pos my_pos_2
pos
pos my_pos_0
sav 3013-len-pos
ent