mirror of
https://github.com/fachat/xa65.git
synced 2024-12-26 19:29:23 +00:00
2.4.1b1
This commit is contained in:
parent
e95549dfd1
commit
25761ea06d
@ -1,12 +1,11 @@
|
||||
# Unix gcc or DOS go32 cross-compiling gcc
|
||||
#
|
||||
VERS = 2.4.0
|
||||
VERS = 2.4.1
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
# for testing. not to be used; build failures in misc/.
|
||||
#CFLAGS = -O2 -W -Wall -pedantic -ansi
|
||||
#CFLAGS = -O2 -g
|
||||
CFLAGS = -O2
|
||||
#CFLAGS = -O2 -W -Wall -pedantic -ansi -g
|
||||
CFLAGS = -O2 -g
|
||||
LDFLAGS = -lc
|
||||
|
||||
# for DOS?
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH FILE65 "1" "18 November 2023"
|
||||
.TH FILE65 "1" "12 January 2024"
|
||||
|
||||
.SH NAME
|
||||
file65 \- print information for o65 object files
|
||||
@ -44,7 +44,6 @@ Show version of program.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR ldo65 (1),
|
||||
.BR printcbm (1),
|
||||
.BR reloc65 (1),
|
||||
.BR uncpk (1),
|
||||
.BR xa (1),
|
||||
@ -54,7 +53,7 @@ Show version of program.
|
||||
This manual page was written by David Weinehall <tao@acc.umu.se>
|
||||
and Cameron Kaiser <ckaiser@floodgap.com>.
|
||||
Original xa package (C)1989-1997 Andre Fachat. Additional changes
|
||||
(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
(C)1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
Cameron Kaiser. The current maintainer is Cameron Kaiser.
|
||||
|
||||
.SH WEBSITE
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH LDO65 "1" "18 November 2023"
|
||||
.TH LDO65 "1" "12 January 2024"
|
||||
|
||||
.SH NAME
|
||||
ldo65 \- linker for o65 object files
|
||||
@ -57,7 +57,6 @@ Show version of program.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR file65 (1),
|
||||
.BR printcbm (1),
|
||||
.BR reloc65 (1),
|
||||
.BR uncpk (1),
|
||||
.BR dxa (1),
|
||||
@ -67,7 +66,7 @@ Show version of program.
|
||||
This manual page was written by David Weinehall <tao@acc.umu.se>
|
||||
and Cameron Kaiser <ckaiser@floodgap.com>.
|
||||
Original xa package (C)1989-1997 Andre Fachat. Additional changes
|
||||
(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
(C)1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
Cameron Kaiser. The current maintainer is Cameron Kaiser.
|
||||
|
||||
.SH WEBSITE
|
||||
|
@ -40,7 +40,7 @@ Show version of program.
|
||||
.SH AUTHOR
|
||||
This manual page was written by David Weinehall <tao@acc.umu.se>.
|
||||
Original xa package (C)1989-1997 Andre Fachat. Additional changes
|
||||
(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
(C)1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
Cameron Kaiser. The current maintainer is Cameron Kaiser.
|
||||
|
||||
.SH WEBSITE
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH RELOC65 "1" "18 November 2023"
|
||||
.TH RELOC65 "1" "12 January 2024"
|
||||
|
||||
.SH NAME
|
||||
reloc65 \- relocator for o65 object files
|
||||
@ -47,6 +47,43 @@ file. Relocating data segment to the end of the text segment and
|
||||
bss segment to the end of the data segment
|
||||
(\-xd and \-xb options override the derived address) before extracting.
|
||||
.TP
|
||||
.B \-C cputype
|
||||
Define a new CPU type for the output file. Available values are:
|
||||
.IP
|
||||
.B 6502
|
||||
- documented 6502 opcodes only
|
||||
.IP
|
||||
.B NMOS6502
|
||||
-
|
||||
.B 6502
|
||||
plus undocumented opcodes
|
||||
.IP
|
||||
.B 65SC02
|
||||
- extends
|
||||
.B 6502
|
||||
with CMOS opcodes, except for
|
||||
.BR BBR / BBS / SMB
|
||||
and
|
||||
.B RMB
|
||||
.IP
|
||||
.B 65C02
|
||||
- extends
|
||||
.B 65SC02
|
||||
with the
|
||||
.BR BBR / BBS / SMB
|
||||
and
|
||||
.B RMB
|
||||
opcodes
|
||||
.IP
|
||||
.B 65CE02
|
||||
- extends
|
||||
.B 65C02
|
||||
with additional CE-specific opcodes
|
||||
.IP
|
||||
.B 65816
|
||||
- 65816 in 6502 emulation mode; extends
|
||||
.B 65SC02
|
||||
.TP
|
||||
.B \-\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
@ -56,7 +93,6 @@ Show version of program.
|
||||
.SH "SEE ALSO"
|
||||
.BR file65 (1),
|
||||
.BR ldo65 (1),
|
||||
.BR printcbm (1),
|
||||
.BR uncpk (1),
|
||||
.BR dxa (1),
|
||||
.BR xa (1)
|
||||
@ -65,7 +101,7 @@ Show version of program.
|
||||
This manual page was written by David Weinehall <tao@acc.umu.se>
|
||||
and Cameron Kaiser <ckaiser@floodgap.com>.
|
||||
Original xa package (C)1989-1997 Andre Fachat. Additional changes
|
||||
(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
(C)1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
Cameron Kaiser. The current maintainer is Cameron Kaiser.
|
||||
|
||||
.SH WEBSITE
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH UNCPK "1" "18 November 2023"
|
||||
.TH UNCPK "1" "12 January 2024"
|
||||
|
||||
.SH NAME
|
||||
uncpk \- manage c64 cpk archives
|
||||
@ -61,7 +61,6 @@ List contents of archive
|
||||
.SH "SEE ALSO"
|
||||
.BR file65 (1),
|
||||
.BR ldo65 (1),
|
||||
.BR printcbm (1),
|
||||
.BR reloc65 (1),
|
||||
.BR dxa (1),
|
||||
.BR xa (1)
|
||||
@ -70,7 +69,7 @@ List contents of archive
|
||||
This manual page was written by David Weinehall <tao@acc.umu.se>
|
||||
and Cameron Kaiser <ckaiser@floodgap.com>.
|
||||
Original xa package (C)1989-1997 Andre Fachat. Additional changes
|
||||
(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
(C)1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall and
|
||||
Cameron Kaiser. The current maintainer is Cameron Kaiser.
|
||||
|
||||
.SH WEBSITE
|
||||
|
37
xa/man/xa.1
37
xa/man/xa.1
@ -1,4 +1,4 @@
|
||||
.TH XA "1" "18 November 2023"
|
||||
.TH XA "1" "12 January 2024"
|
||||
|
||||
.SH NAME
|
||||
xa \- 6502/R65C02/65816 cross-assembler
|
||||
@ -124,6 +124,14 @@ allows nested multi-line comments, and disables all predefined
|
||||
preprocessor macros. This option is inherently deprecated and may be removed
|
||||
in the next 2.x or 3.x release.
|
||||
.TP
|
||||
.B \-a
|
||||
Support
|
||||
.BR ca65 (1)-style
|
||||
unnamed labels using colons, but not the remainder of the other supported
|
||||
.BR ca65 (1)
|
||||
features. This allows their use with 65816 mode, for example. Implies
|
||||
.BR -XMASM .
|
||||
.TP
|
||||
.B \-M
|
||||
This option is deprecated and will be removed in a future version; use
|
||||
.B \-XMASM
|
||||
@ -131,6 +139,14 @@ instead. Allows colons to appear in comments for MASM compatibility. This does
|
||||
not affect colon interpretation elsewhere, and may become the default in a
|
||||
future version.
|
||||
.TP
|
||||
.B \-k
|
||||
Allow the carat
|
||||
.RB ( ^ )
|
||||
to mask a character with $1f/31. This can be used as a shorthand for
|
||||
control characters, such as
|
||||
.B "^m^j"
|
||||
becoming a carriage return followed by a linefeed.
|
||||
.TP
|
||||
.B \-R
|
||||
Start assembler in relocating mode, i.e. use segments.
|
||||
.TP
|
||||
@ -323,14 +339,14 @@ and
|
||||
.LP
|
||||
If
|
||||
.B \-XCA65
|
||||
is specified, "cheap" local labels may be used, marked by the
|
||||
.B @
|
||||
prefix. Additionally, unnamed labels may be specified with
|
||||
or
|
||||
.B \-a
|
||||
is specified, "unnamed" labels may be specified with
|
||||
.B :
|
||||
(i.e., no label, just a colon); branches may then reference these unnamed
|
||||
labels with a colon and plus signs for forward branching or minus signs
|
||||
for backward branching. For example (from the
|
||||
.B ca65
|
||||
.BR ca65 (1)
|
||||
documentation),
|
||||
.LP
|
||||
: lda (ptr1),y ; #1
|
||||
@ -367,6 +383,14 @@ documentation),
|
||||
.BR
|
||||
: rts ; #4
|
||||
.LP
|
||||
Additionally, in
|
||||
.B \-XCA65
|
||||
mode, "cheap" local labels may be used, marked by the
|
||||
.B @
|
||||
prefix. These temporary labels exist only between two regular labels and
|
||||
automatically go out of scope with the next regular label. This allows,
|
||||
with reasonable care, reuse of common label names like "loop."
|
||||
.LP
|
||||
For those instructions where the accumulator is the implied argument (such as
|
||||
.B asl
|
||||
and
|
||||
@ -1175,7 +1199,6 @@ indexed, branching and so on.
|
||||
.SH "SEE ALSO"
|
||||
.BR file65 (1),
|
||||
.BR ldo65 (1),
|
||||
.BR printcbm (1),
|
||||
.BR reloc65 (1),
|
||||
.BR uncpk (1),
|
||||
.BR dxa (1)
|
||||
@ -1185,7 +1208,7 @@ This manual page was written by David Weinehall <tao@acc.umu.se>,
|
||||
Andre Fachat <fachat@web.de>
|
||||
and Cameron Kaiser <ckaiser@floodgap.com>.
|
||||
Original xa package (C)1989-1997 Andre Fachat. Additional changes
|
||||
(C)1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall,
|
||||
(C)1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall,
|
||||
Cameron Kaiser. The official maintainer is Cameron Kaiser.
|
||||
|
||||
.SH OVER 30 YEARS OF XA
|
||||
|
@ -37,6 +37,36 @@
|
||||
#define author "Written by Andre Fachat"
|
||||
#define copyright "Copyright (C) 1997-2002 Andre Fachat."
|
||||
|
||||
/* o65 file format mode bits */
|
||||
#define FM_OBJ 0x1000
|
||||
#define FM_SIZE 0x2000
|
||||
#define FM_RELOC 0x4000
|
||||
#define FM_CPU 0x8000
|
||||
|
||||
#define FM_CPU2 0x00f0
|
||||
|
||||
#define FM_CPU2_6502 0x0000
|
||||
#define FM_CPU2_65C02 0x0010
|
||||
#define FM_CPU2_65SC02 0x0020
|
||||
#define FM_CPU2_65CE02 0x0030
|
||||
#define FM_CPU2_NMOS 0x0040
|
||||
#define FM_CPU2_65816E 0x0050
|
||||
|
||||
const char *cpunames[16] = {
|
||||
"6502",
|
||||
"65C02",
|
||||
"65SC02",
|
||||
"65CE02",
|
||||
"NMOS6502",
|
||||
"65816",
|
||||
NULL, NULL,
|
||||
"6809", NULL, // 1000 -
|
||||
"Z80", NULL, NULL, // 1010 -
|
||||
"8086", // 1101 -
|
||||
"80286", // 1110 -
|
||||
NULL
|
||||
};
|
||||
|
||||
int read_options(FILE *fp);
|
||||
int print_labels(FILE *fp, int offset);
|
||||
|
||||
@ -81,7 +111,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
i = 1;
|
||||
|
||||
if (strstr(argv[i], "--help") || strstr(argv[i], "-?")) {
|
||||
if (strstr(argv[i], "--help") || strstr(argv[i], "-?") || strstr(argv[i], "-h")) {
|
||||
usage(stdout);
|
||||
exit(0);
|
||||
}
|
||||
@ -114,7 +144,7 @@ int main(int argc, char *argv[]) {
|
||||
xapar = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"%s: %s unknown option\n",programname,argv[i]);
|
||||
fprintf(stderr,"%s: %s unknown option, use '-h' for help\n",programname,argv[i]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -127,11 +157,12 @@ int main(int argc, char *argv[]) {
|
||||
printf("%s: o65 version %d %s file\n", argv[i], hdr[5],
|
||||
hdr[7]&0x10 ? "object" : "executable");
|
||||
printf(" mode: %04x =",mode );
|
||||
printf("%s%s%s%s%s\n",
|
||||
(mode & 0x1000)?"[object]":"[executable]",
|
||||
(mode & 0x2000)?"[32bit]":"[16bit]",
|
||||
(mode & 0x4000)?"[page relocation]":"[byte relocation]",
|
||||
(mode & 0x8000)?"[CPU 65816]":"[CPU 6502]",
|
||||
printf("[%s][%sbit][%s relocation][CPU %s][CPU2 %s]%s\n",
|
||||
(mode & 0x1000)?"object":"executable",
|
||||
(mode & 0x2000)?"32":"16",
|
||||
(mode & 0x4000)?"page":"byte",
|
||||
(mode & 0x8000)?"65816":"6502",
|
||||
cpunames[(mode & FM_CPU2) >> 4],
|
||||
aligntxt[mode & 3]);
|
||||
}
|
||||
if(mode & 0x2000) {
|
||||
|
338
xa/misc/ldo65.c
338
xa/misc/ldo65.c
@ -54,6 +54,22 @@ The process of linking works as follows:
|
||||
|
||||
*/
|
||||
|
||||
/* o65 file format mode bits */
|
||||
#define FM_OBJ 0x1000
|
||||
#define FM_SIZE 0x2000
|
||||
#define FM_RELOC 0x4000
|
||||
#define FM_CPU 0x8000
|
||||
|
||||
#define FM_CPU2 0x00f0
|
||||
|
||||
#define FM_CPU2_6502 0x0000
|
||||
#define FM_CPU2_65C02 0x0010
|
||||
#define FM_CPU2_65SC02 0x0020
|
||||
#define FM_CPU2_65CE02 0x0030
|
||||
#define FM_CPU2_NMOS 0x0040
|
||||
#define FM_CPU2_65816E 0x0050
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int len;
|
||||
@ -67,12 +83,21 @@ typedef struct {
|
||||
size_t fsize; /* length of file */
|
||||
unsigned char *buf; /* file content */
|
||||
|
||||
int mode; /* mode value */
|
||||
int align; /* align value */
|
||||
|
||||
int tbase; /* header: text base */
|
||||
int tlen; /* text length */
|
||||
int talign; /* insert to get correct alignment */
|
||||
|
||||
int dbase; /* data base */
|
||||
int dlen; /* data length */
|
||||
int dalign; /* insert to get correct alignment */
|
||||
|
||||
int bbase; /* bss base */
|
||||
int blen; /* bss length */
|
||||
int balign; /* insert to get correct alignment */
|
||||
|
||||
int zbase; /* zero base */
|
||||
int zlen; /* zero length */
|
||||
|
||||
@ -124,6 +149,21 @@ file65 file;
|
||||
unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
|
||||
unsigned char hdr[26] = { 1, 0, 'o', '6', '5', 0 };
|
||||
|
||||
const char *cpunames[16] = {
|
||||
"documented 6502",
|
||||
"65C02 (CMOS with BBR/BBS/RMB/SMB)",
|
||||
"65SC02 (CMOS without BBR/BBS/RMB/SMB)",
|
||||
"65CE02",
|
||||
"6502 with undocumented opcodes",
|
||||
"65816 in 6502 emulation mode",
|
||||
"n/a", "n/a",
|
||||
"6809?", "n/a", // 1000 -
|
||||
"Z80?", "n/a", "n/a", // 1010 -
|
||||
"8086?", // 1101 -
|
||||
"80286?", // 1110 -
|
||||
"n/a"
|
||||
};
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
void usage(FILE *fp)
|
||||
@ -150,6 +190,7 @@ int main(int argc, char *argv[]) {
|
||||
int noglob=0;
|
||||
int undefok=0;
|
||||
int i = 1;
|
||||
// default output segment addresses, overwritten by cmdline params
|
||||
int tbase = 0x0400, dbase = 0x1000, bbase = 0x4000, zbase = 0x0002;
|
||||
int ttlen, tdlen, tblen, tzlen, routtlen, routdlen, tro, dro;
|
||||
int lasttaddr, lastdaddr;
|
||||
@ -158,8 +199,11 @@ int main(int argc, char *argv[]) {
|
||||
int j, jm;
|
||||
file65 *file, **fp = NULL;
|
||||
FILE *fd;
|
||||
int nundef = 0; // counter/index in list of remaining undef'd labels
|
||||
|
||||
int nundef = 0; // counter/index in list of remaining undef'd labels
|
||||
int maxalign; // maximum alignment over all files
|
||||
char *alignfname; // (first) file that requires that alignment
|
||||
int trgmode = 0; // mode for the output file
|
||||
char alignbuf[256]; // to efficiently write align fillers
|
||||
char *arg;
|
||||
|
||||
char **defined = NULL;
|
||||
@ -176,7 +220,7 @@ int main(int argc, char *argv[]) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) {
|
||||
if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) {
|
||||
usage(stdout);
|
||||
exit(0);
|
||||
}
|
||||
@ -188,6 +232,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
/* read options */
|
||||
while(i<argc && argv[i][0]=='-') {
|
||||
arg = NULL;
|
||||
/* process options */
|
||||
switch(argv[i][1]) {
|
||||
case 'v':
|
||||
@ -258,7 +303,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"file65: %s unknown option, use '-?' for help\n",argv[i]);
|
||||
fprintf(stderr,"file65: %s unknown option, use '-h for help\n",argv[i]);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
@ -282,6 +327,154 @@ int main(int argc, char *argv[]) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// compute target file mode value
|
||||
|
||||
// compute target mode and max align value
|
||||
trgmode = 0;
|
||||
maxalign = 0;
|
||||
alignfname = "<none>";
|
||||
{
|
||||
int er = 0;
|
||||
int trgcpu = 0;
|
||||
if (verbose) {
|
||||
printf("Starting CPU type calculation with mode %s (%d) ...\n",
|
||||
cpunames[trgcpu], trgcpu);
|
||||
}
|
||||
for(i=0;i<j;i++) {
|
||||
int fcpu;
|
||||
file = fp[i];
|
||||
if (file->align > maxalign) {
|
||||
maxalign = file->align;
|
||||
alignfname = file->fname;
|
||||
}
|
||||
if (file->mode & 0x8000) {
|
||||
// 65816
|
||||
trgmode |= 0x8000;
|
||||
if (trgcpu == 4) {
|
||||
fprintf(stderr, "Error: file '%s' in 65816 CPU mode is incompatible with previous NMOS undocumented opcodes CPU mode\n",
|
||||
file->fname);
|
||||
er = 1;
|
||||
}
|
||||
}
|
||||
if (file->mode & 0x0200) {
|
||||
// zero out bss
|
||||
trgmode |= 0x0200;
|
||||
}
|
||||
// CPU bits
|
||||
fcpu = (file->mode & FM_CPU2) >> 4;
|
||||
if (verbose) {
|
||||
printf("Matching file %s with CPU %s (%d) to target %s (%d) ...\n",
|
||||
file->fname, cpunames[fcpu], fcpu, cpunames[trgcpu], trgcpu);
|
||||
}
|
||||
switch (fcpu) {
|
||||
case 0x0: // bare minimum documented 6502 is just fine
|
||||
break;
|
||||
|
||||
case 0x1: // 65C02 - CMOS with BBR/BBS/RMB/SMB, incompatible with 65816
|
||||
case 0x3: // 65CE02 - CMOS with BBR/... and add'l opcodes, incompatible w/ 65816
|
||||
if (trgmode & 0x8000 || trgcpu == 5) {
|
||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) "
|
||||
"is incompatible with previous 65816 CPU mode\n",
|
||||
file->fname, fcpu, cpunames[fcpu]);
|
||||
er = 1;
|
||||
}
|
||||
// fall-through
|
||||
case 0x2: // 65SC02 - CMOS without BBR/BBS/RMB/SMB, compatible with 65816
|
||||
if (trgcpu == 4) {
|
||||
// is incompatible with nmos6502 with undocumented opcodes
|
||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) "
|
||||
"is incompatible with previous files with mode %d (%s)\n",
|
||||
file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]);
|
||||
er = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5: // 65816 in 6502 emulation mode
|
||||
if (trgcpu == 1 || trgcpu == 3) {
|
||||
// 65C02 and 65CE02 are incompatible with nmos6502 with undocumented opcodes
|
||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) is "
|
||||
"incompatible with previous files with mode %d (%s)\n",
|
||||
file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]);
|
||||
er = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4: // NMOS 6502 with undocumented opcodes
|
||||
if (trgcpu == 1 || trgcpu == 2 || trgcpu == 3 || trgcpu == 5) {
|
||||
// is incompatible with nmos6502 with undocumented opcodes
|
||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) is "
|
||||
"incompatible with previous files with mode %d (%s)\n",
|
||||
file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]);
|
||||
er = 1;
|
||||
}
|
||||
if (trgmode & 0x8000) {
|
||||
fprintf(stderr, "Error: file '%s' in mode %d (%s) is incompatible with previous 65816 CPU mode\n",
|
||||
file->fname, 4, cpunames[4]);
|
||||
er = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (fcpu > 5) {
|
||||
printf("Warning: unknown CPU mode %d (%s) detected in file %s\n",
|
||||
fcpu, cpunames[fcpu], file->fname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// setting the new mode
|
||||
switch (fcpu) {
|
||||
case 0x0: // compatible with everything, no change
|
||||
break;
|
||||
case 0x3: // 65CE02 -> supersedes 6502, 65SC02, and 65C02
|
||||
if (trgcpu == 1) {
|
||||
// 65C02
|
||||
trgcpu = fcpu;
|
||||
}
|
||||
// fall-through
|
||||
case 0x5: // 65816 in 6502 emu mode, supersedes documented NMOS and 65SC02
|
||||
case 0x1: // CMOS w/ BBR.. -> supersedes documented NMOS and 65SC02
|
||||
if (trgcpu == 2) {
|
||||
// 65SC02
|
||||
trgcpu = fcpu;
|
||||
}
|
||||
// fall-through
|
||||
case 0x2: // 65SC02 -> supersedes only NMOS 6502
|
||||
case 0x4: // NMOS 6502 w/ undocumented opcodes
|
||||
default:
|
||||
if (trgcpu == 0) {
|
||||
// NMOS 6502
|
||||
trgcpu = fcpu;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (verbose && !er) {
|
||||
printf("... to new target %s (%d)\n",
|
||||
cpunames[trgcpu], trgcpu);
|
||||
}
|
||||
}
|
||||
if (er) {
|
||||
exit(1);
|
||||
}
|
||||
trgmode |= trgcpu << 4;
|
||||
}
|
||||
if (maxalign) {
|
||||
printf("Info: Alignment at %d-boundaries required\n", maxalign + 1);
|
||||
}
|
||||
switch (maxalign) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
trgmode |= 1;
|
||||
break;
|
||||
case 3:
|
||||
trgmode |= 2;
|
||||
break;
|
||||
case 255:
|
||||
trgmode |= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// step 2 - calculate new segment base addresses per file, by
|
||||
// concatenating the segments per type
|
||||
@ -290,10 +483,64 @@ int main(int argc, char *argv[]) {
|
||||
/* set total length to zero */
|
||||
ttlen = tdlen = tblen = tzlen = 0;
|
||||
|
||||
|
||||
// then check start addresses
|
||||
file = fp[0];
|
||||
if (file->align != 0) {
|
||||
int er = 0;
|
||||
if (tbase & file->align) {
|
||||
fprintf(stderr, "Error: text segment start address ($%04x) "
|
||||
"not aligned as required by first file (at %d bytes)\n",
|
||||
tbase, file->align + 1);
|
||||
er = 1;
|
||||
}
|
||||
if (dbase & file->align) {
|
||||
fprintf(stderr, "Error: data segment start address ($%04x) "
|
||||
"not aligned as required by first file (at %d bytes)\n",
|
||||
dbase, file->align + 1);
|
||||
er = 1;
|
||||
}
|
||||
if (bbase & file->align) {
|
||||
fprintf(stderr, "Error: bss segment start address ($%04x) "
|
||||
"not aligned as required (by first file at %d bytes)\n",
|
||||
bbase, file->align + 1);
|
||||
er = 1;
|
||||
}
|
||||
if (er) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* find new addresses for the files and read globals */
|
||||
for(i=0;i<j;i++) {
|
||||
file = fp[i];
|
||||
|
||||
/* compute align fillers */
|
||||
file->talign = 0;
|
||||
file->dalign = 0;
|
||||
file->balign = 0;
|
||||
// filler only needed if align not zero ...
|
||||
if (file->align) {
|
||||
// ... and respective segment not empty
|
||||
if (file->tlen) {
|
||||
//file->talign = file->align + 1 - ((tbase + ttlen) & file->align);
|
||||
file->talign = ( -((tbase + ttlen) & file->align) ) & file->align;
|
||||
}
|
||||
if (file->dlen) {
|
||||
//file->dalign = file->align + 1 - ((dbase + tdlen) & file->align);
|
||||
file->dalign = ( -((dbase + tdlen) & file->align) ) & file->align;
|
||||
}
|
||||
if (file->blen) {
|
||||
//file->balign = file->align + 1 - ((bbase + tblen) & file->align);
|
||||
file->balign = ( -((bbase + tblen) & file->align) ) & file->align;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert align fillers */
|
||||
ttlen += file->talign;
|
||||
tdlen += file->dalign;
|
||||
tblen += file->balign;
|
||||
|
||||
/* compute relocation differences */
|
||||
file->tdiff = ((tbase + ttlen) - file->tbase);
|
||||
file->ddiff = ((dbase + tdlen) - file->dbase);
|
||||
@ -308,14 +555,14 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||
*/
|
||||
|
||||
if (verbose > 0) {
|
||||
printf("Relocating file: %s\n", file->fname);
|
||||
printf(" text: from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->tbase, file->tbase + file->tdiff, file->tdiff, file->tlen);
|
||||
printf(" data: from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->dbase, file->dbase + file->ddiff, file->ddiff, file->dlen);
|
||||
printf(" bss: from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->bbase, file->bbase + file->bdiff, file->bdiff, file->blen);
|
||||
printf(" zero: from %02x to %02x (diff is %02x, length is %02x)\n",
|
||||
printf("Relocating file: %s [CPU %s]\n", file->fname, cpunames[((file->mode & FM_CPU2) >> 4) & 0x0f]);
|
||||
printf(" text: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->talign, file->tbase, file->tbase + file->tdiff, file->tdiff, file->tlen);
|
||||
printf(" data: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->dalign, file->dbase, file->dbase + file->ddiff, file->ddiff, file->dlen);
|
||||
printf(" bss: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->balign, file->bbase, file->bbase + file->bdiff, file->bdiff, file->blen);
|
||||
printf(" zero: relocate from %02x to %02x (diff is %02x, length is %02x)\n",
|
||||
file->zbase, file->zbase + file->zdiff, file->zdiff, file->zlen);
|
||||
}
|
||||
|
||||
@ -326,6 +573,31 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||
tzlen += file->zlen;
|
||||
}
|
||||
|
||||
// validate various situations.
|
||||
if (maxalign != 0) {
|
||||
int er = 0;
|
||||
if (tbase & maxalign) {
|
||||
fprintf(stderr, "Error: text segment start address ($%04x) "
|
||||
"not aligned as first required by file %s (at %d bytes)\n",
|
||||
tbase, alignfname, maxalign + 1);
|
||||
er = 1;
|
||||
}
|
||||
if (dbase & maxalign) {
|
||||
fprintf(stderr, "Error: data segment start address ($%04x) "
|
||||
"not aligned as first required by file %s (at %d bytes)\n",
|
||||
dbase, alignfname, maxalign + 1);
|
||||
er = 1;
|
||||
}
|
||||
if (bbase & maxalign) {
|
||||
fprintf(stderr, "Error: bss segment start address ($%04x) "
|
||||
"not aligned as first required (by file %s (at %d bytes)\n",
|
||||
bbase, alignfname, maxalign + 1);
|
||||
er = 1;
|
||||
}
|
||||
if (er) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// validate various situations.
|
||||
{
|
||||
int er = 0;
|
||||
@ -471,7 +743,7 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||
//
|
||||
|
||||
// prepare header
|
||||
hdr[ 6] = 0; hdr[ 7] = 0;
|
||||
hdr[ 6] = trgmode & 255; hdr[ 7] = (trgmode>>8)& 255;
|
||||
hdr[ 8] = tbase & 255; hdr[ 9] = (tbase>>8) & 255;
|
||||
hdr[10] = ttlen & 255; hdr[11] = (ttlen >>8)& 255;
|
||||
hdr[12] = dbase & 255; hdr[13] = (dbase>>8) & 255;
|
||||
@ -499,13 +771,22 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||
}
|
||||
fputc(0,fd);
|
||||
|
||||
// align filler is NOP, just in case
|
||||
memset(alignbuf, 0xea, sizeof(alignbuf));
|
||||
|
||||
// write text segment
|
||||
for(i=0;i<j;i++) {
|
||||
if (fp[i]->talign) {
|
||||
fwrite(alignbuf, 1, fp[i]->talign, fd);
|
||||
}
|
||||
fwrite(fp[i]->buf + fp[i]->tpos, 1, fp[i]->tlen, fd);
|
||||
}
|
||||
|
||||
// write data segment
|
||||
for(i=0;i<j;i++) {
|
||||
if (fp[i]->dalign) {
|
||||
fwrite(alignbuf, 1, fp[i]->dalign, fd);
|
||||
}
|
||||
fwrite(fp[i]->buf + fp[i]->dpos, 1, fp[i]->dlen, fd);
|
||||
}
|
||||
|
||||
@ -732,6 +1013,7 @@ file65 *load_file(char *fname) {
|
||||
struct stat fs;
|
||||
FILE *fp;
|
||||
int mode, hlen;
|
||||
int align;
|
||||
size_t n;
|
||||
|
||||
file=malloc(sizeof(file65));
|
||||
@ -743,7 +1025,10 @@ file65 *load_file(char *fname) {
|
||||
/*printf("load_file(%s)\n",fname);*/
|
||||
|
||||
file->fname=fname;
|
||||
stat(fname, &fs);
|
||||
if(stat(fname, &fs) < 0) {
|
||||
perror("while opening file: stat");
|
||||
exit(1);
|
||||
}
|
||||
file->fsize=fs.st_size;
|
||||
file->buf=malloc(file->fsize);
|
||||
if(!file->buf) {
|
||||
@ -757,6 +1042,7 @@ file65 *load_file(char *fname) {
|
||||
fclose(fp);
|
||||
if((n>=file->fsize) && (!memcmp(file->buf, cmp, 5))) {
|
||||
mode=file->buf[7]*256+file->buf[6];
|
||||
file->mode = mode;
|
||||
if(mode & 0x2000) {
|
||||
fprintf(stderr,"file65: %s: 32 bit size not supported\n", fname);
|
||||
free(file->buf); free(file); file=NULL;
|
||||
@ -766,14 +1052,38 @@ file65 *load_file(char *fname) {
|
||||
fname);
|
||||
free(file->buf); free(file); file=NULL;
|
||||
} else {
|
||||
|
||||
align = mode & 3;
|
||||
switch(align) {
|
||||
case 0:
|
||||
align = 0;
|
||||
break;
|
||||
case 1:
|
||||
// word align
|
||||
align = 1;
|
||||
break;
|
||||
case 2:
|
||||
// long align
|
||||
align = 3;
|
||||
break;
|
||||
case 3:
|
||||
// page align
|
||||
align = 255;
|
||||
break;
|
||||
}
|
||||
file->align = align;
|
||||
|
||||
hlen = BUF+read_options(file->buf+BUF);
|
||||
|
||||
file->tbase = file->buf[ 9]*256+file->buf[ 8];
|
||||
file->tlen = file->buf[11]*256+file->buf[10];
|
||||
file->talign= 0;
|
||||
file->dbase = file->buf[13]*256+file->buf[12];
|
||||
file->dlen = file->buf[15]*256+file->buf[14];
|
||||
file->dalign= 0;
|
||||
file->bbase = file->buf[17]*256+file->buf[16];
|
||||
file->blen = file->buf[19]*256+file->buf[18];
|
||||
file->balign= 0;
|
||||
file->zbase = file->buf[21]*256+file->buf[20];
|
||||
file->zlen = file->buf[23]*256+file->buf[22];
|
||||
|
||||
|
@ -34,6 +34,21 @@
|
||||
#define author "Written by Andre Fachat"
|
||||
#define copyright "Copyright (C) 1997-2002 Andre Fachat."
|
||||
|
||||
/* o65 file format mode bits */
|
||||
#define FM_OBJ 0x1000
|
||||
#define FM_SIZE 0x2000
|
||||
#define FM_RELOC 0x4000
|
||||
#define FM_CPU 0x8000
|
||||
|
||||
#define FM_CPU2 0x00f0
|
||||
|
||||
#define FM_CPU2_6502 0x0000
|
||||
#define FM_CPU2_65C02 0x0010
|
||||
#define FM_CPU2_65SC02 0x0020
|
||||
#define FM_CPU2_65CE02 0x0030
|
||||
#define FM_CPU2_NMOS 0x0040
|
||||
#define FM_CPU2_65816E 0x0050
|
||||
|
||||
typedef struct {
|
||||
char *fname;
|
||||
size_t fsize;
|
||||
@ -74,13 +89,32 @@ void usage(FILE *fp)
|
||||
" -X extracts the file such that text and data\n"
|
||||
" segments are chained, i.e. possibly relocating\n"
|
||||
" the data segment to the end of the text segment\n"
|
||||
" -C <CPU> Set the o65 CPU flags in the output for the following CPUs:\n"
|
||||
" 6502, 65SC02, 65C02, 65CE02, 65816, NMOS6502\n"
|
||||
" (for details see the man page)\n"
|
||||
" -v verbose output\n"
|
||||
" --version output version information and exit\n"
|
||||
" --help display this help and exit\n");
|
||||
}
|
||||
|
||||
const char *cpunames[16] = {
|
||||
"6502",
|
||||
"65C02",
|
||||
"65SC02",
|
||||
"65CE02",
|
||||
"NMOS6502",
|
||||
"65816",
|
||||
NULL, NULL,
|
||||
"6809", NULL, // 1000 -
|
||||
"Z80", NULL, NULL, // 1010 -
|
||||
"8086", // 1101 -
|
||||
"80286", // 1110 -
|
||||
NULL
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i = 1, mode, hlen;
|
||||
int j;
|
||||
size_t n;
|
||||
FILE *fp;
|
||||
int tflag = 0, dflag = 0, bflag = 0, zflag = 0;
|
||||
@ -89,13 +123,15 @@ int main(int argc, char *argv[]) {
|
||||
char *outfile = "a.o65";
|
||||
int extract = 0;
|
||||
int verbose = 0;
|
||||
int trgcpu = -1; // output file target CPU flag (-1 = do not change)
|
||||
char *arg; // temporary argument pointer
|
||||
|
||||
if (argc <= 1) {
|
||||
usage(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) {
|
||||
if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) {
|
||||
usage(stdout);
|
||||
exit(0);
|
||||
}
|
||||
@ -106,6 +142,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
while(i<argc) {
|
||||
arg = NULL;
|
||||
if(argv[i][0]=='-') {
|
||||
/* process options */
|
||||
switch(argv[i][1]) {
|
||||
@ -166,8 +203,27 @@ int main(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
if(argv[i][2]) arg=argv[i]+2;
|
||||
else if(i + 1 < argc) arg=argv[++i];
|
||||
if (arg == NULL) {
|
||||
printf("Missing CPU parameter to -C - ignored\n");
|
||||
break;
|
||||
}
|
||||
for(j = 0; j < 16; j++) {
|
||||
if (cpunames[j] != NULL && !strcmp(arg, cpunames[j])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == 16) {
|
||||
printf("Unknown CPU identifier '%s' for -C - ignored\n",
|
||||
arg);
|
||||
} else {
|
||||
trgcpu = j;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"%s: %s unknown option, use '-?' for help\n",programname,argv[i]);
|
||||
fprintf(stderr,"%s: %s unknown option, use '-h' for help\n",programname,argv[i]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -177,7 +233,7 @@ int main(int argc, char *argv[]) {
|
||||
file.fsize=fs.st_size;
|
||||
file.buf=malloc(file.fsize);
|
||||
if(!file.buf) {
|
||||
fprintf(stderr,"Oops, no more memory!\n");
|
||||
fprintf(stderr,"Oops, no more memory! (%d)\n", file.fsize);
|
||||
exit(1);
|
||||
}
|
||||
printf("reloc65: read file %s -> %s\n",argv[i],outfile);
|
||||
@ -187,12 +243,26 @@ int main(int argc, char *argv[]) {
|
||||
fclose(fp);
|
||||
if((n>=file.fsize) && (!memcmp(file.buf, cmp, 5))) {
|
||||
mode=file.buf[7]*256+file.buf[6];
|
||||
if(mode & 0x2000) {
|
||||
if(mode & FM_SIZE) {
|
||||
fprintf(stderr,"reloc65: %s: 32 bit size not supported\n", argv[i]);
|
||||
} else
|
||||
if(mode & 0x4000) {
|
||||
if(mode & FM_RELOC) {
|
||||
fprintf(stderr,"reloc65: %s: pagewise relocation not supported\n", argv[i]);
|
||||
} else {
|
||||
if (trgcpu >= 0) {
|
||||
// change CPU flags
|
||||
mode &= ~FM_CPU;
|
||||
mode &= ~FM_CPU2;
|
||||
mode |= (trgcpu << 4);
|
||||
if (trgcpu == 5) {
|
||||
// this trgcpu is actually 65816 in emulation mode
|
||||
// unsure if we should do an own cmdline option
|
||||
mode |= FM_CPU; // 65816 native
|
||||
}
|
||||
}
|
||||
file.buf[6] = mode & 0xff;
|
||||
file.buf[7] = (mode >> 8) & 0xff;
|
||||
|
||||
hlen = BUF+read_options(file.buf+BUF);
|
||||
|
||||
file.tbase = file.buf[ 9]*256+file.buf[ 8];
|
||||
|
93
xa/src/xa.c
93
xa/src/xa.c
@ -58,7 +58,7 @@
|
||||
#define programname "xa"
|
||||
/* progversion now in xa.h */
|
||||
#define authors "Written by Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser"
|
||||
#define copyright "Copyright (C) 1989-2023 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser."
|
||||
#define copyright "Copyright (C) 1989-2024 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser."
|
||||
|
||||
/* exported globals */
|
||||
int ncmos, cmosfl, w65816, n65816;
|
||||
@ -66,6 +66,7 @@ int ncmos, cmosfl, w65816, n65816;
|
||||
/* compatibility flags */
|
||||
int masm = 0; /* MASM */
|
||||
int ca65 = 0; /* CA65 */
|
||||
int collab = 0; /* allow colon relative labels even without ca65 mode */
|
||||
int xa23 = 0; /* ^ and recursive comments, disable \ escape */
|
||||
int ctypes = 0; /* C compatibility, like "0xab" types */
|
||||
int nolink = 0;
|
||||
@ -74,6 +75,7 @@ int romaddr = 0;
|
||||
int noglob = 0;
|
||||
int showblk = 0;
|
||||
int crossref = 0;
|
||||
int mask = 0;
|
||||
int undefok = 0; // -R only accepts -Llabels; with -U all undef'd labels are ok in -R mode
|
||||
char altppchar;
|
||||
|
||||
@ -140,12 +142,20 @@ int main(int argc,char *argv[])
|
||||
char old_o[MAXLINE];
|
||||
|
||||
tim1=time(NULL);
|
||||
|
||||
ncmos=0;
|
||||
n65816=0;
|
||||
|
||||
// note: unfortunately we do no full distinction between 65C02 and 65816.
|
||||
// The conflict is in the column 7 and column f opcodes, where the 65C02
|
||||
// has the BBR/BBS/SMB/RMB opcodes, but the 65816 has its own.
|
||||
// Also, we potentially could support the 65SC02, which is the 65C02, but
|
||||
// without the conflicting BBR/BBS/SMB/RMB opcodes.
|
||||
// This, however, is a TODO for a later version.
|
||||
cmosfl=1;
|
||||
//fmode = FM_CPU2_65C02;
|
||||
w65816=0; /* default: 6502 only */
|
||||
|
||||
ncmos=0; // counter for CMOS opcodes used
|
||||
n65816=0; // counter for 65816-specific opcodes used
|
||||
|
||||
altppchar = '#' ; /* i.e., NO alternate char */
|
||||
|
||||
if((tmpp = strrchr(argv[0],'/'))) {
|
||||
@ -205,6 +215,15 @@ int main(int argc,char *argv[])
|
||||
while(i<argc) {
|
||||
if(argv[i][0]=='-') {
|
||||
switch(argv[i][1]) {
|
||||
case 'a':
|
||||
if (ca65) {
|
||||
collab=0; /* paranoia */
|
||||
fprintf(stderr, "Warning: -a not needed with -XCA65\n");
|
||||
} else collab=1;
|
||||
break;
|
||||
case 'k':
|
||||
mask = 1;
|
||||
break;
|
||||
case 'E':
|
||||
ner_max = 0;
|
||||
break;
|
||||
@ -218,7 +237,7 @@ int main(int argc,char *argv[])
|
||||
}
|
||||
if (argv[i][2] == '#')
|
||||
fprintf(stderr,
|
||||
"using -p# is evidence of stupidity\n");
|
||||
"using -p# is not necessary, '#' is the default\n");
|
||||
altppchar = argv[i][2];
|
||||
if (argv[i][3] != '\0')
|
||||
fprintf(stderr,
|
||||
@ -239,6 +258,10 @@ int main(int argc,char *argv[])
|
||||
if (set_compat(name) < 0) {
|
||||
fprintf(stderr, "Compatibility set '%s' unknown - ignoring! (check case?)\n", name);
|
||||
}
|
||||
if (collab && ca65) {
|
||||
collab=0;
|
||||
fprintf(stderr, "Warning: -a not needed with -XCA65\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'O': /* output charset */
|
||||
@ -299,12 +322,29 @@ int main(int argc,char *argv[])
|
||||
break;
|
||||
case 'C':
|
||||
cmosfl = 0;
|
||||
fmode &= ~FM_CPU2; // fall back to standard 6502
|
||||
// breaks existing tests (compare with pre-assembled files)
|
||||
//if (w65816) {
|
||||
// fmode |= FM_CPU2_65816E;
|
||||
//}
|
||||
break;
|
||||
case 'W':
|
||||
w65816 = 0;
|
||||
fmode &= ~FM_CPU;
|
||||
fmode &= ~FM_CPU2;
|
||||
// breaks existing tests (compare with pre-assembled files)
|
||||
//if (cmosfl) {
|
||||
// fmode |= FM_CPU2_65C02;
|
||||
//}
|
||||
break;
|
||||
case 'w':
|
||||
// note: we do not disable cmos here, as opcode tables note CMOS for
|
||||
// opcodes common to both, CMOS and 65816 as well.
|
||||
w65816 = 1;
|
||||
fmode &= ~FM_CPU2;
|
||||
// breaks existing tests (compare with pre-assembled files)
|
||||
//fmode |= FM_CPU; // 65816 bit
|
||||
//fmode |= FM_CPU2_65816E;// 6502 in 65816 emu, to manage opcode compatibility in ldo65
|
||||
break;
|
||||
case 'B':
|
||||
showblk = 1;
|
||||
@ -510,10 +550,6 @@ int main(int argc,char *argv[])
|
||||
sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align);
|
||||
logout(out);
|
||||
}
|
||||
if(zbase & (align-1)) {
|
||||
sprintf(out,"Warning: zero segment ($%04x) start address doesn't align to %d!\n", zbase, align);
|
||||
logout(out);
|
||||
}
|
||||
if (n65816>0)
|
||||
fmode |= 0x8000;
|
||||
switch(align) {
|
||||
@ -612,32 +648,6 @@ int h_length(void) {
|
||||
return 26+o_length();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* write header for relocatable output format */
|
||||
int h_write(FILE *fp, int tbase, int tlen, int dbase, int dlen,
|
||||
int bbase, int blen, int zbase, int zlen) {
|
||||
|
||||
fputc(1, fp); /* version byte */
|
||||
fputc(0, fp); /* hi address 0 -> no C64 */
|
||||
fputc("o", fp);
|
||||
fputc("6", fp);
|
||||
fputc("5", fp);
|
||||
fputc(0, fp); /* format version */
|
||||
fputw(mode, fp); /* file mode */
|
||||
fputw(tbase,fp); /* text base */
|
||||
fputw(tlen,fp); /* text length */
|
||||
fputw(dbase,fp); /* data base */
|
||||
fputw(dlen,fp); /* data length */
|
||||
fputw(bbase,fp); /* bss base */
|
||||
fputw(blen,fp); /* bss length */
|
||||
fputw(zbase,fp); /* zerop base */
|
||||
fputw(zlen,fp); /* zerop length */
|
||||
|
||||
o_write(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int setfext(char *s, char *ext)
|
||||
{
|
||||
@ -665,11 +675,6 @@ static int setfext(char *s, char *ext)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
static char *tmp;
|
||||
static unsigned long tmpz;
|
||||
static unsigned long tmpe;
|
||||
*/
|
||||
|
||||
static long ga_p1(void)
|
||||
{
|
||||
@ -932,6 +937,8 @@ static void usage(int default816, FILE *fp)
|
||||
" (deprecated: prefer -XMASM)\n"
|
||||
" -Xcompatset set compatibility flags for other assemblers, known values are:\n"
|
||||
" C, MASM, CA65, XA23 (deprecated: for better 2.3 compatibility)\n"
|
||||
" -a Allow ca65-style unnamed labels with colons, implies -XMASM\n"
|
||||
" -k Allow carat to mask character value with 31/$1f\n"
|
||||
" -R start assembler in relocating mode\n"
|
||||
" -U allow all undefined labels in relocating mode\n");
|
||||
fprintf(fp,
|
||||
@ -1169,10 +1176,12 @@ static int xa_getline(char *s)
|
||||
we have ca65 compatibility, we ignore the colon */
|
||||
// also check for ":+" and ":-"
|
||||
|
||||
if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !ca65 || comcom) {
|
||||
//#error gotta get collab into this test
|
||||
//if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !ca65 || comcom) {
|
||||
if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !(ca65 || collab) || comcom) {
|
||||
/* but otherwise we check if it is in a comment and we have
|
||||
MASM or CA65 compatibility, then we ignore the colon as well */
|
||||
if(!comcom || !(masm || ca65)) {
|
||||
if(!comcom || !(masm || ca65 || collab)) {
|
||||
/* we found a colon, so we keep the current line in memory
|
||||
but return the part before the colon, and next time the part
|
||||
after the colon, so we can parse C64 BASIC text assembler... */
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
#define progmajor "2"
|
||||
#define progminor "4"
|
||||
#define progpatch "0"
|
||||
#define progpatch "1"
|
||||
#define progversion progmajor "." progminor "." progpatch
|
||||
|
||||
extern int ncmos, cmosfl, w65816, n65816;
|
||||
extern int masm, ca65, xa23, nolink, undefok;
|
||||
extern int masm, ca65, xa23, nolink, undefok, collab, mask;
|
||||
extern int noglob;
|
||||
extern int showblk;
|
||||
extern int relmode;
|
||||
|
@ -39,4 +39,6 @@
|
||||
t[i++] = f & 255; \
|
||||
} while (0)
|
||||
|
||||
#define wval_len 5 /* number of bytes stored in wval() call */
|
||||
|
||||
#endif /* __XA65_XAD_H__ */
|
||||
|
11
xa/src/xah.h
11
xa/src/xah.h
@ -192,11 +192,22 @@ typedef struct {
|
||||
|
||||
#define A_LONG 0xc000
|
||||
|
||||
/* o65 file format mode bits */
|
||||
#define FM_OBJ 0x1000
|
||||
#define FM_SIZE 0x2000
|
||||
#define FM_RELOC 0x4000
|
||||
#define FM_CPU 0x8000
|
||||
|
||||
#define FM_CPU2 0x00f0
|
||||
|
||||
#define FM_CPU2_6502 0x0000
|
||||
#define FM_CPU2_65C02 0x0010
|
||||
#define FM_CPU2_65SC02 0x0020
|
||||
#define FM_CPU2_65CE02 0x0030
|
||||
#define FM_CPU2_NMOS 0x0040
|
||||
#define FM_CPU2_65816E 0x0050
|
||||
|
||||
/* segment definitions */
|
||||
#define SEG_ABS 0
|
||||
#define SEG_UNDEF 1
|
||||
#define SEG_TEXT 2
|
||||
|
@ -278,8 +278,8 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||
cll_clear();
|
||||
}
|
||||
|
||||
if((!isalpha(s[i])) && (s[i]!='_') && !(ca65 && ((cll_fl == UNNAMED) || isdigit(s[i])) ) ) {
|
||||
//printf("SYNTAX cll_fl=%d, i=%d, s[i]=%02x (%c)\n", cll_fl, i, s[i], s[i]);
|
||||
if((!isalpha(s[i])) && (s[i]!='_') && !((ca65 || collab) && ((cll_fl == UNNAMED) || isdigit(s[i])) ) ) {
|
||||
//printf("SYNTAX ca65=%d collab=%d cll_fl=%d, i=%d, s[i]=%02x (%c)\n", ca65, collab, cll_fl, i, s[i], s[i]);
|
||||
er=E_SYNTAX;
|
||||
} else
|
||||
{
|
||||
@ -653,7 +653,7 @@ int ll_search(char *s, int *n, xalabel_t cll_fl) /* search Label in Tab
|
||||
{
|
||||
for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
|
||||
|
||||
if (cll_fl == CHEAP) {
|
||||
if ( (j == k) && cll_fl == CHEAP) {
|
||||
if (ltp->blk == cll_getcur()) {
|
||||
er=E_OK;
|
||||
break;
|
||||
|
21
xa/src/xat.c
21
xa/src/xat.c
@ -834,12 +834,12 @@ printf("reloc: er=%d, l=%d, segment=%d, pc[%d]=%04x, pc[abs(%d)]=%04x, pc[text(%
|
||||
t[0]=Kdsb;
|
||||
i=1;
|
||||
bl=tmp=(tmp - (pc[segment] & (tmp-1))) & (tmp-1);
|
||||
wval(i,tmp, 0);
|
||||
wval(i,tmp, 0); // 5 byte
|
||||
t[i++]=',';
|
||||
tmp2= 0xea;
|
||||
wval(i,tmp2, 0); /* nop opcode */
|
||||
wval(i,tmp2, 0); /* nop opcode, another 5 byte */
|
||||
t[i++]=T_END;
|
||||
*ll=9;
|
||||
*ll=wval_len * 2 + 3; //13; //9;
|
||||
er=E_OKDEF;
|
||||
} else {
|
||||
*ll=0; /* ignore if aligned right */
|
||||
@ -1324,7 +1324,7 @@ int t_p2(signed char *t, int *ll, int fl, int *al)
|
||||
} else {
|
||||
er = E_SYNTAX;
|
||||
}
|
||||
/* get filename.
|
||||
/* get error string.
|
||||
the tokenizer can either see it as a multichar string ... */
|
||||
if (!er) {
|
||||
int k;
|
||||
@ -1344,7 +1344,7 @@ int t_p2(signed char *t, int *ll, int fl, int *al)
|
||||
have been caught by the above) */
|
||||
} else
|
||||
if(!(er=a_term(t+i,&c,&l,pc[segment],&afl,&label,1))) {
|
||||
if (!result) fprintf(stderr, "%c", c);
|
||||
if (!result) fprintf(stderr, "Assertion failed: %c", c);
|
||||
i += l;
|
||||
}
|
||||
}
|
||||
@ -1838,7 +1838,10 @@ fprintf(stderr, "Kdsb E_DSB %i\n", j);
|
||||
if(tolower(t[inp])=='s')
|
||||
sy=12;
|
||||
else
|
||||
if(tolower(t[inp])=='x')
|
||||
sy=5;
|
||||
else
|
||||
er=E_SYNTAX;
|
||||
} else
|
||||
er=E_SYNTAX;
|
||||
}
|
||||
@ -1965,7 +1968,9 @@ fprintf(stderr, "byte length is now %d, am=%d, er=%d\n", bl, am, er);
|
||||
} else {
|
||||
n65816++;
|
||||
if(!w65816) {
|
||||
fprintf(stderr,"n=%d, am=%d\n", n, am);
|
||||
#ifdef DEBUG_AM
|
||||
fprintf(stderr,"not 65816 n=%d, am=%d\n", n, am);
|
||||
#endif
|
||||
er=E_65816;
|
||||
}
|
||||
}
|
||||
@ -2335,7 +2340,7 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
||||
} else
|
||||
/* maybe it's a label
|
||||
Note that for ca65 cheap local labels, we check for "@" */
|
||||
if(isalpha(s[p]) || s[p]=='_' || ((s[p]==':' || s[p]=='@') && ca65))
|
||||
if(isalpha(s[p]) || s[p]=='_' || (s[p]==':' && collab) || ((s[p]==':' || s[p]=='@') && ca65))
|
||||
{
|
||||
|
||||
int p2 = 0;
|
||||
@ -2770,7 +2775,7 @@ fprintf(stderr, "tg_asc token = %i\n", n);
|
||||
if (!n || n == Kbin || n == Kaasc) {
|
||||
t[j++]=s[i];
|
||||
/* XXX 2.4 implement option for ^ for backwards compatibility */
|
||||
} else if(ca65 || !xa23 || s[i]!='^') { /* no escape code "^" - TODO: does ca65 has an escape code */
|
||||
} else if(ca65 || (!xa23 && !mask) || s[i]!='^') { /* no escape code "^" - TODO: does ca65 has an escape code */
|
||||
t[j++]=convert_char(s[i]);
|
||||
} else { /* escape code */
|
||||
signed char payload = s[i+1];
|
||||
|
@ -44,6 +44,7 @@ relmode/ tests concerning switches between segments and absolute mode
|
||||
mvnmvp/ Test MVN MVP unusual addressing mode ('816)
|
||||
dos51/ Regression test, label scoping, "real world code"
|
||||
cpktest/ Regression test, label listing, "real world code"
|
||||
usb65/ Unusual macro and scoping, "real world code"
|
||||
listing/ Test of listing feature
|
||||
op816/ Regression test for '816 opcodes (thanks Alessandro Gatti)
|
||||
branch/ Branch range test
|
||||
|
100
xa/tests/align/Makefile
Normal file
100
xa/tests/align/Makefile
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
XA=../../xa
|
||||
|
||||
default: all
|
||||
all: t01 t02 t03 t11 t12 t13 t21 t22 t23 t31 t32 t33 t41 t42 t43
|
||||
|
||||
# BSD only has suffix rules
|
||||
|
||||
.SUFFIXES: .o65 .hex .a65
|
||||
|
||||
#%.o65: %.s
|
||||
.a65.o65:
|
||||
${XA} -R -c -o $@ $?
|
||||
|
||||
#%.hex: %.o65
|
||||
.o65.hex:
|
||||
../hextool $? > $@
|
||||
|
||||
###############################################
|
||||
# text segment correctly aligned
|
||||
|
||||
t01: t01.o65
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t02: t02.o65
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t03: t03.o65
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
###############################################
|
||||
# data segment correctly aligned
|
||||
|
||||
t11: t11.o65
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t12: t12.o65
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t13: t13.o65
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
###############################################
|
||||
# text segment incorrectly aligned
|
||||
|
||||
t21: t01.a65
|
||||
${XA} -R -c -bt 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t22: t02.a65
|
||||
${XA} -R -c -bt 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t23: t03.a65
|
||||
${XA} -R -c -bt 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
###############################################
|
||||
# text segment correctly aligned, but data segment not (even if empty)
|
||||
|
||||
t31: t01.a65
|
||||
${XA} -R -c -bd 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t32: t02.a65
|
||||
${XA} -R -c -bd 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t33: t03.a65
|
||||
${XA} -R -c -bd 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
###############################################
|
||||
# data segment incorrectly aligned
|
||||
|
||||
t41: t11.a65
|
||||
${XA} -R -c -bd 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t42: t12.a65
|
||||
${XA} -R -c -bd 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
t43: t13.a65
|
||||
${XA} -R -c -bd 1025 -o $@.o65 $? 2> $@.msg
|
||||
../hextool -cmp=$@.mok $@.msg
|
||||
../hextool -cmp=$@.ok $@.o65
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.o65 *.hex
|
||||
|
10
xa/tests/align/t01.a65
Normal file
10
xa/tests/align/t01.a65
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.text
|
||||
|
||||
tay
|
||||
|
||||
.align 2
|
||||
|
||||
tay
|
||||
|
||||
|
BIN
xa/tests/align/t01.ok
Normal file
BIN
xa/tests/align/t01.ok
Normal file
Binary file not shown.
10
xa/tests/align/t02.a65
Normal file
10
xa/tests/align/t02.a65
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.text
|
||||
|
||||
tay
|
||||
|
||||
.align 4
|
||||
|
||||
tay
|
||||
|
||||
|
BIN
xa/tests/align/t02.ok
Normal file
BIN
xa/tests/align/t02.ok
Normal file
Binary file not shown.
10
xa/tests/align/t03.a65
Normal file
10
xa/tests/align/t03.a65
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.text
|
||||
|
||||
tay
|
||||
|
||||
.align 256
|
||||
|
||||
tay
|
||||
|
||||
|
BIN
xa/tests/align/t03.ok
Normal file
BIN
xa/tests/align/t03.ok
Normal file
Binary file not shown.
10
xa/tests/align/t11.a65
Normal file
10
xa/tests/align/t11.a65
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.data
|
||||
|
||||
tay
|
||||
|
||||
.align 2
|
||||
|
||||
tay
|
||||
|
||||
|
BIN
xa/tests/align/t11.ok
Normal file
BIN
xa/tests/align/t11.ok
Normal file
Binary file not shown.
10
xa/tests/align/t12.a65
Normal file
10
xa/tests/align/t12.a65
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.data
|
||||
|
||||
tay
|
||||
|
||||
.align 4
|
||||
|
||||
tay
|
||||
|
||||
|
BIN
xa/tests/align/t12.ok
Normal file
BIN
xa/tests/align/t12.ok
Normal file
Binary file not shown.
10
xa/tests/align/t13.a65
Normal file
10
xa/tests/align/t13.a65
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.data
|
||||
|
||||
tay
|
||||
|
||||
.align 256
|
||||
|
||||
tay
|
||||
|
||||
|
BIN
xa/tests/align/t13.ok
Normal file
BIN
xa/tests/align/t13.ok
Normal file
Binary file not shown.
1
xa/tests/align/t21.mok
Normal file
1
xa/tests/align/t21.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: text segment ($0401) start address doesn't align to 2!
|
1
xa/tests/align/t21.msg
Normal file
1
xa/tests/align/t21.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: text segment ($0401) start address doesn't align to 2!
|
BIN
xa/tests/align/t21.ok
Normal file
BIN
xa/tests/align/t21.ok
Normal file
Binary file not shown.
1
xa/tests/align/t22.mok
Normal file
1
xa/tests/align/t22.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: text segment ($0401) start address doesn't align to 4!
|
1
xa/tests/align/t22.msg
Normal file
1
xa/tests/align/t22.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: text segment ($0401) start address doesn't align to 4!
|
BIN
xa/tests/align/t22.ok
Normal file
BIN
xa/tests/align/t22.ok
Normal file
Binary file not shown.
1
xa/tests/align/t23.mok
Normal file
1
xa/tests/align/t23.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: text segment ($0401) start address doesn't align to 256!
|
1
xa/tests/align/t23.msg
Normal file
1
xa/tests/align/t23.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: text segment ($0401) start address doesn't align to 256!
|
BIN
xa/tests/align/t23.ok
Normal file
BIN
xa/tests/align/t23.ok
Normal file
Binary file not shown.
1
xa/tests/align/t31.mok
Normal file
1
xa/tests/align/t31.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 2!
|
1
xa/tests/align/t31.msg
Normal file
1
xa/tests/align/t31.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 2!
|
BIN
xa/tests/align/t31.ok
Normal file
BIN
xa/tests/align/t31.ok
Normal file
Binary file not shown.
1
xa/tests/align/t32.mok
Normal file
1
xa/tests/align/t32.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 4!
|
1
xa/tests/align/t32.msg
Normal file
1
xa/tests/align/t32.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 4!
|
BIN
xa/tests/align/t32.ok
Normal file
BIN
xa/tests/align/t32.ok
Normal file
Binary file not shown.
1
xa/tests/align/t33.mok
Normal file
1
xa/tests/align/t33.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 256!
|
1
xa/tests/align/t33.msg
Normal file
1
xa/tests/align/t33.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 256!
|
BIN
xa/tests/align/t33.ok
Normal file
BIN
xa/tests/align/t33.ok
Normal file
Binary file not shown.
1
xa/tests/align/t41.mok
Normal file
1
xa/tests/align/t41.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 2!
|
1
xa/tests/align/t41.msg
Normal file
1
xa/tests/align/t41.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 2!
|
BIN
xa/tests/align/t41.ok
Normal file
BIN
xa/tests/align/t41.ok
Normal file
Binary file not shown.
1
xa/tests/align/t42.mok
Normal file
1
xa/tests/align/t42.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 4!
|
1
xa/tests/align/t42.msg
Normal file
1
xa/tests/align/t42.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 4!
|
BIN
xa/tests/align/t42.ok
Normal file
BIN
xa/tests/align/t42.ok
Normal file
Binary file not shown.
1
xa/tests/align/t43.mok
Normal file
1
xa/tests/align/t43.mok
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 256!
|
1
xa/tests/align/t43.msg
Normal file
1
xa/tests/align/t43.msg
Normal file
@ -0,0 +1 @@
|
||||
Warning: data segment ($0401) start address doesn't align to 256!
|
BIN
xa/tests/align/t43.ok
Normal file
BIN
xa/tests/align/t43.ok
Normal file
Binary file not shown.
@ -6,7 +6,7 @@ XA=../../xa
|
||||
|
||||
CA65=ca65
|
||||
LD65=ld65
|
||||
OBJS=unnamed1 unnamed2 escape2
|
||||
OBJS=unnamed1 unnamed2 escape1 escape2 lll
|
||||
|
||||
# escape1 test only relevant if xa23 mode is on
|
||||
#tests: unnamed1 unnamed2 escape1 escape2 clean
|
||||
@ -18,15 +18,23 @@ unnamed1: unnamed1.a65
|
||||
#${CA65} unnamed1.a65; ${LD65} -t none -o unnamed1.ca65 unnamed1.o; rm unnamed1.o
|
||||
${XA} -XCA65 unnamed1.a65 -o $@
|
||||
../hextool -cmp=unnamed1.ca65 < $@
|
||||
${XA} -a unnamed1.a65 -o $@
|
||||
../hextool -cmp=unnamed1.ca65 < $@
|
||||
|
||||
unnamed2: unnamed2.a65
|
||||
#${CA65} unnamed2.a65; ${LD65} -t none -o unnamed2.ca65 unnamed2.o; rm unnamed2.o
|
||||
${XA} -XCA65 unnamed2.a65 -o $@ 2>a.err || true
|
||||
../hextool -cmp=unnamed2.ca65 < $@
|
||||
${XA} -a unnamed2.a65 -o $@ 2>a.err || true
|
||||
../hextool -cmp=unnamed2.ca65 < $@
|
||||
|
||||
# add -XXA23 to actually test this
|
||||
escape1: escape1.a65
|
||||
${XA} escape1.a65 -o $@
|
||||
# shouldn't work by default
|
||||
${XA} escape1.a65 -o $@ || exit 0 && exit 1
|
||||
${XA} -XXA23 escape1.a65 -o $@
|
||||
../hextool -cmp=escape1.out < $@
|
||||
${XA} -k escape1.a65 -o $@
|
||||
../hextool -cmp=escape1.out < $@
|
||||
|
||||
escape2: escape2.a65
|
||||
@ -34,6 +42,15 @@ escape2: escape2.a65
|
||||
${XA} -XCA65 escape2.a65 -o $@ 2>a.err || true
|
||||
../hextool -cmp=escape2.ca65 < $@
|
||||
|
||||
lll: lll.a65
|
||||
# shouldn't work
|
||||
${XA} lll.a65 -o $@ || exit 0 && exit 1
|
||||
${XA} -a lll.a65 -o $@ || exit 0 && exit 1
|
||||
${XA} -w lll.a65 -o $@ || exit 0 && exit 1
|
||||
# should work
|
||||
${XA} -XCA65 lll.a65 -o $@
|
||||
../hextool -cmp=lll.out < $@
|
||||
|
||||
clean:
|
||||
rm -f *.err a.o65 $(OBJS)
|
||||
|
||||
|
@ -2,5 +2,6 @@
|
||||
*=$1000
|
||||
|
||||
lda #"^^"
|
||||
.asc "^m^j"
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
ゥ^
|
||||
ゥ^
|
||||
|
28
xa/tests/ca65/lll.a65
Normal file
28
xa/tests/ca65/lll.a65
Normal file
@ -0,0 +1,28 @@
|
||||
; As extracted from https://codebase64.org/doku.php?id=base:256_bytes_tune_player
|
||||
* = $326
|
||||
|
||||
@musicdata:
|
||||
; errs
|
||||
@Voc0start:
|
||||
.byte $00
|
||||
.byte <(@Voc0komp-@musicdata)
|
||||
; errs
|
||||
@Voc1start:
|
||||
.byte $40
|
||||
.byte <(@Voc1melody-@musicdata)
|
||||
; errs
|
||||
@Voc2start:
|
||||
;-
|
||||
;-
|
||||
.byte $50
|
||||
@Voc2loop:
|
||||
.byte $60
|
||||
.byte <(@Voc2loop-@musicdata)
|
||||
; errs
|
||||
@Voc0komp:
|
||||
.byte $10
|
||||
.byte <(@Voc0start-@musicdata)
|
||||
@Voc1melody:
|
||||
.byte $20
|
||||
.byte <(@Voc1start-@musicdata)
|
||||
|
BIN
xa/tests/ca65/lll.out
Normal file
BIN
xa/tests/ca65/lll.out
Normal file
Binary file not shown.
14
xa/tests/cll/Makefile
Normal file
14
xa/tests/cll/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
XA=../../xa
|
||||
|
||||
all: test1.o65
|
||||
|
||||
.SUFFIXES: .a65 .o65
|
||||
|
||||
.a65.o65:
|
||||
${XA} -XCA65 -o $@ $>
|
||||
|
||||
clean:
|
||||
rm -f *.o65
|
||||
rm -f test1
|
||||
|
30
xa/tests/cll/test1.a65
Normal file
30
xa/tests/cll/test1.a65
Normal file
@ -0,0 +1,30 @@
|
||||
; As extracted from https://codebase64.org/doku.php?id=base:256_bytes_tune_player
|
||||
.org $326
|
||||
|
||||
foo:
|
||||
|
||||
@musicdata:
|
||||
; errs
|
||||
@Voc0start:
|
||||
.byte $00
|
||||
; .byte <(@Voc0komp-@musicdata)
|
||||
; errs
|
||||
@Voc1start:
|
||||
.byte $40
|
||||
.byte <(@Voc1melody-@musicdata)
|
||||
; errs
|
||||
@Voc2start:
|
||||
;-
|
||||
;-
|
||||
.byte $50
|
||||
@Voc2loop:
|
||||
.byte $60
|
||||
.byte <(@Voc2loop-@musicdata)
|
||||
; errs
|
||||
@Voc0komp:
|
||||
.byte $10
|
||||
.byte <(@Voc0start-@musicdata)
|
||||
@Voc1melody:
|
||||
.byte $20
|
||||
.byte <(@Voc1start-@musicdata)
|
||||
|
6
xa/tests/comcom/816com.asm
Normal file
6
xa/tests/comcom/816com.asm
Normal file
@ -0,0 +1,6 @@
|
||||
:
|
||||
lda @$123456
|
||||
beq :+
|
||||
bne :-
|
||||
:
|
||||
sta @$654321
|
1
xa/tests/comcom/816com.ok
Normal file
1
xa/tests/comcom/816com.ok
Normal file
@ -0,0 +1 @@
|
||||
¯V4ðÐø<C390>!Ce
|
@ -1,13 +1,21 @@
|
||||
default:
|
||||
# this should fail.
|
||||
../../xa scomcom.asm || exit 0 && exit 1
|
||||
../../xa -a 816com.asm || exit 0 && exit 1
|
||||
../../xa -w 816com.asm || exit 0 && exit 1
|
||||
# it did fail. these should now all succeed.
|
||||
../../xa -M scomcom.asm
|
||||
../../xa -XMASM scomcom.asm
|
||||
../hextool -cmp=scomcomm.ok < a.o65
|
||||
../../xa -a scomcom.asm
|
||||
../hextool -cmp=scomcomm.ok < a.o65
|
||||
../../xa comcom.asm
|
||||
../hextool -cmp=comcom.ok < a.o65
|
||||
../../xa -M comcom.asm
|
||||
../../xa -XMASM comcom.asm
|
||||
../hextool -cmp=comcomm.ok < a.o65
|
||||
../../xa -a comcom.asm
|
||||
../hextool -cmp=comcomm.ok < a.o65
|
||||
../../xa -a -w 816com.asm
|
||||
../hextool -cmp=816com.ok < a.o65
|
||||
|
||||
clean:
|
||||
rm -f a.o65
|
||||
|
@ -1,6 +1,6 @@
|
||||
default:
|
||||
# compile with masm mode on.
|
||||
../../xa -M -o test.o test.s
|
||||
../../xa -XMASM -o test.o test.s
|
||||
../hextool -cmp=okmasm < test.o
|
||||
# compile without
|
||||
../../xa -o test.o test.s
|
||||
|
149
xa/tests/mode/Makefile
Normal file
149
xa/tests/mode/Makefile
Normal file
@ -0,0 +1,149 @@
|
||||
|
||||
FILES=at1.o65 at2.o65 at4.o65 at256.o65 ad1.o65 ad2.o65 ad4.o65 ad256.o65 ab1.o65 ab2.o65 ab4.o65 ab256.o65
|
||||
|
||||
VERBOSE=
|
||||
#VERBOSE=-v
|
||||
|
||||
XA=../../xa
|
||||
LDO=../../ldo65
|
||||
RELOC=../../reloc65
|
||||
FILE=../../file65
|
||||
|
||||
all: test1.o65 test2.o65 test3.o65 test4 cpus relocsame overwrite linkup1.tmp linkup2
|
||||
|
||||
.SUFFIXES: .a65 .o65
|
||||
|
||||
.a65.o65:
|
||||
${XA} -R -o $@ $?
|
||||
|
||||
# test with files in order of increasing align
|
||||
test1.o65: ${FILES}
|
||||
${LDO} ${VERBOSE} -o $@ ${FILES}
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
# test with files in order of decreasing align
|
||||
test2.o65: ${FILES}
|
||||
${LDO} ${VERBOSE} -o $@ ab256.o65 ab4.o65 ab2.o65 ab1.o65 ad256.o65 ad4.o65 ad2.o65 ad1.o65 at256.o65 at4.o65 at2.o65 at1.o65
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
# test with files in order of increasing align, not starting at align=1
|
||||
test3.o65: ${FILES}
|
||||
${LDO} ${VERBOSE} -o $@ ab2.o65 at2.o65 ad2.o65 ab4.o65 at4.o65 ad4.o65 ad256.o65 at256.o65 ab256.o65
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
# test with files in order of increasing align, with non-aligned segment addresses
|
||||
test4: ${FILES}
|
||||
${LDO} ${VERBOSE} -bt 1025 -bd 1025 -o $@.o65 ab2.o65 at2.o65 ad2.o65 ab4.o65 at4.o65 ad4.o65 ad256.o65 at256.o65 ab256.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -bt 1026 -bd 1026 -o $@.o65 ab2.o65 at2.o65 ad2.o65 ab4.o65 at4.o65 ad4.o65 ad256.o65 at256.o65 ab256.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -bt 1027 -bd 1027 -o $@.o65 ab2.o65 at2.o65 ad2.o65 ab4.o65 at4.o65 ad4.o65 ad256.o65 at256.o65 ab256.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -bt 1028 -bd 1028 -o $@.o65 ab2.o65 at2.o65 ad2.o65 ab4.o65 at4.o65 ad4.o65 ad256.o65 at256.o65 ab256.o65 || exit 0 && exit 1
|
||||
|
||||
#c6502: at2.o65 ad4.o65
|
||||
# for i in $^; do ${RELOC} -C 6502 -o $@-$$i $$i; done
|
||||
# cmp $@-at2.o65 $@-at2.ok
|
||||
# cmp $@-ad4.o65 $@-ad4.ok
|
||||
c6502: c6502-at2.o65 c6502-ad4.o65
|
||||
c6502-at2.o65: at2.o65
|
||||
${RELOC} -C 6502 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
c6502-ad4.o65: ad4.o65
|
||||
${RELOC} -C 6502 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
#c65c02: at2.o65 ad4.o65
|
||||
# for i in $^; do ${RELOC} -C 65C02 -o $@-$$i $$i; done
|
||||
# cmp $@-at2.o65 $@-at2.ok
|
||||
# cmp $@-ad4.o65 $@-ad4.ok
|
||||
c65c02: c65c02-at2.o65 c65c02-ad4.o65
|
||||
c65c02-at2.o65: at2.o65
|
||||
${RELOC} -C 65C02 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
c65c02-ad4.o65: ad4.o65
|
||||
${RELOC} -C 65C02 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
#c65ce02: at2.o65 ad4.o65
|
||||
# for i in $^; do ${RELOC} -C 65CE02 -o $@-$$i $$i; done
|
||||
# cmp $@-at2.o65 $@-at2.ok
|
||||
# cmp $@-ad4.o65 $@-ad4.ok
|
||||
c65ce02: c65ce02-at2.o65 c65ce02-ad4.o65
|
||||
c65ce02-at2.o65: at2.o65
|
||||
${RELOC} -C 65CE02 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
c65ce02-ad4.o65: ad4.o65
|
||||
${RELOC} -C 65CE02 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
#c65sc02: at2.o65 ad4.o65
|
||||
# for i in $^; do ${RELOC} -C 65SC02 -o $@-$$i $$i; done
|
||||
# cmp $@-at2.o65 $@-at2.ok
|
||||
# cmp $@-ad4.o65 $@-ad4.ok
|
||||
c65sc02: c65sc02-at2.o65 c65sc02-ad4.o65
|
||||
c65sc02-at2.o65: at2.o65
|
||||
${RELOC} -C 65SC02 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
c65sc02-ad4.o65: ad4.o65
|
||||
${RELOC} -C 65SC02 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
#c65816: at2.o65 ad4.o65
|
||||
# for i in $^; do ${RELOC} -C 65816 -o $@-$$i $$i; done
|
||||
# cmp $@-at2.o65 $@-at2.ok
|
||||
# cmp $@-ad4.o65 $@-ad4.ok
|
||||
c65816: c65816-at2.o65 c65816-ad4.o65
|
||||
c65816-at2.o65: at2.o65
|
||||
${RELOC} -C 65816 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
c65816-ad4.o65: ad4.o65
|
||||
${RELOC} -C 65816 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
#n6502: at2.o65 ad4.o65
|
||||
# for i in $^; do ${RELOC} -C NMOS6502 -o $@-$$i $$i; done
|
||||
# cmp $@-at2.o65 $@-at2.ok
|
||||
# cmp $@-ad4.o65 $@-ad4.ok
|
||||
n6502: n6502-at2.o65 n6502-ad4.o65
|
||||
n6502-at2.o65: at2.o65
|
||||
${RELOC} -C NMOS6502 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
n6502-ad4.o65: ad4.o65
|
||||
${RELOC} -C NMOS6502 -o $@ $?
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
cpus: c65816 c6502 n6502 c65sc02 c65c02 c65ce02
|
||||
# prereq for the following
|
||||
|
||||
relocsame: cpus
|
||||
${RELOC} -o $@.o65 c65816-ad4.o65
|
||||
cmp $@.o65 c65816-ad4.o65
|
||||
${RELOC} -o $@.o65 c65sc02-at2.o65
|
||||
cmp $@.o65 c65sc02-at2.o65
|
||||
|
||||
overwrite:
|
||||
# overwrite 65816 with nmos 6502
|
||||
${RELOC} -C NMOS6502 -o $@-1.o65 c65816-at2.o65
|
||||
cmp $@-1.o65 n6502-at2.o65
|
||||
# overwrite 65sc02 with 65c02
|
||||
${RELOC} -C 65C02 -o $@-2.o65 c65sc02-ad4.o65
|
||||
cmp $@-2.o65 c65c02-ad4.o65
|
||||
|
||||
linkup1.tmp:
|
||||
${LDO} -v -o $@.tmp c6502-ad4.o65 c65c02-at2.o65 c65sc02-ad4.o65
|
||||
${FILE} $@.tmp > $@
|
||||
../hextool -cmp=$@.ok $@
|
||||
|
||||
linkup2:
|
||||
# incompatible links
|
||||
${LDO} ${VERBOSE} -o $@.o65 c6502-ad4.o65 c65c02-at2.o65 c65816-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 c6502-ad4.o65 c65ce02-at2.o65 c65816-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 c6502-ad4.o65 c65816-at2.o65 c65c02-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 c6502-ad4.o65 c65816-at2.o65 c65ce02-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 c65816-at2.o65 c65ce02-ad4.o65 c65c02-at2.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 n6502-at2.o65 c65ce02-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 n6502-at2.o65 c65c02-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 n6502-at2.o65 c65sc02-ad4.o65 || exit 0 && exit 1
|
||||
${LDO} ${VERBOSE} -o $@.o65 n6502-at2.o65 c65816-ad4.o65 || exit 0 && exit 1
|
||||
|
||||
clean:
|
||||
rm -f *.o65 *.tmp
|
||||
|
6
xa/tests/mode/ab1.a65
Normal file
6
xa/tests/mode/ab1.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 1
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ab2.a65
Normal file
6
xa/tests/mode/ab2.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 2
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ab256.a65
Normal file
6
xa/tests/mode/ab256.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 256
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ab4.a65
Normal file
6
xa/tests/mode/ab4.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 4
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ad1.a65
Normal file
6
xa/tests/mode/ad1.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 1
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ad2.a65
Normal file
6
xa/tests/mode/ad2.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 2
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ad256.a65
Normal file
6
xa/tests/mode/ad256.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 256
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
6
xa/tests/mode/ad4.a65
Normal file
6
xa/tests/mode/ad4.a65
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.align 4
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
4
xa/tests/mode/at1.a65
Normal file
4
xa/tests/mode/at1.a65
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
.align 1
|
||||
iny
|
||||
|
4
xa/tests/mode/at2.a65
Normal file
4
xa/tests/mode/at2.a65
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
.align 2
|
||||
iny
|
||||
|
4
xa/tests/mode/at256.a65
Normal file
4
xa/tests/mode/at256.a65
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
.align 256
|
||||
iny
|
||||
|
4
xa/tests/mode/at4.a65
Normal file
4
xa/tests/mode/at4.a65
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
.align 4
|
||||
iny
|
||||
|
BIN
xa/tests/mode/c6502-ad4.o65.ok
Normal file
BIN
xa/tests/mode/c6502-ad4.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c6502-at2.o65.ok
Normal file
BIN
xa/tests/mode/c6502-at2.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65816-ad4.o65.ok
Normal file
BIN
xa/tests/mode/c65816-ad4.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65816-at2.o65.ok
Normal file
BIN
xa/tests/mode/c65816-at2.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65c02-ad4.o65.ok
Normal file
BIN
xa/tests/mode/c65c02-ad4.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65c02-at2.o65.ok
Normal file
BIN
xa/tests/mode/c65c02-at2.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65ce02-ad4.o65.ok
Normal file
BIN
xa/tests/mode/c65ce02-ad4.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65ce02-at2.o65.ok
Normal file
BIN
xa/tests/mode/c65ce02-at2.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65sc02-ad4.o65.ok
Normal file
BIN
xa/tests/mode/c65sc02-ad4.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/c65sc02-at2.o65.ok
Normal file
BIN
xa/tests/mode/c65sc02-at2.o65.ok
Normal file
Binary file not shown.
7
xa/tests/mode/linkup1.tmp.ok
Normal file
7
xa/tests/mode/linkup1.tmp.ok
Normal file
@ -0,0 +1,7 @@
|
||||
linkup1.tmp.tmp: o65 version 0 executable file
|
||||
mode: 0012 =[executable][16bit][byte relocation][CPU 6502][CPU2 65C02][align 4]
|
||||
text segment @ $0400 - $0401 [$0001 bytes]
|
||||
data segment @ $1000 - $1005 [$0005 bytes]
|
||||
bss segment @ $4000 - $4000 [$0000 bytes]
|
||||
zero segment @ $0002 - $0002 [$0000 bytes]
|
||||
stack size $0000 bytes (i.e. unknown)
|
BIN
xa/tests/mode/n6502-ad4.o65.ok
Normal file
BIN
xa/tests/mode/n6502-ad4.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/n6502-at2.o65.ok
Normal file
BIN
xa/tests/mode/n6502-at2.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/test1.o65.ok
Normal file
BIN
xa/tests/mode/test1.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/test2.o65.ok
Normal file
BIN
xa/tests/mode/test2.o65.ok
Normal file
Binary file not shown.
BIN
xa/tests/mode/test3.o65.ok
Normal file
BIN
xa/tests/mode/test3.o65.ok
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user