1
0
mirror of https://github.com/fachat/xa65.git synced 2024-06-08 23:29:30 +00:00

merge v2.3.11 into listing

This commit is contained in:
Andre Fachat 2021-05-08 18:53:21 +02:00
commit 99c7b36709
46 changed files with 392 additions and 60 deletions

3
README
View File

@ -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:

View File

@ -336,6 +336,33 @@ xa-2.3.9
-- 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
xa-2.3.11
* Compilation fix for gcc 10 (thanks Dan Horak).
* Allow pointer arithmetic in relocating mode within the same segment, since
the result is segmentless (thanks Andre for the report).
* .dsb with negative quantities shouldn't work (thanks Andre for the report).
* Stop a divide-by-zero floating point exception (thanks Frederic Cambus).
* Testsuite expanded.
-- Cameron Kaiser <ckaiser@floodgap.com> 4 May 2020
xa-2.x.x
* Add -E commandline option to not stop after 20 errors, but show all

View File

@ -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.11.tar xa-2.3.11 ; gzip xa-2.3.11.tar
test: xa uncpk
cd tests && ./harness -make="$(MAKE)" -cc="$(CC)" -cflags="$(CFLAGS)"

View File

@ -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.

View File

@ -1,4 +1,4 @@
.TH XA "1" "31 January 2019"
.TH XA "1" "9 November 2019"
.SH NAME
xa \- 6502/R65C02/65816 cross-assembler
@ -24,14 +24,6 @@ Do not stop after 20 errors, but show all errors.
.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
@ -160,6 +152,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
@ -1005,6 +1014,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),

View File

@ -2,7 +2,7 @@ OBJ = xa.o xaa.o xal.o xap.o xat.o xar.o xar2.o xao.o xau.o xam.o xacharset.o xa
#CFLAGS=-W -Wall -pedantic -ansi -g
#CFLAGS=-W -Wall -ansi -O2
CFLAGS=-g -std=c99
CFLAGS=-g -std=c11 -D_GNU_SOURCE
#LD = ${CC}
#LDFLAGS = "-lc"

View File

@ -56,17 +56,18 @@
#define ANZWARN 13
#define programname "xa"
#define progversion "v2.3.9+af"
#define progversion "v2.3.11+af"
#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."
#define copyright "Copyright (C) 1989-2020 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser."
/* exported globals */
int ncmos, cmosfl, w65816, n65816;
/* compatibility flags */
int masm = 0; /* MASM */
int ca65 = 0; /* CA65 */
int ctypes = 0; /* C compatibility, like "0xab" types */
int ppinstr = 0;
int nolink = 0;
int romable = 0;
int romaddr = 0;
@ -239,6 +240,9 @@ int main(int argc,char *argv[])
fprintf(stderr, "Compatibility set '%s' unknown - ignoring! (check case?)\n", name);
}
}
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 */
{
@ -300,7 +304,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) {
@ -449,6 +453,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);
}
@ -519,11 +525,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();
@ -929,11 +937,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");
}
/*

View File

@ -22,7 +22,7 @@
#include "xah.h" /* For SEG_MAX */
extern int ncmos, cmosfl, w65816, n65816;
extern int masm, ca65, nolink,noundef;
extern int masm, ca65, nolink, noundef, ppinstr;
extern int noglob;
extern int showblk;
extern int relmode;

View File

@ -98,7 +98,9 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
afl = 0;
/*printf("ag_term(%02x %02x %02x %02x %02x %02x\n",s[0],s[1],s[2],s[3],s[4],s[5]);*/
/*
printf("ag_term(%02x %02x %02x %02x %02x %02x\n",s[0],s[1],s[2],s[3],s[4],s[5]);
*/
while(s[pp]=='-')
{
pp++;
@ -119,8 +121,10 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
if(s[pp]==T_LABEL)
{
er=l_get(cval(s+pp+1),v, &afl);
//printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
// er, segment, afl, nolink, fundef);
/*
printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
er, segment, afl, nolink, fundef);
*/
if(er==E_NODEF && segment != SEG_ABS && fundef ) {
if( (nolink && !noundef) || ((afl==SEG_UNDEF) || (afl==SEG_UNDEFZP))) {
er = E_OK;
@ -137,16 +141,22 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
if(s[pp]==T_VALUE)
{
*v=lval(s+pp+1);
pp+=5;
/* printf("value: v=%04x\n",*v); */
//pp+=5;
pp+=4;
/*
printf("value: v=%04x\n",*v);
*/
}
else
if(s[pp]==T_POINTER)
{
afl = s[pp+1];
*v=cval(s+pp+2);
pp+=6;
/* printf("pointer: v=%04x, afl=%04x\n",*v,afl); */
//pp+=6;
pp+=4;
/*
printf("pointer: v=%04x, afl=%04x\n",*v,afl);
*/
}
else
if(s[pp]=='*')
@ -180,11 +190,12 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
if((afl && !*nafl) && o==2) {
afl=(afl | *nafl); /* substract constant from pointer */
} else {
if(segment!=SEG_ABS) {
/* allow math in the same segment */
if(segment!=SEG_ABS && segment != afl) {
if(!dsb_len) {
/*printf("ILLPOINTER=dsb_len=%d,segment=%d\n",dsb_len, segment);*/
/* e.g. adding two pointers, adding two undefined values */
er=E_ILLPOINTER;
er=E_ILLSEGMENT;
}
}
afl=0;
@ -236,7 +247,7 @@ static int do_op(int *w,int w2,int o)
*w *=w2;
break;
case 4:
if (w!=0)
if (w2!=0)
*w /=w2;
else
er =E_DIV;

View File

@ -480,10 +480,12 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
printf("replace part: n=%d, sl=%d, rec=%d, %s\n", n, sl, recursive, t);
#endif
// yes, mark replacement string
char *rs=liste[n].replace;
// yes, mark replacement string
char *rs=liste[n].replace;
// does it have parameters?
// does it have parameters?
if(liste[n].p_anz)
{
// yes, we have parameters, so we need to pp_replace them

View File

@ -38,7 +38,7 @@ int gm_pp(void);
long gm_ppm(void);
long ga_ppm(void);
Datei *filep;
char s[MAXLINE];
extern Datei *filep;
extern char s[MAXLINE];
#endif /* __XA65_XAP_H__ */

View File

@ -616,48 +616,44 @@ printf(" wrote %02x %02x %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;
@ -857,9 +853,14 @@ fprintf(stderr, "E_NODEF pass1 xat.c\n");
inp++;
}
/* 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)
@ -1506,6 +1507,9 @@ fprintf(stderr, "mvn mvp: %i %i %i %i %i\n", t[0], t[i], wide, i, j);
dsb_len = 1;
if(!(er=a_term(t+1,&j,&i,pc[segment],&afl,&label,0)))
{
if (j<0)
er=E_SYNTAX;
else
/*
if(t[i+1]!=',')
er=E_SYNTAX;
@ -1713,9 +1717,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)
@ -1753,8 +1767,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!
@ -1796,15 +1810,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)
@ -1855,6 +1875,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 {

View File

@ -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 negative offsets/values with/without relocation
chppch/ Changing preprocessor characters (-p)
charset/ Tests of when charsets should be honoured and when not
ca65/ Compatibility tests for ca65 compatibility
@ -39,6 +43,8 @@ branch/ Branch range test
masmcom/ Another test for -M that generates totally valid code
quotch/ Test quoting problematic characters (thanks Simon Rowe)
linkr/ Test linking using .dsb and generated code
csapiec/ Test on pointer arithmetic in relocating mode
math/ Math tests (currently divide by zero, thanks Frederic Cambus)
Cameron Kaiser, André Fachat

12
xa/tests/csapiec/Makefile Normal file
View File

@ -0,0 +1,12 @@
default:
# xa should not allow this to happen. if it does, this test is no good.
../../xa -DBUG=1 -o test.o test.s || exit 0 && exit 1
../../xa -R -DBUG=1 -o testseg.o test.s || exit 0 && exit 1
# xa *should* allow this to happen.
../../xa -o test.o test.s
../hextool -cmp=test.ok < test.o
../../xa -R -o testseg.o test.s
../hextool -cmp=testseg.ok < testseg.o
clean:
rm -f *.o

BIN
xa/tests/csapiec/test.ok Normal file

Binary file not shown.

32
xa/tests/csapiec/test.s Normal file
View File

@ -0,0 +1,32 @@
.text
c0 =*-1
#ifdef BUG
.data
#endif
cmdt .asc "$",0
cow .asc "@",0
c2 .asc "rename",0
c3 .asc "scratch",0
c4 .asc "copy",0
c5 .asc "new",0
c6 .asc "validate",0
c7 .asc "initialize",0
;c8 .asc "rmdir",0
;c9 .asc "mkdir",0
;c10 .asc "chdir",0
c11 .asc "assign",0
c12 .asc "cd",0
c13 .asc "rd",0
c14 .asc "md",0
c15 .asc "drv",0 ; iec-bus-unit
cmda .byt cmdt-c0
.byt <c0
.byt <cow-c0
.word <cow-c0
.byt c2-c0, c3-c0, c4-c0, c5-c0, c6-c0, c7-c0 /*,c8-c0*/
.byt /*c9-c0,c10-c0,*/ c11-c0, c12-c0, c13-c0, c14-c0, c15-c0, 0

BIN
xa/tests/csapiec/testseg.ok Normal file

Binary file not shown.

7
xa/tests/math/Makefile Normal file
View File

@ -0,0 +1,7 @@
default:
# xa should not allow this to happen. if it does, this test is no good.
../../xa -o divzero.o divzero.s || exit 0 && exit 1
../../xa -o divzero2.o divzero2.s || exit 0 && exit 1
clean:
rm -f *.o

3
xa/tests/math/divzero.s Normal file
View File

@ -0,0 +1,3 @@
.word $
* = $0/00

6
xa/tests/math/divzero2.s Normal file
View File

@ -0,0 +1,6 @@
.word $
xyz = 2
zyx = xyz - xyz
* = $0/zyx

View File

@ -0,0 +1,40 @@
default: test0 test1 test2 test3 test4 test5 test6 test7 test8
test0:
# this test must fail.
../../xa -o test0.o test0.s || exit 0 && exit 1
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

BIN
xa/tests/neg_offset/a.o65 Normal file

Binary file not shown.

BIN
xa/tests/neg_offset/ok1 Normal file

Binary file not shown.

BIN
xa/tests/neg_offset/ok2 Normal file

Binary file not shown.

BIN
xa/tests/neg_offset/ok3 Normal file

Binary file not shown.

BIN
xa/tests/neg_offset/ok4 Normal file

Binary file not shown.

BIN
xa/tests/neg_offset/ok5 Normal file

Binary file not shown.

View File

@ -0,0 +1,2 @@
.dsb -10, 32

View File

@ -0,0 +1,6 @@
.text
jsr LIB6502-3

View File

@ -0,0 +1,9 @@
#define flib2osa_r LIB6502-3
.text
jsr flib2osa_r

View File

@ -0,0 +1,6 @@
.text
jsr LIB6502-255

View File

@ -0,0 +1,6 @@
.text
jsr LIB6502+256

View File

@ -0,0 +1,6 @@
.text
jsr LIB6502-256

View File

@ -0,0 +1,6 @@
.text
jsr LIB6502-65537

View File

@ -0,0 +1,6 @@
.text
jsr 65536

View File

@ -0,0 +1,6 @@
.text
jsr LIB6502+65536

BIN
xa/tests/ppstrings/ok Normal file

Binary file not shown.

15
xa/tests/ppstrings/test.s Normal file
View File

@ -0,0 +1,15 @@
#define DUP 123
.asc "DUP^@"
.asc '0DUP^@'
.asc "D","UP^@"
.asc "DUP
.asc "DU0
.asc "DU

View File

@ -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

BIN
xa/tests/relocmode/ok Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
lda foo
.data
foo .byt $aa

View File

@ -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

BIN
xa/tests/reset_segment/ok1 Normal file

Binary file not shown.

BIN
xa/tests/reset_segment/ok2 Normal file

Binary file not shown.

View File

@ -0,0 +1,12 @@
; forward reference
; results in illegal ptr arithmetic when segment
; is not reset between pass1 and pass2
bne foo
foo
.data

View File

@ -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