mirror of https://github.com/fachat/xa65.git
release 2.4.1
This commit is contained in:
parent
e95549dfd1
commit
3be092964c
17
xa/ChangeLog
17
xa/ChangeLog
|
@ -438,3 +438,20 @@ xa-2.4.0
|
|||
-- André Fachat <afachat@gmx.de> and
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com>, 18 November, 2023
|
||||
|
||||
xa 2.4.1
|
||||
|
||||
* Allow colon-based unnamed labels to be used separately of CA65 mode
|
||||
(such as with 65816) with -a. Implies -XMASM.
|
||||
* Restore ^ syntax for generating control sequences (e.g., "^m^j" evaluates
|
||||
as 0d 0a) with -k.
|
||||
* Fix a bug using cheap local labels in expressions.
|
||||
* Properly tag and match CPU types in o65 objects during relocation and
|
||||
linking.
|
||||
* Fix a bug with .align when aligning segments.
|
||||
* Better validation of arguments to indexed opcodes.
|
||||
* Testsuite expanded.
|
||||
|
||||
-- André Fachat <afachat@gmx.de> and
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com>, 5 March, 2024
|
||||
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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.4.0, the first new feature release literally in
|
||||
The current version is 2.4.1, a bug fix for 2.4.0, the first major release in
|
||||
years. It builds upon the improvements in 2.3.x and its unified 6502/65816
|
||||
assembler core by adding listing capability, greater flexibility with
|
||||
relocatable objects, and better cross-compatibility with other popular
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH FILE65 "1" "18 November 2023"
|
||||
.TH FILE65 "1" "5 March 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" "5 March 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" "5 March 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" "5 March 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
|
||||
|
|
42
xa/man/xa.1
42
xa/man/xa.1
|
@ -1,4 +1,4 @@
|
|||
.TH XA "1" "18 November 2023"
|
||||
.TH XA "1" "5 March 2024"
|
||||
|
||||
.SH NAME
|
||||
xa \- 6502/R65C02/65816 cross-assembler
|
||||
|
@ -117,13 +117,22 @@ restores partial compatibility with
|
|||
.B xa
|
||||
2.3.x. In particular, it uses
|
||||
.B ^
|
||||
for quote escapes instead of 2.4's
|
||||
for generating control characters, disables escaped characters with
|
||||
.BR \e ,
|
||||
allows nested multi-line comments, and disables all predefined
|
||||
.B xa
|
||||
preprocessor macros. This option is inherently deprecated and may be removed
|
||||
preprocessor macros. Although some portions of this option remain
|
||||
supported syntax, the option itself 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 +140,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 +340,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 +384,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 +1200,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 +1209,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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
.text
|
||||
|
||||
tay
|
||||
|
||||
.align 2
|
||||
|
||||
tay
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
|
||||
.text
|
||||
|
||||
tay
|
||||
|
||||
.align 4
|
||||
|
||||
tay
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
|
||||
.text
|
||||
|
||||
tay
|
||||
|
||||
.align 256
|
||||
|
||||
tay
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
|
||||
.data
|
||||
|
||||
tay
|
||||
|
||||
.align 2
|
||||
|
||||
tay
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
|
||||
.data
|
||||
|
||||
tay
|
||||
|
||||
.align 4
|
||||
|
||||
tay
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
|
||||
.data
|
||||
|
||||
tay
|
||||
|
||||
.align 256
|
||||
|
||||
tay
|
||||
|
||||
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: text segment ($0401) start address doesn't align to 2!
|
|
@ -0,0 +1 @@
|
|||
Warning: text segment ($0401) start address doesn't align to 2!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: text segment ($0401) start address doesn't align to 4!
|
|
@ -0,0 +1 @@
|
|||
Warning: text segment ($0401) start address doesn't align to 4!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: text segment ($0401) start address doesn't align to 256!
|
|
@ -0,0 +1 @@
|
|||
Warning: text segment ($0401) start address doesn't align to 256!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 2!
|
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 2!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 4!
|
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 4!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 256!
|
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 256!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 2!
|
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 2!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 4!
|
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 4!
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 256!
|
|
@ -0,0 +1 @@
|
|||
Warning: data segment ($0401) start address doesn't align to 256!
|
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 @@
|
|||
ゥ^
|
||||
ゥ^
|
||||
|
|
|
@ -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)
|
||||
|
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
|
||||
XA=../../xa
|
||||
|
||||
all: test1.o65
|
||||
|
||||
.SUFFIXES: .a65 .o65
|
||||
|
||||
.a65.o65:
|
||||
${XA} -XCA65 -o $@ $>
|
||||
|
||||
clean:
|
||||
rm -f *.o65
|
||||
rm -f test1
|
||||
|
|
@ -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)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
:
|
||||
lda @$123456
|
||||
beq :+
|
||||
bne :-
|
||||
:
|
||||
sta @$654321
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
../hextool -cmp=c65816-ad4.o65 $@.o65
|
||||
${RELOC} -o $@.o65 c65sc02-at2.o65
|
||||
../hextool -cmp=c65sc02-at2.o65 $@.o65
|
||||
|
||||
overwrite: cpus
|
||||
# overwrite 65816 with nmos 6502
|
||||
${RELOC} -C NMOS6502 -o $@-1.o65 c65816-at2.o65
|
||||
../hextool -cmp=n6502-at2.o65 $@-1.o65
|
||||
# overwrite 65sc02 with 65c02
|
||||
${RELOC} -C 65C02 -o $@-2.o65 c65sc02-ad4.o65
|
||||
../hextool -cmp=c65c02-ad4.o65 $@-2.o65
|
||||
|
||||
linkup1.tmp: cpus
|
||||
${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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 1
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 2
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 256
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 4
|
||||
|
||||
.bss
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 1
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 2
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 256
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.align 4
|
||||
|
||||
.data
|
||||
.byt 0
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
.align 1
|
||||
iny
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
.align 2
|
||||
iny
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
.align 256
|
||||
iny
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
.align 4
|
||||
iny
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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,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)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue