mirror of
https://github.com/byteworksinc/Linker.git
synced 2024-05-28 16:41:31 +00:00
Compare commits
26 Commits
linker-204
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
740f75cff5 | ||
|
ac725a6207 | ||
|
850952d612 | ||
|
9f232e883a | ||
|
da13b94a43 | ||
|
0b275e5b22 | ||
|
085c7c46ca | ||
|
3bb2802f2f | ||
|
390fd96ede | ||
|
ea3550bfcc | ||
|
ef5360eddd | ||
|
47460f34bb | ||
|
8aa3c4e8c7 | ||
|
aa9a585d19 | ||
|
d62fdba4bb | ||
|
2275b137d8 | ||
|
76ba56a36b | ||
|
42734c7433 | ||
|
1a643585e8 | ||
|
170fa09ecc | ||
|
433b4652d7 | ||
|
2cdbebe6e6 | ||
|
9bca07851b | ||
|
a8528f35b7 | ||
|
1ec542fde5 | ||
|
ce65f20394 |
28
GNUmakefile
Normal file
28
GNUmakefile
Normal file
|
@ -0,0 +1,28 @@
|
|||
SRC = exp.asm file.asm linker.asm out.asm pass1.asm pass2.asm \
|
||||
seg.asm symbol.asm util.asm
|
||||
|
||||
OBJECTS = $(SRC:%.asm=obj/%.A) $(SRC:%.asm=obj/%.ROOT)
|
||||
|
||||
|
||||
# link order is important.
|
||||
linker: $(OBJECTS)
|
||||
iix link \
|
||||
obj/linker obj/util obj/file obj/pass1 obj/pass2 obj/seg \
|
||||
obj/symbol obj/exp obj/out \
|
||||
keep=$@
|
||||
iix chtyp -a 0xdb01 $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) obj/*.A obj/*.ROOT obj/*.a obj.*.root
|
||||
$(RM) linker
|
||||
|
||||
|
||||
# fix the filetype on these headers
|
||||
# since they have no extension.
|
||||
ftype:
|
||||
iix chtyp -l asm directpage
|
||||
|
||||
obj/%.A : %.asm %.mac directpage
|
||||
iix compile $< keep=obj/$*
|
||||
|
50
build.ninja
Normal file
50
build.ninja
Normal file
|
@ -0,0 +1,50 @@
|
|||
# ninja build file.
|
||||
|
||||
builddir = obj
|
||||
o = obj
|
||||
|
||||
|
||||
rule compile
|
||||
command = iix compile $in keep=$o/$keep
|
||||
description = build $out
|
||||
|
||||
rule link
|
||||
command = iix link $orca-in keep=$out
|
||||
description = link $out
|
||||
|
||||
|
||||
|
||||
|
||||
build linker : link $o/exp.a $o/exp.root $o/file.a $o/file.root $
|
||||
$o/linker.a $o/linker.root $o/out.a $o/out.root $o/pass1.a $o/pass1.root $
|
||||
$o/pass2.a $o/pass2.root $o/seg.a $o/seg.root $o/symbol.a $o/symbol.root $
|
||||
$o/util.a $o/util.root
|
||||
orca-in = $o/linker $o/util $o/file $o/pass1 $o/pass2 $o/seg $
|
||||
$o/symbol $o/exp $o/out
|
||||
|
||||
|
||||
build $o/exp.a $o/exp.root : compile exp.asm | exp.mac directpage
|
||||
keep = exp
|
||||
build $o/file.a $o/file.root : compile file.asm | file.mac directpage
|
||||
keep = file
|
||||
build $o/linker.a $o/linker.root : compile linker.asm | linker.mac directpage
|
||||
keep = linker
|
||||
build $o/out.a $o/out.root : compile out.asm | out.mac directpage
|
||||
keep = out
|
||||
build $o/pass1.a $o/pass1.root : compile pass1.asm | pass1.mac directpage
|
||||
keep = pass1
|
||||
build $o/pass2.a $o/pass2.root : compile pass2.asm | pass2.mac directpage
|
||||
keep = pass2
|
||||
build $o/seg.a $o/seg.root : compile seg.asm | seg.mac directpage
|
||||
keep = seg
|
||||
build $o/symbol.a $o/symbol.root : compile symbol.asm | symbol.mac directpage
|
||||
keep = symbol
|
||||
build $o/util.a $o/util.root : compile util.asm | util.mac directpage
|
||||
keep = util
|
||||
|
||||
|
||||
default linker
|
||||
|
||||
build all : phony linker
|
||||
|
||||
# eof
|
1
exp.asm
1
exp.asm
|
@ -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
|
||||
*
|
||||
****************************************************************
|
||||
|
|
14
linker.asm
14
linker.asm
|
@ -8,6 +8,18 @@
|
|||
*
|
||||
****************************************************************
|
||||
*
|
||||
* Linker 2.1.0 prepared Jun 23 by Stephen Heumann
|
||||
*
|
||||
****************************************************************
|
||||
*
|
||||
* Linker 2.0.6 prepared Aug 21 by Stephen Heumann
|
||||
*
|
||||
****************************************************************
|
||||
*
|
||||
* Linker 2.0.5 prepared Sep 18 by Stephen Heumann
|
||||
*
|
||||
****************************************************************
|
||||
*
|
||||
* Linker 2.0.4 prepared Oct 17 by Stephen Heumann
|
||||
*
|
||||
****************************************************************
|
||||
|
@ -290,7 +302,7 @@ sf8 anop
|
|||
;
|
||||
lda progress
|
||||
beq wh1
|
||||
puts #'Link Editor 2.0.4',cr=t
|
||||
puts #'Link Editor 2.1.0',cr=t
|
||||
putcr
|
||||
wh1 anop
|
||||
;
|
||||
|
|
69
linker.notes
69
linker.notes
|
@ -1,8 +1,53 @@
|
|||
ORCA/Linker 2.0.4
|
||||
ORCA/Linker 2.1.0
|
||||
Copyright 1996, Byte Works Inc.
|
||||
Updated 2023
|
||||
|
||||
-- Change List --------------------------------------------------------------
|
||||
|
||||
2.1.0 1. The linker can now automatically divide a large program into
|
||||
segments. See "Auto-Segmentation," below.
|
||||
|
||||
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
|
||||
calculation for BRL wraps around within the program bank, it
|
||||
can branch forward or backward by up to 64 KB (to any location
|
||||
in the program bank), and the linker now allows this.
|
||||
|
||||
2. Fixed several problems related to alignment. Previously,
|
||||
the linker both reported spurious errors about alignment in
|
||||
certain cases and failed to detect errors in other cases.
|
||||
With these fixes, a segment alignment of $10000 is now
|
||||
permitted. Also, the linker can now link together multiple
|
||||
object segments with different alignment requirements into a
|
||||
single load segment, regardless of the order of the object
|
||||
segments. The alignment of the load segment will be the most
|
||||
restrictive alignment of any of the object segments, and the
|
||||
alignment requirements of each object segment will be obeyed.
|
||||
|
||||
3. A spurious error is no longer reported for code segments that
|
||||
are exactly $10000 bytes long (the full size of a bank).
|
||||
|
||||
2.0.5 1. On case-sensitive filesystems (which are not normally used
|
||||
natively on the Apple IIGS, but may be used through emulation
|
||||
tools or network file servers), the linker can now find object
|
||||
files with either upper-case or lower-case file extensions.
|
||||
|
||||
(Kelvin Sherlock, Stephen Heumann)
|
||||
|
||||
2. KeepType values of "DVR", "LDF", and "FST" are now accepted.
|
||||
|
||||
2.0.4 1. Fixed bugs that could cause spurious errors to be reported.
|
||||
|
||||
(Stephen Heumann)
|
||||
|
@ -29,4 +74,24 @@ Copyright 1996, Byte Works Inc.
|
|||
|
||||
-- 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 ----------------------------------
|
||||
|
||||
Auto-Segmentation
|
||||
-----------------
|
||||
|
||||
On the Apple IIGS, programs with more than 64 KB of code have to be divided into multiple load segments. This can be done using the segment directives in the various ORCA languages, but the programmer has to manually manage them, working out how much code would fit in each segment. Changes to a program's code or its compilation options (e.g. debugging or optimization settings) could alter the size of the generated machine code, requiring its segmentation to be changed.
|
||||
|
||||
The ORCA linker can now automatically assign code to load segments, avoiding the need to manually change the segmentation based on the code size. If code uses the special load segment name AUTOSEG~~~, the linker will automatically place it into load segments named AUTOSEG~00, AUTOSEG~01, etc., creating as many load segments as necessary to fit the code.
|
||||
|
||||
To use this feature in ORCA/C, ORCA/Pascal, or ORCA/Modula-2, simply use those languages' segment directives to specify the load segment name as AUTOSEG~~~ :
|
||||
|
||||
segment "AUTOSEG~~~"; (in ORCA/C)
|
||||
(*$Segment 'AUTOSEG~~~'*) (in ORCA/Pascal or ORCA/Modula-2)
|
||||
|
||||
You can place a directive like this at the top of each of your source files or (for ORCA/C) in a pre-include file.
|
||||
|
||||
It is also possible to use auto-segmentation for assembly code, but the code must be written to account for the fact that any two program segments using auto-segmentation may wind up in different load segments, and therefore might be placed in different banks at run time.
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
resource rVersion(1) {
|
||||
{
|
||||
2, /* Major revision */
|
||||
0, /* Minor revision */
|
||||
4, /* Bug version */
|
||||
1, /* Minor revision */
|
||||
0, /* Bug version */
|
||||
release, /* Release stage */
|
||||
0, /* Non-final release # */
|
||||
},
|
||||
verUS, /* Region code */
|
||||
"ORCA/Linker", /* Short version number */
|
||||
"Copyright 1996, Byte Works, Inc." /* Long version number */
|
||||
"Copyright 1996, Byte Works, Inc.\n" /* Long version number */
|
||||
"Updated 2023"
|
||||
};
|
||||
|
|
18
make
18
make
|
@ -14,47 +14,47 @@ end
|
|||
|
||||
if {#} == 0 then
|
||||
|
||||
Newer obj/linker.a linker.asm linker.macros directPage
|
||||
Newer obj/linker.a linker.asm linker.mac directPage
|
||||
if {Status} != 0
|
||||
set linker linker
|
||||
end
|
||||
|
||||
Newer obj/util.a util.asm util.macros directPage
|
||||
Newer obj/util.a util.asm util.mac directPage
|
||||
if {Status} != 0
|
||||
set util util
|
||||
end
|
||||
|
||||
Newer obj/file.a file.asm file.macros directPage
|
||||
Newer obj/file.a file.asm file.mac directPage
|
||||
if {Status} != 0
|
||||
set file file
|
||||
end
|
||||
|
||||
Newer obj/pass1.a pass1.asm pass1.macros directPage
|
||||
Newer obj/pass1.a pass1.asm pass1.mac directPage
|
||||
if {Status} != 0
|
||||
set pass1 pass1
|
||||
end
|
||||
|
||||
Newer obj/pass2.a pass2.asm pass2.macros directPage
|
||||
Newer obj/pass2.a pass2.asm pass2.mac directPage
|
||||
if {Status} != 0
|
||||
set pass2 pass2
|
||||
end
|
||||
|
||||
Newer obj/seg.a seg.asm seg.macros directPage
|
||||
Newer obj/seg.a seg.asm seg.mac directPage
|
||||
if {Status} != 0
|
||||
set seg seg
|
||||
end
|
||||
|
||||
Newer obj/symbol.a symbol.asm symbol.macros directPage
|
||||
Newer obj/symbol.a symbol.asm symbol.mac directPage
|
||||
if {Status} != 0
|
||||
set symbol symbol
|
||||
end
|
||||
|
||||
Newer obj/exp.a exp.asm exp.macros directPage
|
||||
Newer obj/exp.a exp.asm exp.mac directPage
|
||||
if {Status} != 0
|
||||
set exp exp
|
||||
end
|
||||
|
||||
Newer obj/out.a out.asm out.2 out.macros directPage
|
||||
Newer obj/out.a out.asm out.mac directPage
|
||||
if {Status} != 0
|
||||
set out out
|
||||
end
|
||||
|
|
25
out.asm
25
out.asm
|
@ -268,7 +268,7 @@ st1 lda segType or in the or flags
|
|||
sta loadType
|
||||
lda segType mask out missing and flags
|
||||
and #$E200
|
||||
ora #$3DFF
|
||||
ora #$1DFF
|
||||
and loadType
|
||||
sta loadType
|
||||
lda loadType get the type without flags
|
||||
|
@ -385,10 +385,13 @@ or4 anop
|
|||
ora loadAlign+2
|
||||
bne la1
|
||||
move4 segAlign,loadAlign loadAlign = segAlign
|
||||
bra la2 else
|
||||
la1 move4 segAlign,r0 PrepareAlign(segAlign)
|
||||
bra la3 else
|
||||
la1 cmpl loadAlign,segAlign if loadAlign < segAlign then
|
||||
bge la2
|
||||
move4 segAlign,loadAlign loadAlign = segAlign
|
||||
la2 move4 segAlign,r0 PrepareAlign(segAlign)
|
||||
jsr PrepareAlign
|
||||
la2 anop endif
|
||||
la3 anop endif
|
||||
bra sa4
|
||||
;
|
||||
; Set the load segment alignment (pass 2)
|
||||
|
@ -408,13 +411,9 @@ sa0 lda segAlign skip if alignment is 0
|
|||
bra sa3 else
|
||||
sa1 cmpl loadAlign,segAlign if loadAlign < segAlign then
|
||||
bge sa2
|
||||
ph4 #0 Error(NULL,22)
|
||||
ph2 #22
|
||||
jsr Error
|
||||
bra sa3 else
|
||||
sa2 move4 segAlign,r0 DefineAlign(segAlign)
|
||||
move4 segAlign,loadAlign loadAlign = segAlign
|
||||
sa2 move4 segAlign,r0 DefineAlign(segAlign)
|
||||
jsr DefineAlign
|
||||
! anop endif
|
||||
sa3 anop endif
|
||||
jsr CheckAlignOrg check for conflicts between align,org
|
||||
sa4 anop
|
||||
|
@ -2221,7 +2220,7 @@ NamedVariable private
|
|||
bne lb3 return false
|
||||
lda #nameEnd-name-3 index into the name array
|
||||
sta r4
|
||||
lda #$BA initial file number
|
||||
lda #$BD initial file number
|
||||
sta r6
|
||||
lb1 ldx r4 check for match
|
||||
ldy #2
|
||||
|
@ -2263,6 +2262,9 @@ name dc c'S16' file type mnemonics
|
|||
dc c'NDA'
|
||||
dc c'CDA'
|
||||
dc c'TOL'
|
||||
dc c'DVR'
|
||||
dc c'LDF'
|
||||
dc c'FST'
|
||||
nameEnd anop
|
||||
end
|
||||
|
||||
|
@ -2493,6 +2495,7 @@ lb2 add4 length,loadPC update the length of the program
|
|||
beq lb2a
|
||||
cmpl loadPC,loadBanksize
|
||||
blt lb2a
|
||||
beq lb2a
|
||||
ph4 #0
|
||||
ph2 #18
|
||||
jsr Error
|
||||
|
|
|
@ -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
|
||||
|
|
20
pass2.asm
20
pass2.asm
|
@ -26,6 +26,7 @@
|
|||
****************************************************************
|
||||
*
|
||||
Align private
|
||||
using Common
|
||||
|
||||
ldy #1 get the alignment factor
|
||||
lda [sp],Y
|
||||
|
@ -34,7 +35,12 @@ Align private
|
|||
iny
|
||||
lda [sp],Y
|
||||
sta r2
|
||||
add4 sp,#5 skip the alignment opcode and operand
|
||||
cmpl segAlign,r0 if alignment factor > segAlign
|
||||
bge lb1
|
||||
ph4 #0 Error(NULL,22)
|
||||
ph2 #22
|
||||
jsr Error
|
||||
lb1 add4 sp,#5 skip the alignment opcode and operand
|
||||
jsr DefineAlign do the align
|
||||
rts
|
||||
end
|
||||
|
@ -637,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
|
||||
|
@ -1385,7 +1390,7 @@ lb2 lda t1,X
|
|||
blt lb2
|
||||
lda t1-1,Y
|
||||
bpl lb6
|
||||
bra lb5
|
||||
bra lb4a
|
||||
lb3 lda #$FF
|
||||
lb4 cmp t1,X
|
||||
bne lb5
|
||||
|
@ -1394,6 +1399,9 @@ lb4 cmp t1,X
|
|||
blt lb4
|
||||
lda t1-1,Y
|
||||
bmi lb6
|
||||
lb4a lda expLength let BRL wrap around within program bank
|
||||
cmp #2
|
||||
bge lb6
|
||||
lb5 long I,M
|
||||
ph4 #0
|
||||
ph2 #11
|
||||
|
|
|
@ -608,3 +608,12 @@
|
|||
.d
|
||||
sta 2+&op
|
||||
mend
|
||||
macro
|
||||
&lab cmpl &n1,&n2
|
||||
&lab lda 2+&n1
|
||||
cmp 2+&n2
|
||||
bne ~&syscnt
|
||||
lda &n1
|
||||
cmp &n2
|
||||
~&syscnt anop
|
||||
mend
|
||||
|
|
158
seg.asm
158
seg.asm
|
@ -24,6 +24,102 @@ isLibrary ds 2 is the file we are processing a library file?
|
|||
largeLibFile ds 2 largest library file number
|
||||
libDisp ds 4 disp in library symbol table
|
||||
suffix ds 2 suffix letter
|
||||
|
||||
autoSegCounter ds 2 auto-segmentation counter (hex string)
|
||||
autoSegLength ds 4 length of current auto segment
|
||||
autoSegNamePtr ds 4 pointer to current auto-segment name
|
||||
end
|
||||
|
||||
****************************************************************
|
||||
*
|
||||
* AutoSegment - perform auto-segmentation
|
||||
*
|
||||
* inputs:
|
||||
* loadNamePtr - load segment name
|
||||
* segLength - # of bytes of code in the segment
|
||||
* segAlign - segment alignment factor
|
||||
*
|
||||
* outputs:
|
||||
* loadNamePtr - modified if using auto-segmentation
|
||||
*
|
||||
****************************************************************
|
||||
*
|
||||
AutoSegment start
|
||||
using SegCommon
|
||||
using Common
|
||||
using OutCommon
|
||||
|
||||
move4 loadNamePtr,r0 if load seg name is not 'AUTOSEG~~~'
|
||||
ldy #nameSize-2
|
||||
lb0 lda [r0],Y
|
||||
cmp autoSegStr,Y
|
||||
beq lb0a
|
||||
rts return
|
||||
lb0a dey
|
||||
dey
|
||||
bpl lb0
|
||||
|
||||
lda segAlign perform alignment if necessary
|
||||
bne lb1
|
||||
lda segAlign+2
|
||||
beq lb2
|
||||
lda #0
|
||||
lb1 dec a
|
||||
bit autoSegLength
|
||||
beq lb2
|
||||
ora autoSegLength
|
||||
inc a
|
||||
sta autoSegLength
|
||||
bne lb2
|
||||
inc autoSegLength+2
|
||||
|
||||
lb2 add4 autoSegLength,segLength update auto seg length
|
||||
lda autoSegLength+2 if it is over $10000 bytes
|
||||
beq lb5
|
||||
dec a
|
||||
ora autoSegLength
|
||||
beq lb5
|
||||
move4 segLength,autoSegLength set length to seg length
|
||||
|
||||
short M update auto-seg counter
|
||||
lda autoSegCounter+1
|
||||
inc a
|
||||
cmp #'9'+1
|
||||
bne lb3
|
||||
lda #'A'
|
||||
lb3 cmp #'F'+1
|
||||
bne lb3b
|
||||
lda autoSegCounter
|
||||
inc a
|
||||
cmp #'9'+1
|
||||
bne lb3a
|
||||
lda #'A'
|
||||
lb3a sta autoSegCounter
|
||||
lda #'0'
|
||||
lb3b sta autoSegCounter+1
|
||||
long M
|
||||
|
||||
ph4 #nameSize make new auto-seg name string
|
||||
jsr MLalloc
|
||||
sta r4
|
||||
sta autoSegNamePtr
|
||||
stx r4+2
|
||||
stx autoSegNamePtr+2
|
||||
ldy #nameSize-2
|
||||
lda autoSegCounter
|
||||
bra lb4a
|
||||
lb4 lda autoSegStr,Y
|
||||
lb4a sta [r4],Y
|
||||
dey
|
||||
dey
|
||||
bpl lb4
|
||||
! set load seg name to auto-seg name
|
||||
lb5 move4 autoSegNamePtr,loadNamePtr
|
||||
rts
|
||||
;
|
||||
; Local constant
|
||||
;
|
||||
autoSegStr dc c'AUTOSEG~~~'
|
||||
end
|
||||
|
||||
****************************************************************
|
||||
|
@ -161,7 +257,7 @@ giFiletype ds 2
|
|||
FindSuffix private
|
||||
using SegCommon
|
||||
|
||||
lda #'A' set the initial suffix
|
||||
lda #'a' set the initial suffix
|
||||
sta lsuffix
|
||||
lb1 lda lsuffix try it out
|
||||
sta suffix
|
||||
|
@ -174,7 +270,7 @@ lb1 lda lsuffix try it out
|
|||
bra lb1
|
||||
|
||||
lb2 lda lsuffix use the last one - it worked (or did
|
||||
dec A not exist, as in 'A'-1)
|
||||
dec A not exist, as in 'a'-1)
|
||||
sta suffix
|
||||
rts
|
||||
|
||||
|
@ -283,7 +379,17 @@ InitPass start
|
|||
stz lastFileNumber
|
||||
stz dataNumber no data areas processed
|
||||
stz lastDataNumber
|
||||
|
||||
lda #'00' initial auto-seg is 'AUTOSEG~00'
|
||||
sta autoSegCounter
|
||||
lla autoSegNamePtr,initialAutoSegName
|
||||
stz autoSegLength initial auto-seg length is 0
|
||||
stz autoSegLength+2
|
||||
rts
|
||||
;
|
||||
; Local constant
|
||||
;
|
||||
initialAutoSegName dc c'AUTOSEG~00'
|
||||
end
|
||||
|
||||
****************************************************************
|
||||
|
@ -304,8 +410,8 @@ InitPass start
|
|||
KeepName private
|
||||
using SegCommon
|
||||
|
||||
lda suffix if suffix = 'A'-1 then
|
||||
cmp #'A'-1
|
||||
lda suffix if suffix = 'a'-1 then
|
||||
cmp #'a'-1
|
||||
bne kn0
|
||||
clc return false
|
||||
rts
|
||||
|
@ -336,7 +442,18 @@ kn1 lda #'.'
|
|||
iny
|
||||
lda suffix
|
||||
sta [fname],Y
|
||||
dec suffix --suffix
|
||||
long M
|
||||
phy
|
||||
ph4 fname if not exists(fname) then
|
||||
jsr ExistsM
|
||||
ply
|
||||
tax
|
||||
short M
|
||||
bne kn2
|
||||
lda suffix uppercase suffix
|
||||
and #$DF
|
||||
sta [fname],Y
|
||||
kn2 dec suffix --suffix
|
||||
long M
|
||||
sec
|
||||
rts
|
||||
|
@ -865,6 +982,7 @@ vt0 ldy #version get the segment version number
|
|||
sta segName+2
|
||||
move4 segName,loadNamePtr
|
||||
add4 segName,#10
|
||||
jsr AutoSegment
|
||||
jsr FindLoadSegment
|
||||
ldy #s2numsex verify that numsex = 0
|
||||
lda [seg],Y
|
||||
|
@ -955,6 +1073,7 @@ vo1 cmp #1 branch if not version 1
|
|||
sta segName+2
|
||||
move4 segName,loadNamePtr
|
||||
add4 segName,#10
|
||||
jsr AutoSegment
|
||||
jsr FindLoadSegment
|
||||
ldy #s1numsex verify that numsex = 0
|
||||
lda [seg],Y
|
||||
|
@ -1053,14 +1172,14 @@ blankSeg dc 10c' ' default load segment name
|
|||
|
||||
****************************************************************
|
||||
*
|
||||
* RootName - Append .ROOT to file name
|
||||
* RootName - Append .root to file name
|
||||
*
|
||||
* inputs:
|
||||
* basename - base file name
|
||||
*
|
||||
* outputs:
|
||||
* ckname - current keep file name
|
||||
* tkname - .ROOT appended to contents of kname
|
||||
* tkname - .root appended to contents of kname
|
||||
* kltr - suffix letter for the main obj file
|
||||
*
|
||||
****************************************************************
|
||||
|
@ -1091,15 +1210,32 @@ RootName private
|
|||
iny
|
||||
iny
|
||||
ldx #0
|
||||
phy
|
||||
short M
|
||||
kn1 lda root,X
|
||||
rn1 lda root,X
|
||||
sta [fname],Y
|
||||
iny
|
||||
inx
|
||||
cpx #l:root
|
||||
bne kn1
|
||||
bne rn1
|
||||
long M
|
||||
rts
|
||||
ph4 fname if not exists(fname) then
|
||||
jsr ExistsM
|
||||
ply
|
||||
tax
|
||||
bne ret
|
||||
short M
|
||||
ldx #1
|
||||
iny
|
||||
rn2 lda root,X uppercase suffix
|
||||
and #$DF
|
||||
sta [fname],Y
|
||||
iny
|
||||
inx
|
||||
cpx #l:root
|
||||
bne rn2
|
||||
long M
|
||||
ret rts
|
||||
|
||||
root dc c'.ROOT'
|
||||
root dc c'.root'
|
||||
end
|
||||
|
|
16
settypes
Normal file
16
settypes
Normal file
|
@ -0,0 +1,16 @@
|
|||
filetype -p =.asm src; change -p =.asm asm65816
|
||||
filetype -p =.mac src; change -p =.mac asm65816
|
||||
filetype directpage src; change directpage asm65816
|
||||
filetype smac src; change smac asm65816
|
||||
filetype linker.rez src; change linker.rez rez
|
||||
filetype backup src; change backup exec
|
||||
filetype count src; change count exec
|
||||
filetype linkit src; change linkit exec
|
||||
filetype make src; change make exec
|
||||
filetype settypes src; change settypes exec
|
||||
filetype build.ninja txt
|
||||
filetype GNUmakefile txt
|
||||
filetype LICENSE txt
|
||||
filetype linker.notes txt
|
||||
filetype README.md txt
|
||||
filetype obj:README.txt txt
|
28
symbol.asm
28
symbol.asm
|
@ -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
|
||||
|
|
17
util.asm
17
util.asm
|
@ -24,8 +24,14 @@ count equ 1 bit count
|
|||
|
||||
sub (4:align),2
|
||||
|
||||
stz count count the bits
|
||||
ldx #16
|
||||
cmpl align,#$10001 if align > $10000 then
|
||||
blt lb0
|
||||
ph4 #0 flag the error (alignment too large)
|
||||
ph2 #25
|
||||
jsr Error
|
||||
|
||||
lb0 stz count count the bits
|
||||
ldx #32
|
||||
lb1 lsr align+2
|
||||
ror align
|
||||
bcc lb2
|
||||
|
@ -124,6 +130,7 @@ erLev dc I1'8,16,16,2'
|
|||
dc I1'4,16,2,8'
|
||||
dc I1'8,4,4,8'
|
||||
dc I1'8,8,8,8'
|
||||
dc I1'8'
|
||||
|
||||
erAdr dc a'er1-1'
|
||||
dc a'er2-1'
|
||||
|
@ -149,6 +156,7 @@ erAdr dc a'er1-1'
|
|||
dc a'er22-1'
|
||||
dc a'er23-1'
|
||||
dc a'er24-1'
|
||||
dc a'er25-1'
|
||||
|
||||
er1 dw 'Duplicate label'
|
||||
er2 dw 'Illegal shift operator'
|
||||
|
@ -172,6 +180,7 @@ er21 dw 'Alignment and ORG conflict'
|
|||
er22 dw 'Alignment factor must not exceed segment align factor'
|
||||
er23 dw 'Alignment factor must be a power of two'
|
||||
er24 dw 'Expression operand is not in same segment'
|
||||
er25 dw 'Alignment factor is too large'
|
||||
end
|
||||
|
||||
****************************************************************
|
||||
|
@ -382,7 +391,7 @@ lb4 ret
|
|||
*
|
||||
* 1: Could not open file <fname>
|
||||
* 2: Must be an object file: <fname>
|
||||
* 3: Linker version misatch
|
||||
* 3: Linker version mismatch
|
||||
* 4: Illegal header value in <fname>
|
||||
* 5: Out of memory
|
||||
* 6: File read error: <fname>
|
||||
|
@ -435,7 +444,7 @@ msg dc a'e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15'
|
|||
|
||||
e1 dos 'Could not open file '
|
||||
e2 dos 'Must be an object file: '
|
||||
e3 dos 'Linker version misatch'
|
||||
e3 dos 'Linker version mismatch'
|
||||
e4 dos 'Illegal header value in '
|
||||
e5 dos 'Out of memory'
|
||||
e6 dos 'File read error: '
|
||||
|
|
Loading…
Reference in New Issue
Block a user