mirror of https://github.com/fachat/xa65.git
Merge tag 'xa-2.3.10' into 6-dsb-neg
This commit is contained in:
commit
20ea553a48
3
README
3
README
|
@ -5,8 +5,7 @@ xa65 is a 6502 cross assembler, running on Unix (and Unix-alikes), and producing
|
|||
|
||||
xa65 was originally authored by me, André Fachat, but currently and still xa65 is maintained by Cameron Kaiser at http://www.floodgap.com/retrotech/xa/ .
|
||||
|
||||
Due to current time constraints Cameron can not do any updates, so I decided to create this repository to publish my (beta) version that implements a long outstanding feature: assembler listings...
|
||||
|
||||
In this experimental repository, I am mirroring Cameron's releases and I am working on fixes and changes that I may want to submit to Cameron.
|
||||
|
||||
These are the directories:
|
||||
|
||||
|
|
17
xa/ChangeLog
17
xa/ChangeLog
|
@ -335,3 +335,20 @@ xa-2.3.9
|
|||
(Just kidding.)
|
||||
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com> 31 January 2019
|
||||
|
||||
xa-2.3.10
|
||||
|
||||
* Three fixes, all from Andre:
|
||||
- Don't crash if a useless segment is referenced outside of relocating
|
||||
mode (thanks Laszlo Barath for the report).
|
||||
- Don't substitute within strings, for better cpp compatibility (thanks
|
||||
Glenn Holmer for the report). I added the -S option for backwards
|
||||
compatibility for the old behaviour; it will be removed in 2.4 and later.
|
||||
- Fix underflow issue if a variable is late-bound (with -L) when that
|
||||
variable is used in computations with negative offsets.
|
||||
* Deprecated options will be removed in 2.4 and everything is warned.
|
||||
* Documentation updated.
|
||||
* Testsuite expanded.
|
||||
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com> 9 November 2019
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ install: xa uncpk
|
|||
#$(MKDIR) $(DOCDIR)/xa65
|
||||
|
||||
dist: clean
|
||||
cd .. ; tar cvf xa-2.3.9.tar xa-2.3.9 ; gzip xa-2.3.9.tar
|
||||
cd .. ; tar cvf xa-2.3.10.tar xa-2.3.10 ; gzip xa-2.3.10.tar
|
||||
|
||||
test: xa uncpk
|
||||
cd tests && ./harness -make="$(MAKE)" -cc="$(CC)" -cflags="$(CFLAGS)"
|
||||
|
|
|
@ -3,7 +3,7 @@ derivatives). xa is a small, fast, portable two-pass assembler that compiles
|
|||
under most ANSI C compilers. It is distributed under the GNU Public License
|
||||
(see COPYING).
|
||||
|
||||
The current version is 2.3.9, a bug fix to the long-lived 2.3.0, itself with
|
||||
The current version is 2.3.10, a bug fix to the long-lived 2.3.0, itself with
|
||||
compatibility improvements and new man-based documentation. It also completed
|
||||
the merge of the 65816 and 6502/R65C02 versions and thus the current xa can
|
||||
generate code for all targets now.
|
||||
|
|
41
xa/man/xa.1
41
xa/man/xa.1
|
@ -1,4 +1,4 @@
|
|||
.TH XA "1" "31 January 2019"
|
||||
.TH XA "1" "9 November 2019"
|
||||
|
||||
.SH NAME
|
||||
xa \- 6502/R65C02/65816 cross-assembler
|
||||
|
@ -21,14 +21,6 @@ further in this manual page.
|
|||
.B \-v
|
||||
Verbose output.
|
||||
.TP
|
||||
.B \-x
|
||||
Use old filename behaviour (overrides
|
||||
.BR \-o ,
|
||||
.B \-e
|
||||
and
|
||||
.BR \-l ).
|
||||
This option is now deprecated.
|
||||
.TP
|
||||
.B \-C
|
||||
No CMOS opcodes (default is to allow R65C02 opcodes).
|
||||
.TP
|
||||
|
@ -133,6 +125,23 @@ Show summary of options.
|
|||
.TP
|
||||
.B \-\-version
|
||||
Show version of program.
|
||||
.LP
|
||||
The following options are
|
||||
.BR deprecated
|
||||
and will be removed in 2.4 and later versions:
|
||||
.TP
|
||||
.B \-x
|
||||
Use old filename behaviour (overrides
|
||||
.BR \-o ,
|
||||
.B \-e
|
||||
and
|
||||
.BR \-l ).
|
||||
.TP
|
||||
.B \-S
|
||||
Allow preprocessor substitution within strings (this is now disallowed
|
||||
for better
|
||||
.BR cpp (1)
|
||||
compatibility).
|
||||
|
||||
.SH ASSEMBLER SYNTAX
|
||||
|
||||
|
@ -946,6 +955,20 @@ be prepended with the
|
|||
prefix. Otherwise, the assembler will attempt to optimize to 16 bits, which
|
||||
may be undesirable.
|
||||
|
||||
.SH "IMMINENT DEPRECATION"
|
||||
The following options and modes will be
|
||||
.B REMOVED
|
||||
in 2.4 and later versions of
|
||||
.BR xa :
|
||||
.LP
|
||||
.B \-x
|
||||
.LP
|
||||
.B \-S
|
||||
.LP
|
||||
the original
|
||||
.B mvn $xxxx
|
||||
syntax
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR file65 (1),
|
||||
.BR ldo65 (1),
|
||||
|
|
28
xa/src/xa.c
28
xa/src/xa.c
|
@ -55,13 +55,14 @@
|
|||
#define ANZWARN 13
|
||||
|
||||
#define programname "xa"
|
||||
#define progversion "v2.3.9"
|
||||
#define progversion "v2.3.10"
|
||||
#define authors "Written by Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser"
|
||||
#define copyright "Copyright (C) 1989-2019 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser."
|
||||
|
||||
/* exported globals */
|
||||
int ncmos, cmosfl, w65816, n65816;
|
||||
int masm = 0;
|
||||
int ppinstr = 0;
|
||||
int nolink = 0;
|
||||
int romable = 0;
|
||||
int romaddr = 0;
|
||||
|
@ -210,6 +211,10 @@ int main(int argc,char *argv[])
|
|||
case 'M':
|
||||
masm = 1; /* MASM compatibility mode */
|
||||
break;
|
||||
case 'S':
|
||||
ppinstr = 1; /* preprocessor substitution in strings ok */
|
||||
fprintf(stderr, "Warning: -S is deprecated and will be removed in 2.4+!\n");
|
||||
break;
|
||||
case 'O': /* output charset */
|
||||
{
|
||||
char *name = NULL;
|
||||
|
@ -267,7 +272,7 @@ int main(int argc,char *argv[])
|
|||
break;
|
||||
case 'x': /* old filename behaviour */
|
||||
oldfile = 1;
|
||||
fprintf(stderr, "Warning: -x is now deprecated and may disappear in future versions!\n");
|
||||
fprintf(stderr, "Warning: -x is now deprecated and will be removed in 2.4+!\n");
|
||||
break;
|
||||
case 'I':
|
||||
if(argv[i][2]==0) {
|
||||
|
@ -392,6 +397,8 @@ int main(int argc,char *argv[])
|
|||
r_mode(RMODE_RELOC);
|
||||
segment = SEG_TEXT;
|
||||
} else {
|
||||
/* prime old_segment in r_mode with SEG_TEXT */
|
||||
segment = SEG_ABS;
|
||||
r_mode(RMODE_ABS);
|
||||
}
|
||||
|
||||
|
@ -460,11 +467,13 @@ int main(int argc,char *argv[])
|
|||
|
||||
seg_pass2();
|
||||
|
||||
if(!relmode) {
|
||||
r_mode(RMODE_ABS);
|
||||
if(relmode) {
|
||||
r_mode(RMODE_RELOC);
|
||||
segment = SEG_TEXT;
|
||||
} else {
|
||||
r_mode(RMODE_RELOC);
|
||||
segment = SEG_TEXT;
|
||||
/* prime old_segment in r_mode with SEG_TEXT */
|
||||
segment = SEG_ABS;
|
||||
r_mode(RMODE_ABS);
|
||||
}
|
||||
er=pass2();
|
||||
}
|
||||
|
@ -825,8 +834,6 @@ static void usage(int default816, FILE *fp)
|
|||
programname);
|
||||
fprintf(fp,
|
||||
" -v verbose output\n"
|
||||
" -x old filename behaviour (overrides `-o', `-e', `-l')\n"
|
||||
" This is deprecated and may disappear in future versions!\n"
|
||||
" -C no CMOS-opcodes\n"
|
||||
" -W no 65816-opcodes%s\n"
|
||||
" -w allow 65816-opcodes%s\n",
|
||||
|
@ -854,11 +861,16 @@ static void usage(int default816, FILE *fp)
|
|||
" Other segments must be specified with `-b?'\n"
|
||||
" -G suppress list of exported globals\n");
|
||||
fprintf(fp,
|
||||
" -p? set preprocessor character to ?, default is #\n"
|
||||
" -DDEF=TEXT defines a preprocessor replacement\n"
|
||||
" -Ocharset set output charset (PETSCII, ASCII, etc.), case-sensitive\n"
|
||||
" -Idir add directory `dir' to include path (before XAINPUT)\n"
|
||||
" --version output version information and exit\n"
|
||||
" --help display this help and exit\n");
|
||||
fprintf(fp,
|
||||
"== These options are deprecated and will be removed in 2.4+! ==\n"
|
||||
" -x old filename behaviour (overrides `-o', `-e', `-l')\n"
|
||||
" -S allow preprocessor substitution within strings\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "xah.h" /* For SEG_MAX */
|
||||
|
||||
extern int ncmos, cmosfl, w65816, n65816;
|
||||
extern int masm, nolink;
|
||||
extern int masm, nolink, ppinstr;
|
||||
extern int noglob;
|
||||
extern int showblk;
|
||||
extern int relmode;
|
||||
|
|
21
xa/src/xap.c
21
xa/src/xap.c
|
@ -456,7 +456,25 @@ int pp_replace(char *to, char *ti, int a,int b)
|
|||
{
|
||||
while(t[0]!='\0')
|
||||
{
|
||||
while(!isalpha(t[0]) && t[0]!='_')
|
||||
/* find start of a potential token to be replaced */
|
||||
while(!isalpha(t[0]) && t[0]!='_') {
|
||||
|
||||
/* escape strings quoted with " */
|
||||
if (!ppinstr && t[0] == '\"') {
|
||||
do {
|
||||
t++;
|
||||
ti++;
|
||||
} while (t[0] && t[0]!='\"');
|
||||
}
|
||||
|
||||
/* escape strings quoted with ' */
|
||||
if (!ppinstr && t[0] == '\'') {
|
||||
do {
|
||||
t++;
|
||||
ti++;
|
||||
} while (t[0] && t[0]!='\'');
|
||||
}
|
||||
|
||||
if(t[0]=='\0')
|
||||
break; /*return(E_OK);*/
|
||||
else
|
||||
|
@ -464,6 +482,7 @@ int pp_replace(char *to, char *ti, int a,int b)
|
|||
t++;
|
||||
ti++;
|
||||
}
|
||||
}
|
||||
|
||||
for(l=0;isalnum(t[l])||t[l]=='_';l++);
|
||||
ld=l;
|
||||
|
|
61
xa/src/xat.c
61
xa/src/xat.c
|
@ -479,48 +479,44 @@ printf(" wrote %02x %02x %02x %02x %02x %02x\n",
|
|||
dsb_len = 0;
|
||||
} else
|
||||
if(n==Ktext) {
|
||||
/* if(segment!=SEG_ABS) { */
|
||||
segment = relmode ? SEG_TEXT : SEG_ABS;
|
||||
t[0]=Ksegment;
|
||||
t[1]=segment;
|
||||
*ll=2;
|
||||
er=E_OKDEF;
|
||||
/* } else {
|
||||
er=E_ILLSEGMENT;
|
||||
} */
|
||||
} else
|
||||
if(n==Kdata) {
|
||||
/* if(segment!=SEG_ABS) { */
|
||||
if(relmode) {
|
||||
segment = SEG_DATA;
|
||||
t[0]=Ksegment;
|
||||
t[1]=SEG_DATA;
|
||||
*ll=2;
|
||||
er=E_OKDEF;
|
||||
/* } else {
|
||||
} else {
|
||||
er=E_ILLSEGMENT;
|
||||
} */
|
||||
}
|
||||
} else
|
||||
if(n==Kbss) {
|
||||
/* if(segment!=SEG_ABS) { */
|
||||
if(relmode) {
|
||||
segment = SEG_BSS;
|
||||
t[0]=Ksegment;
|
||||
t[1]=SEG_BSS;
|
||||
*ll=2;
|
||||
er=E_OKDEF;
|
||||
/* } else {
|
||||
} else {
|
||||
er=E_ILLSEGMENT;
|
||||
} */
|
||||
}
|
||||
} else
|
||||
if(n==Kzero) {
|
||||
/* if(segment!=SEG_ABS) { */
|
||||
if(relmode) {
|
||||
segment = SEG_ZERO;
|
||||
t[0]=Ksegment;
|
||||
t[1]=SEG_ZERO;
|
||||
*ll=2;
|
||||
er=E_OKDEF;
|
||||
/* } else {
|
||||
} else {
|
||||
er=E_ILLSEGMENT;
|
||||
} */
|
||||
}
|
||||
} else
|
||||
if (n==Kbin) {
|
||||
int j;
|
||||
|
@ -704,8 +700,14 @@ fprintf(stderr, "E_NODEF pass1 xat.c\n");
|
|||
} else
|
||||
sy=4+nk; /* absolute or zero page */
|
||||
|
||||
/* length counter set to maximum length + 1 */
|
||||
bl=Maxbyt+1;
|
||||
/* length counter set to maximum length + 1 */
|
||||
if (w65816 || (t[l-1]=='@' || t[l-1] == '!')) {
|
||||
/* for 65816 allow addressing modes up to 4 byte overall length */
|
||||
bl=Maxbyt+1;
|
||||
} else {
|
||||
/* for other modes only check for addressing modes up to 3 byte overall length */
|
||||
bl=Maxbyt;
|
||||
}
|
||||
|
||||
/* find best fit for length of this operand */
|
||||
while(--bl)
|
||||
|
@ -1377,9 +1379,19 @@ fprintf(stderr, "Kdsb E_DSB %i\n", j);
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bl=Maxbyt+1;
|
||||
|
||||
/* set bl to maximum overall length +1 as while() below starts with decrementing it */
|
||||
if (w65816 || (t[*ll-1]=='@' || t[*ll-1] == '!')) {
|
||||
/* for 65816 allow addressing modes up to 4 byte overall length */
|
||||
bl=Maxbyt+1;
|
||||
} else {
|
||||
/* for other modes only check for addressing modes up to 3 byte overall length */
|
||||
bl=Maxbyt;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_AM
|
||||
printf("--- trying to find am using: (max+1) bl=%d, sy=%d\n", bl, sy);
|
||||
#endif
|
||||
while(--bl)
|
||||
{
|
||||
if((am=at[sy][bl-1])>=0)
|
||||
|
@ -1417,8 +1429,8 @@ fprintf(stderr, "Kdsb E_DSB %i\n", j);
|
|||
{
|
||||
#ifdef DEBUG_AM
|
||||
fprintf(stderr,
|
||||
"b4: pc= %d, am = %d and vv[0] = %d, optimize = %d, bitmask = %d\n",
|
||||
pc[segment], am, vv[0], fl, (vv[0]&0xffff00));
|
||||
"b4: pc= %d, am = %d and vv[0] = %d, optimize = %d, bitmask = %u, er=%d\n",
|
||||
pc[segment], am, vv[0], fl, (vv[0]&0xffff00), er);
|
||||
#endif
|
||||
|
||||
/* terrible KLUDGE!!!! OH NOES!!!1!
|
||||
|
@ -1457,15 +1469,21 @@ fprintf(stderr,
|
|||
else
|
||||
{
|
||||
bl=le[am];
|
||||
if ((am != 11 && am != 16) && (vv[0] > 255 || vv[0] < -256) && bl == 2) {
|
||||
er = E_OVERFLOW;
|
||||
} else
|
||||
if ((am != 11 && am != 16) && (vv[0] > 65535 || vv[0] < -65536) && (bl == 2 || bl == 3)) {
|
||||
er = E_OVERFLOW;
|
||||
} else
|
||||
if( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode)) {
|
||||
bl++;
|
||||
}
|
||||
}
|
||||
*ll=bl;
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_AM
|
||||
fprintf(stderr, "byte length is now %d\n", bl);
|
||||
fprintf(stderr, "byte length is now %d, am=%d, er=%d\n", bl, am, er);
|
||||
#endif
|
||||
|
||||
if(!er)
|
||||
|
@ -1514,6 +1532,7 @@ fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]);
|
|||
}
|
||||
} else
|
||||
if(am==11 || am==16) {
|
||||
/* relative, relative long */
|
||||
if((segment!=SEG_ABS) && (!rlt[0])) {
|
||||
er=E_ILLPOINTER;
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,8 @@ adrm/ Addressing mode test (especially the optimizer and quantity
|
|||
prefixes)
|
||||
nonl/ Patryk's no-new-line-on-last-line cases ;)
|
||||
fordef/ Optimizer warnings for forward defined labels
|
||||
relocmode/ Tests to prevent use of irrational segments if relocating
|
||||
mde isn't on
|
||||
relocundef/ Tests for the detection of undefined references during a
|
||||
reloc65 export
|
||||
ldoreloc/ Test case for the relocation table reading of ldo when undef'd
|
||||
|
@ -27,6 +29,8 @@ cpp/ Random preprocessor tests, mostly crap
|
|||
incerr/ 1) .xl/.al should error without -w 2) error should be in
|
||||
the correct file ('816)
|
||||
binclude/ Binary include code with some weird casing
|
||||
ppstrings/ Don't substitute inside strings (unless -S)
|
||||
neg_offset/ Test handling of negative offsets with/without relocation
|
||||
chppch/ Changing preprocessor characters (-p)
|
||||
charset/ Tests of when charsets should be honoured and when not
|
||||
mvnmvp/ Test MVN MVP unusual addressing mode ('816)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
default: test1 test2 test3 test4 test5 test6 test7 test8
|
||||
|
||||
test1:
|
||||
../../xa -R -LLIB6502 test1.s -o test1.o
|
||||
../hextool -cmp=ok1 < test1.o
|
||||
|
||||
test2:
|
||||
../../xa -R -LLIB6502 test2.s -o test2.o
|
||||
../hextool -cmp=ok2 < test2.o
|
||||
|
||||
test3:
|
||||
../../xa -R -LLIB6502 test3.s -o test3.o
|
||||
../hextool -cmp=ok3 < test3.o
|
||||
|
||||
test4:
|
||||
../../xa -R -LLIB6502 test4.s -o test4.o
|
||||
../hextool -cmp=ok4 < test4.o
|
||||
|
||||
test5:
|
||||
../../xa -R -LLIB6502 test5.s -o test5.o
|
||||
../hextool -cmp=ok5 < test5.o
|
||||
|
||||
test6:
|
||||
# this test must fail.
|
||||
../../xa -R -LLIB6502 test6.s -o test6.o || exit 0 && exit 1
|
||||
|
||||
test7:
|
||||
# this test must fail.
|
||||
../../xa -R -LLIB6502 test7.s -o test7.o || exit 0 && exit 1
|
||||
|
||||
test8:
|
||||
# this test must fail.
|
||||
../../xa -R -LLIB6502 test8.s -o test8.o || exit 0 && exit 1
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr LIB6502-3
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#define flib2osa_r LIB6502-3
|
||||
|
||||
.text
|
||||
|
||||
jsr flib2osa_r
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr LIB6502-255
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr LIB6502+256
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr LIB6502-256
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr LIB6502-65537
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr 65536
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.text
|
||||
|
||||
jsr LIB6502+65536
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,15 @@
|
|||
|
||||
#define DUP 123
|
||||
|
||||
.asc "DUP^@"
|
||||
|
||||
.asc '0DUP^@'
|
||||
|
||||
.asc "D","UP^@"
|
||||
|
||||
.asc "DUP
|
||||
|
||||
.asc "DU0
|
||||
|
||||
.asc "DU
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
default: test1
|
||||
|
||||
test1:
|
||||
# this should fail in non-relocating mode
|
||||
../../xa test1.s -o test1.o || exit 0 && exit 1
|
||||
../../xa -R test1.s -o test1.o
|
||||
../hextool -cmp=ok < test1.o
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
|
||||
lda foo
|
||||
|
||||
.data
|
||||
|
||||
foo .byt $aa
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
default: test1
|
||||
|
||||
test1:
|
||||
../../xa -R -LLIB6502 test1.s -o test1.o
|
||||
../hextool -cmp=ok1 < test1.o
|
||||
../../xa -R test2.s -o test2.o
|
||||
../hextool -cmp=ok2 < test2.o
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,12 @@
|
|||
|
||||
; forward reference
|
||||
; results in illegal ptr arithmetic when segment
|
||||
; is not reset between pass1 and pass2
|
||||
|
||||
bne foo
|
||||
foo
|
||||
|
||||
.data
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
; test absolute code embedded into relocatable mode
|
||||
|
||||
.text
|
||||
|
||||
lda foo
|
||||
lda bar
|
||||
|
||||
; go into absolute mode
|
||||
*=$1234
|
||||
|
||||
foo .asc "absolute",0
|
||||
|
||||
lda foo
|
||||
lda bar
|
||||
|
||||
; go back into relocatble mode
|
||||
*=
|
||||
|
||||
bar .asc "reloc",0
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue