mirror of
https://github.com/fachat/xa65.git
synced 2024-06-28 21:29:45 +00:00
Compare commits
2 Commits
59a635ce37
...
f2dac69090
Author | SHA1 | Date | |
---|---|---|---|
|
f2dac69090 | ||
|
4eb72b1896 |
184
xa/misc/file65.c
184
xa/misc/file65.c
|
@ -1,7 +1,7 @@
|
||||||
/* file65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
/* file65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
* Print information about o65 files
|
* Print information about o65 files
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -52,20 +52,13 @@
|
||||||
#define FM_CPU2_NMOS 0x0040
|
#define FM_CPU2_NMOS 0x0040
|
||||||
#define FM_CPU2_65816E 0x0050
|
#define FM_CPU2_65816E 0x0050
|
||||||
|
|
||||||
const char *cpunames[16] = {
|
const char *cpunames[16] = { "6502", "65C02", "65SC02", "65CE02", "NMOS6502",
|
||||||
"6502",
|
|
||||||
"65C02",
|
|
||||||
"65SC02",
|
|
||||||
"65CE02",
|
|
||||||
"NMOS6502",
|
|
||||||
"65816",
|
"65816",
|
||||||
NULL, NULL,
|
NULL, NULL, "6809", NULL, // 1000 -
|
||||||
"6809", NULL, // 1000 -
|
|
||||||
"Z80", NULL, NULL, // 1010 -
|
"Z80", NULL, NULL, // 1010 -
|
||||||
"8086", // 1101 -
|
"8086", // 1101 -
|
||||||
"80286", // 1110 -
|
"80286", // 1110 -
|
||||||
NULL
|
NULL };
|
||||||
};
|
|
||||||
|
|
||||||
int read_options(FILE *fp);
|
int read_options(FILE *fp);
|
||||||
int print_labels(FILE *fp, int offset);
|
int print_labels(FILE *fp, int offset);
|
||||||
|
@ -80,10 +73,8 @@ int labels = 0;
|
||||||
|
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
|
||||||
void usage(FILE *fp)
|
void usage(FILE *fp) {
|
||||||
{
|
fprintf(fp, "Usage: %s [options] [file]\n"
|
||||||
fprintf(fp,
|
|
||||||
"Usage: %s [options] [file]\n"
|
|
||||||
"Print file information about o65 files\n"
|
"Print file information about o65 files\n"
|
||||||
"\n",
|
"\n",
|
||||||
programname);
|
programname);
|
||||||
|
@ -111,7 +102,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
|
|
||||||
if (strstr(argv[i], "--help") || strstr(argv[i], "-?") || strstr(argv[i], "-h")) {
|
if (strstr(argv[i], "--help") || strstr(argv[i], "-?")
|
||||||
|
|| strstr(argv[i], "-h")) {
|
||||||
usage(stdout);
|
usage(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -135,16 +127,21 @@ int main(int argc, char *argv[]) {
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A':
|
case 'A':
|
||||||
rompar = 1;
|
rompar = 1;
|
||||||
if(argv[i][1]=='A') rompar++;
|
if (argv[i][1] == 'A')
|
||||||
if(argv[i][2]) romoff = atoi(argv[i]+2);
|
rompar++;
|
||||||
else if(i + 1 < argc) romoff = atoi(argv[++i]);
|
if (argv[i][2])
|
||||||
else fprintf(stderr,"%s: missing offset\n",programname);
|
romoff = atoi(argv[i] + 2);
|
||||||
|
else if (i + 1 < argc)
|
||||||
|
romoff = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s: missing offset\n", programname);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
xapar = 1;
|
xapar = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"%s: %s unknown option, use '-h' for help\n",programname,argv[i]);
|
fprintf(stderr, "%s: %s unknown option, use '-h' for help\n",
|
||||||
|
programname, argv[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -157,7 +154,8 @@ int main(int argc, char *argv[]) {
|
||||||
printf("%s: o65 version %d %s file\n", argv[i], hdr[5],
|
printf("%s: o65 version %d %s file\n", argv[i], hdr[5],
|
||||||
hdr[7] & 0x10 ? "object" : "executable");
|
hdr[7] & 0x10 ? "object" : "executable");
|
||||||
printf(" mode: %04x =", mode);
|
printf(" mode: %04x =", mode);
|
||||||
printf("[%s][%sbit][%s relocation][CPU %s][CPU2 %s]%s\n",
|
printf(
|
||||||
|
"[%s][%sbit][%s relocation][CPU %s][CPU2 %s]%s\n",
|
||||||
(mode & 0x1000) ? "object" : "executable",
|
(mode & 0x1000) ? "object" : "executable",
|
||||||
(mode & 0x2000) ? "32" : "16",
|
(mode & 0x2000) ? "32" : "16",
|
||||||
(mode & 0x4000) ? "page" : "byte",
|
(mode & 0x4000) ? "page" : "byte",
|
||||||
|
@ -166,44 +164,78 @@ int main(int argc, char *argv[]) {
|
||||||
aligntxt[mode & 3]);
|
aligntxt[mode & 3]);
|
||||||
}
|
}
|
||||||
if (mode & 0x2000) {
|
if (mode & 0x2000) {
|
||||||
fprintf(stderr,"file65: %s: 32 bit size not supported\n", argv[i]);
|
fprintf(stderr,
|
||||||
|
"file65: %s: 32 bit size not supported\n",
|
||||||
|
argv[i]);
|
||||||
} else {
|
} else {
|
||||||
n = fread(hdr + 8, 1, 18, fp);
|
n = fread(hdr + 8, 1, 18, fp);
|
||||||
if (n < 18) {
|
if (n < 18) {
|
||||||
fprintf(stderr,"file65: %s: truncated file\n", argv[i]);
|
fprintf(stderr, "file65: %s: truncated file\n",
|
||||||
|
argv[i]);
|
||||||
} else {
|
} else {
|
||||||
if (!xapar && !rompar) {
|
if (!xapar && !rompar) {
|
||||||
printf(" text segment @ $%04x - $%04x [$%04x bytes]\n", hdr[9]*256+hdr[8], hdr[9]*256+hdr[8]+hdr[11]*256+hdr[10], hdr[11]*256+hdr[10]);
|
printf(
|
||||||
printf(" data segment @ $%04x - $%04x [$%04x bytes]\n", hdr[13]*256+hdr[12], hdr[13]*256+hdr[12]+hdr[15]*256+hdr[14], hdr[15]*256+hdr[14]);
|
" text segment @ $%04x - $%04x [$%04x bytes]\n",
|
||||||
printf(" bss segment @ $%04x - $%04x [$%04x bytes]\n", hdr[17]*256+hdr[16], hdr[17]*256+hdr[16]+hdr[19]*256+hdr[18], hdr[19]*256+hdr[18]);
|
hdr[9] * 256 + hdr[8],
|
||||||
printf(" zero segment @ $%04x - $%04x [$%04x bytes]\n", hdr[21]*256+hdr[20], hdr[21]*256+hdr[20]+hdr[23]*256+hdr[22], hdr[23]*256+hdr[22]);
|
hdr[9] * 256 + hdr[8] + hdr[11] * 256
|
||||||
printf(" stack size $%04x bytes %s\n", hdr[25]*256+hdr[24],
|
+ hdr[10],
|
||||||
(hdr[25]*256+hdr[24])==0?"(i.e. unknown)":"");
|
hdr[11] * 256 + hdr[10]);
|
||||||
|
printf(
|
||||||
|
" data segment @ $%04x - $%04x [$%04x bytes]\n",
|
||||||
|
hdr[13] * 256 + hdr[12],
|
||||||
|
hdr[13] * 256 + hdr[12] + hdr[15] * 256
|
||||||
|
+ hdr[14],
|
||||||
|
hdr[15] * 256 + hdr[14]);
|
||||||
|
printf(
|
||||||
|
" bss segment @ $%04x - $%04x [$%04x bytes]\n",
|
||||||
|
hdr[17] * 256 + hdr[16],
|
||||||
|
hdr[17] * 256 + hdr[16] + hdr[19] * 256
|
||||||
|
+ hdr[18],
|
||||||
|
hdr[19] * 256 + hdr[18]);
|
||||||
|
printf(
|
||||||
|
" zero segment @ $%04x - $%04x [$%04x bytes]\n",
|
||||||
|
hdr[21] * 256 + hdr[20],
|
||||||
|
hdr[21] * 256 + hdr[20] + hdr[23] * 256
|
||||||
|
+ hdr[22],
|
||||||
|
hdr[23] * 256 + hdr[22]);
|
||||||
|
printf(" stack size $%04x bytes %s\n",
|
||||||
|
hdr[25] * 256 + hdr[24],
|
||||||
|
(hdr[25] * 256 + hdr[24]) == 0 ?
|
||||||
|
"(i.e. unknown)" : "");
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
read_options(fp);
|
read_options(fp);
|
||||||
print_labels(fp, hdr[11]*256+hdr[10] + hdr[15]*256+hdr[14]);
|
print_labels(fp,
|
||||||
|
hdr[11] * 256 + hdr[10]
|
||||||
|
+ hdr[15] * 256 + hdr[14]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct stat fbuf;
|
struct stat fbuf;
|
||||||
hlen = 8 + 18 + read_options(fp);
|
hlen = 8 + 18 + read_options(fp);
|
||||||
stat(argv[i], &fbuf);
|
stat(argv[i], &fbuf);
|
||||||
if (xapar) {
|
if (xapar) {
|
||||||
if(!rompar) printf("-bt %d ",
|
if (!rompar)
|
||||||
(hdr[9]*256+hdr[8]) + (hdr[11]*256+hdr[10])
|
printf("-bt %d ",
|
||||||
);
|
(hdr[9] * 256 + hdr[8])
|
||||||
|
+ (hdr[11] * 256
|
||||||
|
+ hdr[10]));
|
||||||
printf("-bd %d -bb %d -bz %d ",
|
printf("-bd %d -bb %d -bz %d ",
|
||||||
(hdr[13]*256+hdr[12]) + (hdr[15]*256+hdr[14]),
|
(hdr[13] * 256 + hdr[12])
|
||||||
(hdr[17]*256+hdr[16]) + (hdr[19]*256+hdr[18]),
|
+ (hdr[15] * 256 + hdr[14]),
|
||||||
(hdr[21]*256+hdr[20]) + (hdr[23]*256+hdr[22])
|
(hdr[17] * 256 + hdr[16])
|
||||||
);
|
+ (hdr[19] * 256 + hdr[18]),
|
||||||
|
(hdr[21] * 256 + hdr[20])
|
||||||
|
+ (hdr[23] * 256 + hdr[22]));
|
||||||
}
|
}
|
||||||
if (rompar == 1) {
|
if (rompar == 1) {
|
||||||
printf("-A %lu ", (unsigned long)((hdr[9]*256+hdr[8])
|
printf("-A %lu ",
|
||||||
-hlen +romoff +(fbuf.st_size)));
|
(unsigned long) ((hdr[9] * 256
|
||||||
} else
|
+ hdr[8]) - hlen + romoff
|
||||||
if(rompar==2) {
|
+ (fbuf.st_size)));
|
||||||
printf("%lu ", (unsigned long)((hdr[9]*256+hdr[8])
|
} else if (rompar == 2) {
|
||||||
-hlen +romoff +(fbuf.st_size)));
|
printf("%lu ",
|
||||||
|
(unsigned long) ((hdr[9] * 256
|
||||||
|
+ hdr[8]) - hlen + romoff
|
||||||
|
+ (fbuf.st_size)));
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -212,10 +244,13 @@ int main(int argc, char *argv[]) {
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "file65: %s: not an o65 file!\n", argv[i]);
|
fprintf(stderr, "file65: %s: not an o65 file!\n", argv[i]);
|
||||||
if (hdr[0] == 1 && hdr[1] == 8 && hdr[3] == 8) {
|
if (hdr[0] == 1 && hdr[1] == 8 && hdr[3] == 8) {
|
||||||
printf("%s: C64 BASIC executable (start address $0801)?\n", argv[i]);
|
printf(
|
||||||
} else
|
"%s: C64 BASIC executable (start address $0801)?\n",
|
||||||
if(hdr[0]==1 && hdr[1]==4 && hdr[3]==4) {
|
argv[i]);
|
||||||
printf("%s: CBM PET BASIC executable (start address $0401)?\n", argv[i]);
|
} else if (hdr[0] == 1 && hdr[1] == 4 && hdr[3] == 4) {
|
||||||
|
printf(
|
||||||
|
"%s: CBM PET BASIC executable (start address $0401)?\n",
|
||||||
|
argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -227,29 +262,21 @@ int main(int argc, char *argv[]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct { int opt; int strfl; char *string; } otab[] = {
|
static struct {
|
||||||
{ 0, 1, "Filename" },
|
int opt;
|
||||||
{ 1, 0, "O/S Type" },
|
int strfl;
|
||||||
{ 2, 1, "Assembler" },
|
char *string;
|
||||||
{ 3, 1, "Author" },
|
} otab[] = { { 0, 1, "Filename" }, { 1, 0, "O/S Type" }, { 2, 1, "Assembler" },
|
||||||
{ 4, 1, "Creation Date" },
|
{ 3, 1, "Author" }, { 4, 1, "Creation Date" }, { -1, -1, NULL } };
|
||||||
{ -1, -1, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static char* stab[] = {
|
static char *stab[] = { "undefined", "absolute", "text", "data", "bss", "zero",
|
||||||
"undefined" ,
|
"-", "-" };
|
||||||
"absolute" ,
|
|
||||||
"text" ,
|
|
||||||
"data" ,
|
|
||||||
"bss" ,
|
|
||||||
"zero" ,
|
|
||||||
"-" ,
|
|
||||||
"-"
|
|
||||||
};
|
|
||||||
|
|
||||||
void print_option(unsigned char *buf, int len) {
|
void print_option(unsigned char *buf, int len) {
|
||||||
int i, strfl = 0;
|
int i, strfl = 0;
|
||||||
for(i=0;otab[i].opt>=0; i++) if(*buf==otab[i].opt) break;
|
for (i = 0; otab[i].opt >= 0; i++)
|
||||||
|
if (*buf == otab[i].opt)
|
||||||
|
break;
|
||||||
if (otab[i].opt >= 0) {
|
if (otab[i].opt >= 0) {
|
||||||
printf("fopt: %-17s: ", otab[i].string);
|
printf("fopt: %-17s: ", otab[i].string);
|
||||||
strfl = otab[i].strfl;
|
strfl = otab[i].strfl;
|
||||||
|
@ -271,11 +298,13 @@ int read_options(FILE *fp) {
|
||||||
int c, d, l = 0;
|
int c, d, l = 0;
|
||||||
unsigned char tb[256];
|
unsigned char tb[256];
|
||||||
|
|
||||||
c=fgetc(fp); l++;
|
c = fgetc(fp);
|
||||||
|
l++;
|
||||||
while (c && c != EOF) {
|
while (c && c != EOF) {
|
||||||
c &= 255;
|
c &= 255;
|
||||||
d = fread(tb, 1, c - 1, fp);
|
d = fread(tb, 1, c - 1, fp);
|
||||||
if(labels) print_option(tb, c);
|
if (labels)
|
||||||
|
print_option(tb, c);
|
||||||
l += c;
|
l += c;
|
||||||
c = fgetc(fp);
|
c = fgetc(fp);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +314,8 @@ int read_options(FILE *fp) {
|
||||||
int print_labels(FILE *fp, int offset) {
|
int print_labels(FILE *fp, int offset) {
|
||||||
int i, nud, c, seg, off;
|
int i, nud, c, seg, off;
|
||||||
const char *segments[] = { "undef", "abs", "text", "data", "bss", "zero" };
|
const char *segments[] = { "undef", "abs", "text", "data", "bss", "zero" };
|
||||||
const char *reltype[] = { "-", "LOW", "HIGH", "-", "WORD", "SEG", "SEGADDR" };
|
const char *reltype[] =
|
||||||
|
{ "-", "LOW", "HIGH", "-", "WORD", "SEG", "SEGADDR" };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("print_labels:offset=%d\n",offset);
|
printf("print_labels:offset=%d\n",offset);
|
||||||
|
@ -331,10 +361,12 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
while (c == 255 && c != EOF) {
|
while (c == 255 && c != EOF) {
|
||||||
offset += 254;
|
offset += 254;
|
||||||
c = fgetc(fp);
|
c = fgetc(fp);
|
||||||
if(c==EOF) break;
|
if (c == EOF)
|
||||||
|
break;
|
||||||
c &= 0xff;
|
c &= 0xff;
|
||||||
}
|
}
|
||||||
if(c==EOF) break;
|
if (c == EOF)
|
||||||
|
break;
|
||||||
offset += c;
|
offset += c;
|
||||||
|
|
||||||
c = fgetc(fp);
|
c = fgetc(fp);
|
||||||
|
@ -346,7 +378,8 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
index += (fgetc(fp) & 0xff) << 8;
|
index += (fgetc(fp) & 0xff) << 8;
|
||||||
}
|
}
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("\t%d:%s(%s (%d)", offset, reltype[ (c>>5) & 0xf], segments[c & 0x07], (c&0x07));
|
printf("\t%d:%s(%s (%d)", offset, reltype[(c >> 5) & 0xf],
|
||||||
|
segments[c & 0x07], (c & 0x07));
|
||||||
if ((c & 0xe0) == 0x40) {
|
if ((c & 0xe0) == 0x40) {
|
||||||
printf(", %02x", lowbyte);
|
printf(", %02x", lowbyte);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +395,6 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// print global labels
|
// print global labels
|
||||||
nud = (fgetc(fp) & 0xff);
|
nud = (fgetc(fp) & 0xff);
|
||||||
|
@ -376,7 +408,8 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
fputc(c, stdout);
|
fputc(c, stdout);
|
||||||
c = fgetc(fp);
|
c = fgetc(fp);
|
||||||
}
|
}
|
||||||
if(c==EOF) break;
|
if (c == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
seg = fgetc(fp) & 0xff;
|
seg = fgetc(fp) & 0xff;
|
||||||
off = (fgetc(fp) & 0xff);
|
off = (fgetc(fp) & 0xff);
|
||||||
|
@ -388,4 +421,3 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
267
xa/misc/ldo65.c
267
xa/misc/ldo65.c
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* A part of the xa65 - 65xx/65816 cross-assembler and utility suite
|
* A part of the xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1997-2023 André Fachat (fachat@web.de)
|
* Copyright (C) 1997-2023 Andr<EFBFBD> Fachat (fachat@web.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -69,7 +69,6 @@ The process of linking works as follows:
|
||||||
#define FM_CPU2_NMOS 0x0040
|
#define FM_CPU2_NMOS 0x0040
|
||||||
#define FM_CPU2_65816E 0x0050
|
#define FM_CPU2_65816E 0x0050
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
int len;
|
int len;
|
||||||
|
@ -127,7 +126,6 @@ typedef struct {
|
||||||
file65 *file; /* in which file is it? */
|
file65 *file; /* in which file is it? */
|
||||||
} glob;
|
} glob;
|
||||||
|
|
||||||
|
|
||||||
file65* load_file(char *fname);
|
file65* load_file(char *fname);
|
||||||
|
|
||||||
int read_options(unsigned char *f);
|
int read_options(unsigned char *f);
|
||||||
|
@ -135,7 +133,8 @@ int read_undef(unsigned char *f, file65 *fp);
|
||||||
int write_undef(FILE *f, file65 *fp);
|
int write_undef(FILE *f, file65 *fp);
|
||||||
int check_undef(file65 *fp, char *defined[], int ndefined);
|
int check_undef(file65 *fp, char *defined[], int ndefined);
|
||||||
int len_reloc_seg(unsigned char *buf, int ri);
|
int len_reloc_seg(unsigned char *buf, int ri);
|
||||||
int reloc_seg(unsigned char *buf, int pos, int addr, int rdiff, int ri, unsigned char *obuf, int *lastaddrp, int *rop, file65 *fp);
|
int reloc_seg(unsigned char *buf, int pos, int addr, int rdiff, int ri,
|
||||||
|
unsigned char *obuf, int *lastaddrp, int *rop, file65 *fp);
|
||||||
unsigned char* reloc_globals(unsigned char*, file65 *fp);
|
unsigned char* reloc_globals(unsigned char*, file65 *fp);
|
||||||
int read_globals(file65 *file);
|
int read_globals(file65 *file);
|
||||||
int write_options(FILE *fp, file65 *file);
|
int write_options(FILE *fp, file65 *file);
|
||||||
|
@ -149,25 +148,19 @@ file65 file;
|
||||||
unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
|
unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
|
||||||
unsigned char hdr[26] = { 1, 0, 'o', '6', '5', 0 };
|
unsigned char hdr[26] = { 1, 0, 'o', '6', '5', 0 };
|
||||||
|
|
||||||
const char *cpunames[16] = {
|
const char *cpunames[16] = { "documented 6502",
|
||||||
"documented 6502",
|
|
||||||
"65C02 (CMOS with BBR/BBS/RMB/SMB)",
|
"65C02 (CMOS with BBR/BBS/RMB/SMB)",
|
||||||
"65SC02 (CMOS without BBR/BBS/RMB/SMB)",
|
"65SC02 (CMOS without BBR/BBS/RMB/SMB)", "65CE02",
|
||||||
"65CE02",
|
"6502 with undocumented opcodes", "65816 in 6502 emulation mode", "n/a",
|
||||||
"6502 with undocumented opcodes",
|
"n/a", "6809?", "n/a", // 1000 -
|
||||||
"65816 in 6502 emulation mode",
|
|
||||||
"n/a", "n/a",
|
|
||||||
"6809?", "n/a", // 1000 -
|
|
||||||
"Z80?", "n/a", "n/a", // 1010 -
|
"Z80?", "n/a", "n/a", // 1010 -
|
||||||
"8086?", // 1101 -
|
"8086?", // 1101 -
|
||||||
"80286?", // 1110 -
|
"80286?", // 1110 -
|
||||||
"n/a"
|
"n/a" };
|
||||||
};
|
|
||||||
|
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
|
||||||
void usage(FILE *fp)
|
void usage(FILE *fp) {
|
||||||
{
|
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"Usage: %s [OPTION]... [FILE]...\n"
|
"Usage: %s [OPTION]... [FILE]...\n"
|
||||||
"Linker for o65 object files\n"
|
"Linker for o65 object files\n"
|
||||||
|
@ -220,7 +213,8 @@ int main(int argc, char *argv[]) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) {
|
if (strstr(argv[1], "--help") || strstr(argv[1], "-?")
|
||||||
|
|| strstr(argv[1], "-h")) {
|
||||||
usage(stdout);
|
usage(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -249,31 +243,35 @@ int main(int argc, char *argv[]) {
|
||||||
undefok = 1;
|
undefok = 1;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if(argv[i][2]) outfile=argv[i]+2;
|
if (argv[i][2])
|
||||||
else outfile=argv[++i];
|
outfile = argv[i] + 2;
|
||||||
|
else
|
||||||
|
outfile = argv[++i];
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
noglob = 1;
|
noglob = 1;
|
||||||
if(argv[i][2]) arg=argv[i]+2;
|
if (argv[i][2])
|
||||||
else arg=argv[++i];
|
arg = argv[i] + 2;
|
||||||
|
else
|
||||||
|
arg = argv[++i];
|
||||||
if (ngloballoc == 0) {
|
if (ngloballoc == 0) {
|
||||||
ngloballoc = 20;
|
ngloballoc = 20;
|
||||||
globdef = malloc(ngloballoc * sizeof(char*));
|
globdef = malloc(ngloballoc * sizeof(char*));
|
||||||
} else
|
} else if (nglobal >= ngloballoc) {
|
||||||
if (nglobal >= ngloballoc) {
|
|
||||||
ngloballoc *= 2;
|
ngloballoc *= 2;
|
||||||
globdef = realloc(globdef, ngloballoc * sizeof(char*));
|
globdef = realloc(globdef, ngloballoc * sizeof(char*));
|
||||||
}
|
}
|
||||||
globdef[nglobal++] = arg;
|
globdef[nglobal++] = arg;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
if(argv[i][2]) arg=argv[i]+2;
|
if (argv[i][2])
|
||||||
else arg=argv[++i];
|
arg = argv[i] + 2;
|
||||||
|
else
|
||||||
|
arg = argv[++i];
|
||||||
if (ndefalloc == 0) {
|
if (ndefalloc == 0) {
|
||||||
ndefalloc = 20;
|
ndefalloc = 20;
|
||||||
defined = malloc(ndefalloc * sizeof(char*));
|
defined = malloc(ndefalloc * sizeof(char*));
|
||||||
} else
|
} else if (ndefined >= ndefalloc) {
|
||||||
if (ndefined >= ndefalloc) {
|
|
||||||
ndefalloc *= 2;
|
ndefalloc *= 2;
|
||||||
defined = realloc(defined, ndefalloc * sizeof(char*));
|
defined = realloc(defined, ndefalloc * sizeof(char*));
|
||||||
}
|
}
|
||||||
|
@ -282,20 +280,28 @@ int main(int argc, char *argv[]) {
|
||||||
case 'b':
|
case 'b':
|
||||||
switch (argv[i][2]) {
|
switch (argv[i][2]) {
|
||||||
case 't':
|
case 't':
|
||||||
if(argv[i][3]) tbase = atoi(argv[i]+3);
|
if (argv[i][3])
|
||||||
else tbase = atoi(argv[++i]);
|
tbase = atoi(argv[i] + 3);
|
||||||
|
else
|
||||||
|
tbase = atoi(argv[++i]);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
if(argv[i][3]) dbase = atoi(argv[i]+3);
|
if (argv[i][3])
|
||||||
else dbase = atoi(argv[++i]);
|
dbase = atoi(argv[i] + 3);
|
||||||
|
else
|
||||||
|
dbase = atoi(argv[++i]);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if(argv[i][3]) bbase = atoi(argv[i]+3);
|
if (argv[i][3])
|
||||||
else bbase = atoi(argv[++i]);
|
bbase = atoi(argv[i] + 3);
|
||||||
|
else
|
||||||
|
bbase = atoi(argv[++i]);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
if(argv[i][3]) zbase = atoi(argv[i]+3);
|
if (argv[i][3])
|
||||||
else zbase = atoi(argv[++i]);
|
zbase = atoi(argv[i] + 3);
|
||||||
|
else
|
||||||
|
zbase = atoi(argv[++i]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]);
|
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]);
|
||||||
|
@ -303,7 +309,8 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"file65: %s unknown option, use '-h for help\n",argv[i]);
|
fprintf(stderr, "file65: %s unknown option, use '-h for help\n",
|
||||||
|
argv[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -313,13 +320,19 @@ int main(int argc, char *argv[]) {
|
||||||
// step 1 - load files
|
// step 1 - load files
|
||||||
|
|
||||||
/* each file is loaded first */
|
/* each file is loaded first */
|
||||||
j=0; jm=0; fp=NULL;
|
j = 0;
|
||||||
|
jm = 0;
|
||||||
|
fp = NULL;
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
file65 *f;
|
file65 *f;
|
||||||
f = load_file(argv[i]);
|
f = load_file(argv[i]);
|
||||||
if (f) {
|
if (f) {
|
||||||
if(j>=jm) fp=realloc(fp, (jm=(jm?jm*2:10))*sizeof(file65*));
|
if (j >= jm)
|
||||||
if(!fp) { fprintf(stderr,"Oops, no more memory\n"); exit(1); }
|
fp = realloc(fp, (jm = (jm ? jm * 2 : 10)) * sizeof(file65*));
|
||||||
|
if (!fp) {
|
||||||
|
fprintf(stderr, "Oops, no more memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
fp[j++] = f;
|
fp[j++] = f;
|
||||||
} else {
|
} else {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -352,7 +365,8 @@ int main(int argc, char *argv[]) {
|
||||||
// 65816
|
// 65816
|
||||||
trgmode |= 0x8000;
|
trgmode |= 0x8000;
|
||||||
if (trgcpu == 4) {
|
if (trgcpu == 4) {
|
||||||
fprintf(stderr, "Error: file '%s' in 65816 CPU mode is incompatible with previous NMOS undocumented opcodes CPU mode\n",
|
fprintf(stderr,
|
||||||
|
"Error: file '%s' in 65816 CPU mode is incompatible with previous NMOS undocumented opcodes CPU mode\n",
|
||||||
file->fname);
|
file->fname);
|
||||||
er = 1;
|
er = 1;
|
||||||
}
|
}
|
||||||
|
@ -364,8 +378,10 @@ int main(int argc, char *argv[]) {
|
||||||
// CPU bits
|
// CPU bits
|
||||||
fcpu = (file->mode & FM_CPU2) >> 4;
|
fcpu = (file->mode & FM_CPU2) >> 4;
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("Matching file %s with CPU %s (%d) to target %s (%d) ...\n",
|
printf(
|
||||||
file->fname, cpunames[fcpu], fcpu, cpunames[trgcpu], trgcpu);
|
"Matching file %s with CPU %s (%d) to target %s (%d) ...\n",
|
||||||
|
file->fname, cpunames[fcpu], fcpu, cpunames[trgcpu],
|
||||||
|
trgcpu);
|
||||||
}
|
}
|
||||||
switch (fcpu) {
|
switch (fcpu) {
|
||||||
case 0x0: // bare minimum documented 6502 is just fine
|
case 0x0: // bare minimum documented 6502 is just fine
|
||||||
|
@ -383,9 +399,11 @@ int main(int argc, char *argv[]) {
|
||||||
case 0x2: // 65SC02 - CMOS without BBR/BBS/RMB/SMB, compatible with 65816
|
case 0x2: // 65SC02 - CMOS without BBR/BBS/RMB/SMB, compatible with 65816
|
||||||
if (trgcpu == 4) {
|
if (trgcpu == 4) {
|
||||||
// is incompatible with nmos6502 with undocumented opcodes
|
// is incompatible with nmos6502 with undocumented opcodes
|
||||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) "
|
fprintf(stderr,
|
||||||
|
"Error: file '%s' in CPU mode %d (%s) "
|
||||||
"is incompatible with previous files with mode %d (%s)\n",
|
"is incompatible with previous files with mode %d (%s)\n",
|
||||||
file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]);
|
file->fname, fcpu, cpunames[fcpu], trgcpu,
|
||||||
|
cpunames[trgcpu]);
|
||||||
er = 1;
|
er = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -393,9 +411,11 @@ int main(int argc, char *argv[]) {
|
||||||
case 0x5: // 65816 in 6502 emulation mode
|
case 0x5: // 65816 in 6502 emulation mode
|
||||||
if (trgcpu == 1 || trgcpu == 3) {
|
if (trgcpu == 1 || trgcpu == 3) {
|
||||||
// 65C02 and 65CE02 are incompatible with nmos6502 with undocumented opcodes
|
// 65C02 and 65CE02 are incompatible with nmos6502 with undocumented opcodes
|
||||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) is "
|
fprintf(stderr,
|
||||||
|
"Error: file '%s' in CPU mode %d (%s) is "
|
||||||
"incompatible with previous files with mode %d (%s)\n",
|
"incompatible with previous files with mode %d (%s)\n",
|
||||||
file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]);
|
file->fname, fcpu, cpunames[fcpu], trgcpu,
|
||||||
|
cpunames[trgcpu]);
|
||||||
er = 1;
|
er = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -403,20 +423,24 @@ int main(int argc, char *argv[]) {
|
||||||
case 0x4: // NMOS 6502 with undocumented opcodes
|
case 0x4: // NMOS 6502 with undocumented opcodes
|
||||||
if (trgcpu == 1 || trgcpu == 2 || trgcpu == 3 || trgcpu == 5) {
|
if (trgcpu == 1 || trgcpu == 2 || trgcpu == 3 || trgcpu == 5) {
|
||||||
// is incompatible with nmos6502 with undocumented opcodes
|
// is incompatible with nmos6502 with undocumented opcodes
|
||||||
fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) is "
|
fprintf(stderr,
|
||||||
|
"Error: file '%s' in CPU mode %d (%s) is "
|
||||||
"incompatible with previous files with mode %d (%s)\n",
|
"incompatible with previous files with mode %d (%s)\n",
|
||||||
file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]);
|
file->fname, fcpu, cpunames[fcpu], trgcpu,
|
||||||
|
cpunames[trgcpu]);
|
||||||
er = 1;
|
er = 1;
|
||||||
}
|
}
|
||||||
if (trgmode & 0x8000) {
|
if (trgmode & 0x8000) {
|
||||||
fprintf(stderr, "Error: file '%s' in mode %d (%s) is incompatible with previous 65816 CPU mode\n",
|
fprintf(stderr,
|
||||||
|
"Error: file '%s' in mode %d (%s) is incompatible with previous 65816 CPU mode\n",
|
||||||
file->fname, 4, cpunames[4]);
|
file->fname, 4, cpunames[4]);
|
||||||
er = 1;
|
er = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (fcpu > 5) {
|
if (fcpu > 5) {
|
||||||
printf("Warning: unknown CPU mode %d (%s) detected in file %s\n",
|
printf(
|
||||||
|
"Warning: unknown CPU mode %d (%s) detected in file %s\n",
|
||||||
fcpu, cpunames[fcpu], file->fname);
|
fcpu, cpunames[fcpu], file->fname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -448,8 +472,7 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (verbose && !er) {
|
if (verbose && !er) {
|
||||||
printf("... to new target %s (%d)\n",
|
printf("... to new target %s (%d)\n", cpunames[trgcpu], trgcpu);
|
||||||
cpunames[trgcpu], trgcpu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (er) {
|
if (er) {
|
||||||
|
@ -474,7 +497,6 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// step 2 - calculate new segment base addresses per file, by
|
// step 2 - calculate new segment base addresses per file, by
|
||||||
// concatenating the segments per type
|
// concatenating the segments per type
|
||||||
|
@ -483,7 +505,6 @@ int main(int argc, char *argv[]) {
|
||||||
/* set total length to zero */
|
/* set total length to zero */
|
||||||
ttlen = tdlen = tblen = tzlen = 0;
|
ttlen = tdlen = tblen = tzlen = 0;
|
||||||
|
|
||||||
|
|
||||||
// then check start addresses
|
// then check start addresses
|
||||||
file = fp[0];
|
file = fp[0];
|
||||||
if (file->align != 0) {
|
if (file->align != 0) {
|
||||||
|
@ -555,15 +576,24 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (verbose > 0) {
|
if (verbose > 0) {
|
||||||
printf("Relocating file: %s [CPU %s]\n", file->fname, cpunames[((file->mode & FM_CPU2) >> 4) & 0x0f]);
|
printf("Relocating file: %s [CPU %s]\n", file->fname,
|
||||||
printf(" text: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
cpunames[((file->mode & FM_CPU2) >> 4) & 0x0f]);
|
||||||
file->talign, file->tbase, file->tbase + file->tdiff, file->tdiff, file->tlen);
|
printf(
|
||||||
printf(" data: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
" text: 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);
|
file->talign, file->tbase, file->tbase + file->tdiff,
|
||||||
printf(" bss: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
file->tdiff, file->tlen);
|
||||||
file->balign, file->bbase, file->bbase + file->bdiff, file->bdiff, file->blen);
|
printf(
|
||||||
printf(" zero: relocate from %02x to %02x (diff is %02x, length is %02x)\n",
|
" data: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||||
file->zbase, file->zbase + file->zdiff, file->zdiff, file->zlen);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update globals (for result file) */
|
/* update globals (for result file) */
|
||||||
|
@ -640,7 +670,6 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||||
read_globals(file);
|
read_globals(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// step 4 - for each file, resolve undefined lables, storing replacement info
|
// step 4 - for each file, resolve undefined lables, storing replacement info
|
||||||
// in the ud label table; merge remaining undefined labels into global
|
// in the ud label table; merge remaining undefined labels into global
|
||||||
|
@ -698,15 +727,8 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||||
&tro, // pointer in output reloc bufer
|
&tro, // pointer in output reloc bufer
|
||||||
file);
|
file);
|
||||||
|
|
||||||
reloc_seg(file->buf,
|
reloc_seg(file->buf, file->dpos, file->dbase, file->ddiff, file->drpos,
|
||||||
file->dpos,
|
dreloc, &lastdaddr, &dro, file);
|
||||||
file->dbase,
|
|
||||||
file->ddiff,
|
|
||||||
file->drpos,
|
|
||||||
dreloc,
|
|
||||||
&lastdaddr,
|
|
||||||
&dro,
|
|
||||||
file);
|
|
||||||
|
|
||||||
// change file information to relocated values
|
// change file information to relocated values
|
||||||
file->tbase += file->tdiff;
|
file->tbase += file->tdiff;
|
||||||
|
@ -743,22 +765,32 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
|
||||||
//
|
//
|
||||||
|
|
||||||
// prepare header
|
// prepare header
|
||||||
hdr[ 6] = trgmode & 255; hdr[ 7] = (trgmode>>8)& 255;
|
hdr[6] = trgmode & 255;
|
||||||
hdr[ 8] = tbase & 255; hdr[ 9] = (tbase>>8) & 255;
|
hdr[7] = (trgmode >> 8) & 255;
|
||||||
hdr[10] = ttlen & 255; hdr[11] = (ttlen >>8)& 255;
|
hdr[8] = tbase & 255;
|
||||||
hdr[12] = dbase & 255; hdr[13] = (dbase>>8) & 255;
|
hdr[9] = (tbase >> 8) & 255;
|
||||||
hdr[14] = tdlen & 255; hdr[15] = (tdlen >>8)& 255;
|
hdr[10] = ttlen & 255;
|
||||||
hdr[16] = bbase & 255; hdr[17] = (bbase>>8) & 255;
|
hdr[11] = (ttlen >> 8) & 255;
|
||||||
hdr[18] = tblen & 255; hdr[19] = (tblen >>8)& 255;
|
hdr[12] = dbase & 255;
|
||||||
hdr[20] = zbase & 255; hdr[21] = (zbase>>8) & 255;
|
hdr[13] = (dbase >> 8) & 255;
|
||||||
hdr[22] = tzlen & 255; hdr[23] = (tzlen >>8)& 255;
|
hdr[14] = tdlen & 255;
|
||||||
hdr[24] = 0; hdr[25] = 0;
|
hdr[15] = (tdlen >> 8) & 255;
|
||||||
|
hdr[16] = bbase & 255;
|
||||||
|
hdr[17] = (bbase >> 8) & 255;
|
||||||
|
hdr[18] = tblen & 255;
|
||||||
|
hdr[19] = (tblen >> 8) & 255;
|
||||||
|
hdr[20] = zbase & 255;
|
||||||
|
hdr[21] = (zbase >> 8) & 255;
|
||||||
|
hdr[22] = tzlen & 255;
|
||||||
|
hdr[23] = (tzlen >> 8) & 255;
|
||||||
|
hdr[24] = 0;
|
||||||
|
hdr[25] = 0;
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
fd = fopen(outfile, "wb");
|
fd = fopen(outfile, "wb");
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
fprintf(stderr,"Couldn't open output file %s (%s)\n",
|
fprintf(stderr, "Couldn't open output file %s (%s)\n", outfile,
|
||||||
outfile, strerror(errno));
|
strerror(errno));
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,7 +896,8 @@ int read_undef(unsigned char *buf, file65 *file) {
|
||||||
while (i < nlabels) {
|
while (i < nlabels) {
|
||||||
// find length of label name
|
// find length of label name
|
||||||
startp = bufp;
|
startp = bufp;
|
||||||
while(buf[bufp++]);
|
while (buf[bufp++])
|
||||||
|
;
|
||||||
// store label info
|
// store label info
|
||||||
current = &file->ud[i];
|
current = &file->ud[i];
|
||||||
current->name = (char*) buf + startp;
|
current->name = (char*) buf + startp;
|
||||||
|
@ -907,7 +940,6 @@ printf("resolved undef label %s to: resolved=%d, newidx=%d\n", current->name, cu
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int write_undef(FILE *f, file65 *fp) {
|
int write_undef(FILE *f, file65 *fp) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < fp->nundef; i++) {
|
for (i = 0; i < fp->nundef; i++) {
|
||||||
|
@ -948,7 +980,6 @@ int check_undef(file65 *fp, char *defined[], int ndefined) {
|
||||||
return er;
|
return er;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
/* compute and return the length of the relocation table */
|
/* compute and return the length of the relocation table */
|
||||||
|
@ -973,7 +1004,8 @@ int len_reloc_seg(unsigned char *buf, int ri) {
|
||||||
case 0x20:
|
case 0x20:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(seg==0) ri+=2;
|
if (seg == 0)
|
||||||
|
ri += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ++ri;
|
return ++ri;
|
||||||
|
@ -990,13 +1022,14 @@ unsigned char *reloc_globals(unsigned char *buf, file65 *fp) {
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
name = buf;
|
name = buf;
|
||||||
while(*(buf++));
|
while (*(buf++))
|
||||||
|
;
|
||||||
seg = *buf & 0x07;
|
seg = *buf & 0x07;
|
||||||
old = buf[1] + 256 * buf[2];
|
old = buf[1] + 256 * buf[2];
|
||||||
new = old + reldiff(seg);
|
new = old + reldiff(seg);
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("%s:%s: old=%04x, seg=%d, rel=%04x, new=%04x\n",
|
printf("%s:%s: old=%04x, seg=%d, rel=%04x, new=%04x\n", fp->fname,
|
||||||
fp->fname, name, old, seg, reldiff(seg), new);
|
name, old, seg, reldiff(seg), new);
|
||||||
}
|
}
|
||||||
buf[1] = new & 255;
|
buf[1] = new & 255;
|
||||||
buf[2] = (new >> 8) & 255;
|
buf[2] = (new >> 8) & 255;
|
||||||
|
@ -1041,13 +1074,18 @@ file65 *load_file(char *fname) {
|
||||||
mode = file->buf[7] * 256 + file->buf[6];
|
mode = file->buf[7] * 256 + file->buf[6];
|
||||||
file->mode = mode;
|
file->mode = mode;
|
||||||
if (mode & 0x2000) {
|
if (mode & 0x2000) {
|
||||||
fprintf(stderr,"file65: %s: 32 bit size not supported\n", fname);
|
fprintf(stderr, "file65: %s: 32 bit size not supported\n",
|
||||||
free(file->buf); free(file); file=NULL;
|
|
||||||
} else
|
|
||||||
if(mode & 0x4000) {
|
|
||||||
fprintf(stderr,"file65: %s: pagewise relocation not supported\n",
|
|
||||||
fname);
|
fname);
|
||||||
free(file->buf); free(file); file=NULL;
|
free(file->buf);
|
||||||
|
free(file);
|
||||||
|
file = NULL;
|
||||||
|
} else if (mode & 0x4000) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"file65: %s: pagewise relocation not supported\n",
|
||||||
|
fname);
|
||||||
|
free(file->buf);
|
||||||
|
free(file);
|
||||||
|
file = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
align = mode & 3;
|
align = mode & 3;
|
||||||
|
@ -1087,7 +1125,8 @@ file65 *load_file(char *fname) {
|
||||||
file->tpos = hlen;
|
file->tpos = hlen;
|
||||||
file->dpos = hlen + file->tlen;
|
file->dpos = hlen + file->tlen;
|
||||||
file->upos = file->dpos + file->dlen;
|
file->upos = file->dpos + file->dlen;
|
||||||
file->trpos= file->upos + read_undef(file->buf+file->upos, file);
|
file->trpos = file->upos
|
||||||
|
+ read_undef(file->buf + file->upos, file);
|
||||||
file->drpos = len_reloc_seg(file->buf, file->trpos);
|
file->drpos = len_reloc_seg(file->buf, file->trpos);
|
||||||
file->gpos = len_reloc_seg(file->buf, file->drpos);
|
file->gpos = len_reloc_seg(file->buf, file->drpos);
|
||||||
}
|
}
|
||||||
|
@ -1111,7 +1150,6 @@ int g=0;
|
||||||
// number of globals for which memory is already allocated
|
// number of globals for which memory is already allocated
|
||||||
int gm = 0;
|
int gm = 0;
|
||||||
|
|
||||||
|
|
||||||
int write_globals(FILE *fp) {
|
int write_globals(FILE *fp) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1119,8 +1157,8 @@ int write_globals(FILE *fp) {
|
||||||
fputc((g >> 8) & 255, fp);
|
fputc((g >> 8) & 255, fp);
|
||||||
|
|
||||||
for (i = 0; i < g; i++) {
|
for (i = 0; i < g; i++) {
|
||||||
fprintf(fp,"%s%c%c%c%c",gp[i].name,0,gp[i].seg,
|
fprintf(fp, "%s%c%c%c%c", gp[i].name, 0, gp[i].seg, gp[i].val & 255,
|
||||||
gp[i].val & 255, (gp[i].val>>8)&255);
|
(gp[i].val >> 8) & 255);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1157,7 +1195,9 @@ int write_nglobals(FILE *fp, char **globdef, int nglobal) {
|
||||||
}
|
}
|
||||||
if (i >= g) {
|
if (i >= g) {
|
||||||
// not found
|
// not found
|
||||||
fprintf(stderr,"Warning: command line allowed global '%s' is not defined!\n", globdef[j]);
|
fprintf(stderr,
|
||||||
|
"Warning: command line allowed global '%s' is not defined!\n",
|
||||||
|
globdef[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1167,8 +1207,8 @@ int write_nglobals(FILE *fp, char **globdef, int nglobal) {
|
||||||
|
|
||||||
for (i = 0; i < g; i++) {
|
for (i = 0; i < g; i++) {
|
||||||
if (gp[i].name != NULL) {
|
if (gp[i].name != NULL) {
|
||||||
fprintf(fp,"%s%c%c%c%c",gp[i].name,0,gp[i].seg,
|
fprintf(fp, "%s%c%c%c%c", gp[i].name, 0, gp[i].seg, gp[i].val & 255,
|
||||||
gp[i].val & 255, (gp[i].val>>8)&255);
|
(gp[i].val >> 8) & 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1186,7 +1226,8 @@ int read_globals(file65 *fp) {
|
||||||
/*printf("reading %s, ", buf);*/
|
/*printf("reading %s, ", buf);*/
|
||||||
name = (char*) buf;
|
name = (char*) buf;
|
||||||
l = 0;
|
l = 0;
|
||||||
while(buf[l++]);
|
while (buf[l++])
|
||||||
|
;
|
||||||
buf += l;
|
buf += l;
|
||||||
ll = l - 1;
|
ll = l - 1;
|
||||||
seg = *buf;
|
seg = *buf;
|
||||||
|
@ -1197,7 +1238,8 @@ int read_globals(file65 *fp) {
|
||||||
/* multiply defined? */
|
/* multiply defined? */
|
||||||
for (i = 0; i < g; i++) {
|
for (i = 0; i < g; i++) {
|
||||||
if (ll == gp[i].len && !strcmp(name, gp[i].name)) {
|
if (ll == gp[i].len && !strcmp(name, gp[i].name)) {
|
||||||
fprintf(stderr,"Warning: label '%s' multiply defined (%s and %s)\n",
|
fprintf(stderr,
|
||||||
|
"Warning: label '%s' multiply defined (%s and %s)\n",
|
||||||
name, fp->fname, gp[i].file->fname);
|
name, fp->fname, gp[i].file->fname);
|
||||||
gp[i].fl = 1;
|
gp[i].fl = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -1213,7 +1255,8 @@ int read_globals(file65 *fp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g >= 0x10000) {
|
if (g >= 0x10000) {
|
||||||
fprintf(stderr,"Outch, maximum number of labels (65536) exceeded!\n");
|
fprintf(stderr,
|
||||||
|
"Outch, maximum number of labels (65536) exceeded!\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
gp[g].name = name;
|
gp[g].name = name;
|
||||||
|
@ -1261,13 +1304,13 @@ int find_file_global(unsigned char *bp, file65 *fp, int *seg) {
|
||||||
for (i = 0; i < g; i++) {
|
for (i = 0; i < g; i++) {
|
||||||
if (gp[i].len == l && !strcmp(gp[i].name, n)) {
|
if (gp[i].len == l && !strcmp(gp[i].name, n)) {
|
||||||
*seg = gp[i].seg;
|
*seg = gp[i].seg;
|
||||||
bp[0] = i & 255; bp[1] = (i>>8) & 255;
|
bp[0] = i & 255;
|
||||||
|
bp[1] = (i >> 8) & 255;
|
||||||
/*printf("return gp[%d]=%s (len=%d), val=%04x\n",i,gp[i].name,gp[i].len,gp[i].val);*/
|
/*printf("return gp[%d]=%s (len=%d), val=%04x\n",i,gp[i].name,gp[i].len,gp[i].val);*/
|
||||||
return gp[i].val;
|
return gp[i].val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr,"Warning: undefined label '%s' in file %s\n",
|
fprintf(stderr, "Warning: undefined label '%s' in file %s\n", n, fp->fname);
|
||||||
n, fp->fname);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,5 +1486,3 @@ printf("found undef'd label %s, resolved=%d, newidx=%d, (ri=%d, ro=%d)\n", u->na
|
||||||
return ++ri;
|
return ++ri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#
|
#
|
||||||
# xa65 - 6502 cross assembler and utility suite
|
# xa65 - 6502 cross assembler and utility suite
|
||||||
# mkrom.sh - assemble several 'romable' files into one binary
|
# mkrom.sh - assemble several 'romable' files into one binary
|
||||||
# Copyright (C) 1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
# Copyright (C) 1997 Andre Fachat (afachat@gmx.de)
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* printcbm -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
/* printcbm -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
* list CBM BASIC programs
|
* list CBM BASIC programs
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,20 +29,16 @@
|
||||||
#define author "Written by Andre Fachat"
|
#define author "Written by Andre Fachat"
|
||||||
#define copyright "Copyright (C) 1997-2002 Andre Fachat."
|
#define copyright "Copyright (C) 1997-2002 Andre Fachat."
|
||||||
|
|
||||||
char *cmd[] = {
|
char *cmd[] = { "end", "for", "next", "data", "input#", "input", "dim", "read",
|
||||||
"end", "for", "next", "data", "input#", "input", "dim", "read",
|
"let", "goto", "run", "if", "restore", "gosub", "return", "rem", "stop",
|
||||||
"let", "goto", "run", "if", "restore", "gosub", "return",
|
"on", "wait", "load", "save", "verify", "def", "poke", "print#",
|
||||||
"rem", "stop", "on", "wait", "load", "save", "verify", "def",
|
"print", "cont", "list", "clr", "cmd", "sys", "open", "close", "get",
|
||||||
"poke", "print#", "print", "cont", "list", "clr", "cmd", "sys",
|
"new", "tab(", "to", "fn", "spc(", "then", "not", "step", "+", "-", "*",
|
||||||
"open", "close", "get", "new", "tab(", "to", "fn", "spc(",
|
"/", "^", "and", "or", ">", "=", "<", "sgn", "int", "abs", "usr", "fre",
|
||||||
"then", "not", "step", "+", "-", "*", "/", "^", "and", "or",
|
"pos", "sqr", "rnd", "log", "exp", "cos", "sin", "tan", "atn", "peek",
|
||||||
">", "=", "<", "sgn", "int", "abs", "usr", "fre", "pos", "sqr",
|
"len", "str$", "val", "asc", "chr$", "left$", "right$", "mid$", "go" };
|
||||||
"rnd", "log", "exp", "cos", "sin", "tan", "atn", "peek", "len",
|
|
||||||
"str$", "val", "asc", "chr$", "left$", "right$", "mid$", "go"
|
|
||||||
};
|
|
||||||
|
|
||||||
void usage(FILE *fp)
|
void usage(FILE *fp) {
|
||||||
{
|
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"Usage: %s [OPTION]... [FILE]...\n"
|
"Usage: %s [OPTION]... [FILE]...\n"
|
||||||
"List CBM BASIC programs\n"
|
"List CBM BASIC programs\n"
|
||||||
|
@ -54,8 +50,7 @@ void usage(FILE *fp)
|
||||||
programname);
|
programname);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
* o65 file relocator
|
* o65 file relocator
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -63,17 +63,16 @@ typedef struct {
|
||||||
unsigned char *extab;
|
unsigned char *extab;
|
||||||
} file65;
|
} file65;
|
||||||
|
|
||||||
|
|
||||||
int read_options(unsigned char *f);
|
int read_options(unsigned char *f);
|
||||||
int read_undef(unsigned char *f);
|
int read_undef(unsigned char *f);
|
||||||
unsigned char *reloc_seg(unsigned char *f, int len, unsigned char *rtab, file65 *fp, int undefwarn);
|
unsigned char* reloc_seg(unsigned char *f, int len, unsigned char *rtab,
|
||||||
|
file65 *fp, int undefwarn);
|
||||||
unsigned char* reloc_globals(unsigned char*, file65 *fp);
|
unsigned char* reloc_globals(unsigned char*, file65 *fp);
|
||||||
|
|
||||||
file65 file;
|
file65 file;
|
||||||
unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
|
unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
|
||||||
|
|
||||||
void usage(FILE *fp)
|
void usage(FILE *fp) {
|
||||||
{
|
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"Usage: %s [OPTION]... [FILE]...\n"
|
"Usage: %s [OPTION]... [FILE]...\n"
|
||||||
"Relocator for o65 object files\n"
|
"Relocator for o65 object files\n"
|
||||||
|
@ -97,20 +96,13 @@ void usage(FILE *fp)
|
||||||
" --help display this help and exit\n");
|
" --help display this help and exit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cpunames[16] = {
|
const char *cpunames[16] = { "6502", "65C02", "65SC02", "65CE02", "NMOS6502",
|
||||||
"6502",
|
|
||||||
"65C02",
|
|
||||||
"65SC02",
|
|
||||||
"65CE02",
|
|
||||||
"NMOS6502",
|
|
||||||
"65816",
|
"65816",
|
||||||
NULL, NULL,
|
NULL, NULL, "6809", NULL, // 1000 -
|
||||||
"6809", NULL, // 1000 -
|
|
||||||
"Z80", NULL, NULL, // 1010 -
|
"Z80", NULL, NULL, // 1010 -
|
||||||
"8086", // 1101 -
|
"8086", // 1101 -
|
||||||
"80286", // 1110 -
|
"80286", // 1110 -
|
||||||
NULL
|
NULL };
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int i = 1, mode, hlen;
|
int i = 1, mode, hlen;
|
||||||
|
@ -131,7 +123,8 @@ int main(int argc, char *argv[]) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) {
|
if (strstr(argv[1], "--help") || strstr(argv[1], "-?")
|
||||||
|
|| strstr(argv[1], "-h")) {
|
||||||
usage(stdout);
|
usage(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -150,9 +143,12 @@ int main(int argc, char *argv[]) {
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if(argv[i][2]) outfile=argv[i]+2;
|
if (argv[i][2])
|
||||||
else if(i + 1 < argc) outfile=argv[++i];
|
outfile = argv[i] + 2;
|
||||||
else fprintf(stderr,"%s: missing output file\n",programname);
|
else if (i + 1 < argc)
|
||||||
|
outfile = argv[++i];
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s: missing output file\n", programname);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
extract = 3;
|
extract = 3;
|
||||||
|
@ -177,13 +173,17 @@ int main(int argc, char *argv[]) {
|
||||||
base = &zbase;
|
base = &zbase;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]);
|
printf("Unknown segment type '%c' - ignored!\n",
|
||||||
|
argv[i][2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (base != NULL) {
|
if (base != NULL) {
|
||||||
if(argv[i][3]) *base = atoi(argv[i]+3);
|
if (argv[i][3])
|
||||||
else if(i + 1 < argc) *base = atoi(argv[++i]);
|
*base = atoi(argv[i] + 3);
|
||||||
else fprintf(stderr,"%s: missing address\n",programname);
|
else if (i + 1 < argc)
|
||||||
|
*base = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s: missing address\n", programname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'x': /* extract segment */
|
case 'x': /* extract segment */
|
||||||
|
@ -196,16 +196,20 @@ int main(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
case 'b':
|
case 'b':
|
||||||
printf("Cannot extract segment type '%c' - ignored!\n", argv[i][2]);
|
printf("Cannot extract segment type '%c' - ignored!\n",
|
||||||
|
argv[i][2]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]);
|
printf("Unknown segment type '%c' - ignored!\n",
|
||||||
|
argv[i][2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if(argv[i][2]) arg=argv[i]+2;
|
if (argv[i][2])
|
||||||
else if(i + 1 < argc) arg=argv[++i];
|
arg = argv[i] + 2;
|
||||||
|
else if (i + 1 < argc)
|
||||||
|
arg = argv[++i];
|
||||||
if (arg == NULL) {
|
if (arg == NULL) {
|
||||||
printf("Missing CPU parameter to -C - ignored\n");
|
printf("Missing CPU parameter to -C - ignored\n");
|
||||||
break;
|
break;
|
||||||
|
@ -223,7 +227,8 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"%s: %s unknown option, use '-h' for help\n",programname,argv[i]);
|
fprintf(stderr, "%s: %s unknown option, use '-h' for help\n",
|
||||||
|
programname, argv[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -244,10 +249,13 @@ int main(int argc, char *argv[]) {
|
||||||
if ((n >= file.fsize) && (!memcmp(file.buf, cmp, 5))) {
|
if ((n >= file.fsize) && (!memcmp(file.buf, cmp, 5))) {
|
||||||
mode = file.buf[7] * 256 + file.buf[6];
|
mode = file.buf[7] * 256 + file.buf[6];
|
||||||
if (mode & FM_SIZE) {
|
if (mode & FM_SIZE) {
|
||||||
fprintf(stderr,"reloc65: %s: 32 bit size not supported\n", argv[i]);
|
fprintf(stderr,
|
||||||
} else
|
"reloc65: %s: 32 bit size not supported\n",
|
||||||
if(mode & FM_RELOC) {
|
argv[i]);
|
||||||
fprintf(stderr,"reloc65: %s: pagewise relocation not supported\n", argv[i]);
|
} else if (mode & FM_RELOC) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"reloc65: %s: pagewise relocation not supported\n",
|
||||||
|
argv[i]);
|
||||||
} else {
|
} else {
|
||||||
if (trgcpu >= 0) {
|
if (trgcpu >= 0) {
|
||||||
// change CPU flags
|
// change CPU flags
|
||||||
|
@ -274,7 +282,9 @@ int main(int argc, char *argv[]) {
|
||||||
file.ddiff = dflag ? dbase - file.dbase : 0;
|
file.ddiff = dflag ? dbase - file.dbase : 0;
|
||||||
if (extract == 3) {
|
if (extract == 3) {
|
||||||
if (dflag) {
|
if (dflag) {
|
||||||
fprintf(stderr,"reloc65: %s: Warning: data segment address overrides -X option\n", argv[i]);
|
fprintf(stderr,
|
||||||
|
"reloc65: %s: Warning: data segment address overrides -X option\n",
|
||||||
|
argv[i]);
|
||||||
} else {
|
} else {
|
||||||
dbase = file.tbase + file.tdiff + file.tlen;
|
dbase = file.tbase + file.tdiff + file.tlen;
|
||||||
file.ddiff = dbase - file.dbase;
|
file.ddiff = dbase - file.dbase;
|
||||||
|
@ -286,7 +296,9 @@ int main(int argc, char *argv[]) {
|
||||||
file.bdiff = bflag ? bbase - file.bbase : 0;
|
file.bdiff = bflag ? bbase - file.bbase : 0;
|
||||||
if (extract == 3) {
|
if (extract == 3) {
|
||||||
if (bflag) {
|
if (bflag) {
|
||||||
fprintf(stderr,"reloc65: %s: Warning: bss segment address overrides -X option\n", argv[i]);
|
fprintf(stderr,
|
||||||
|
"reloc65: %s: Warning: bss segment address overrides -X option\n",
|
||||||
|
argv[i]);
|
||||||
} else {
|
} else {
|
||||||
bbase = file.dbase + file.ddiff + file.dlen;
|
bbase = file.dbase + file.ddiff + file.dlen;
|
||||||
file.bdiff = bbase - file.bbase;
|
file.bdiff = bbase - file.bbase;
|
||||||
|
@ -299,18 +311,30 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("Relocating segments to:\n");
|
printf("Relocating segments to:\n");
|
||||||
printf("text segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
printf(
|
||||||
file.tbase + file.tdiff, file.tbase + file.tdiff + file.tlen,
|
"text segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
||||||
file.tlen, file.tlen, file.tdiff, file.tdiff & 0xffff);
|
file.tbase + file.tdiff,
|
||||||
printf("data segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
file.tbase + file.tdiff + file.tlen,
|
||||||
file.dbase + file.ddiff, file.dbase + file.ddiff + file.dlen,
|
file.tlen, file.tlen, file.tdiff,
|
||||||
file.dlen, file.dlen, file.ddiff, file.ddiff & 0xffff);
|
file.tdiff & 0xffff);
|
||||||
printf("bss segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
printf(
|
||||||
file.bbase + file.bdiff, file.bbase + file.bdiff + file.blen,
|
"data segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
||||||
file.blen, file.blen, file.bdiff, file.bdiff & 0xffff);
|
file.dbase + file.ddiff,
|
||||||
printf("zero segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
file.dbase + file.ddiff + file.dlen,
|
||||||
file.zbase + file.zdiff, file.zbase + file.zdiff + file.zlen,
|
file.dlen, file.dlen, file.ddiff,
|
||||||
file.zlen, file.zlen, file.zdiff, file.zdiff & 0xffff);
|
file.ddiff & 0xffff);
|
||||||
|
printf(
|
||||||
|
"bss segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
||||||
|
file.bbase + file.bdiff,
|
||||||
|
file.bbase + file.bdiff + file.blen,
|
||||||
|
file.blen, file.blen, file.bdiff,
|
||||||
|
file.bdiff & 0xffff);
|
||||||
|
printf(
|
||||||
|
"zero segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
|
||||||
|
file.zbase + file.zdiff,
|
||||||
|
file.zbase + file.zdiff + file.zlen,
|
||||||
|
file.zlen, file.zlen, file.zdiff,
|
||||||
|
file.zdiff & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pointer of position in file */
|
/* pointer of position in file */
|
||||||
|
@ -368,16 +392,21 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "reloc65: %s: not an o65 file!\n", argv[i]);
|
fprintf(stderr, "reloc65: %s: not an o65 file!\n", argv[i]);
|
||||||
if(file.buf[0]==1 && file.buf[1]==8 && file.buf[3]==8) {
|
if (file.buf[0] == 1 && file.buf[1] == 8
|
||||||
printf("%s: C64 BASIC executable (start address $0801)?\n", argv[i]);
|
&& file.buf[3] == 8) {
|
||||||
} else
|
printf(
|
||||||
if(file.buf[0]==1 && file.buf[1]==4 && file.buf[3]==4) {
|
"%s: C64 BASIC executable (start address $0801)?\n",
|
||||||
printf("%s: CBM PET BASIC executable (start address $0401)?\n", argv[i]);
|
argv[i]);
|
||||||
|
} else if (file.buf[0] == 1 && file.buf[1] == 4
|
||||||
|
&& file.buf[3] == 4) {
|
||||||
|
printf(
|
||||||
|
"%s: CBM PET BASIC executable (start address $0401)?\n",
|
||||||
|
argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"reloc65: read '%s': %s\n",
|
fprintf(stderr, "reloc65: read '%s': %s\n", argv[i],
|
||||||
argv[i], strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -385,7 +414,6 @@ int main(int argc, char *argv[]) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int read_options(unsigned char *buf) {
|
int read_options(unsigned char *buf) {
|
||||||
int c, l = 0;
|
int c, l = 0;
|
||||||
|
|
||||||
|
@ -454,14 +482,17 @@ unsigned char *reloc_seg(unsigned char *buf, int len, unsigned char *rtab,
|
||||||
if (seg == 0) {
|
if (seg == 0) {
|
||||||
/* undefined segment entry */
|
/* undefined segment entry */
|
||||||
if (undefwarn) {
|
if (undefwarn) {
|
||||||
fprintf(stderr,"reloc65: %s: Warning: undefined relocation table entry not handled!\n", fp->fname);
|
fprintf(stderr,
|
||||||
|
"reloc65: %s: Warning: undefined relocation table entry not handled!\n",
|
||||||
|
fp->fname);
|
||||||
}
|
}
|
||||||
rtab += 2;
|
rtab += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (adr > len) {
|
if (adr > len) {
|
||||||
fprintf(stderr,"reloc65: %s: Warning: relocation table entries past segment end!\n",
|
fprintf(stderr,
|
||||||
|
"reloc65: %s: Warning: relocation table entries past segment end!\n",
|
||||||
fp->fname);
|
fp->fname);
|
||||||
fprintf(stderr, "reloc65: adr=%x len=%x\n", adr, len);
|
fprintf(stderr, "reloc65: adr=%x len=%x\n", adr, len);
|
||||||
}
|
}
|
||||||
|
@ -476,7 +507,8 @@ unsigned char *reloc_globals(unsigned char *buf, file65 *fp) {
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
/*printf("relocating %s, ", buf);*/
|
/*printf("relocating %s, ", buf);*/
|
||||||
while(*(buf++));
|
while (*(buf++))
|
||||||
|
;
|
||||||
seg = *buf;
|
seg = *buf;
|
||||||
old = buf[1] + 256 * buf[2];
|
old = buf[1] + 256 * buf[2];
|
||||||
new = old + reldiff(seg);
|
new = old + reldiff(seg);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
* Pack/Unpack cpk archive files
|
* Pack/Unpack cpk archive files
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-2002 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-2002 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -36,10 +36,8 @@ FILE *fp;
|
||||||
char name[100];
|
char name[100];
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
void usage(FILE *fp)
|
void usage(FILE *fp) {
|
||||||
{
|
fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n"
|
||||||
fprintf(fp,
|
|
||||||
"Usage: %s [OPTION]... [FILE]...\n"
|
|
||||||
"Manage c64 cpk archives\n"
|
"Manage c64 cpk archives\n"
|
||||||
"\n"
|
"\n"
|
||||||
" c create an archive\n"
|
" c create an archive\n"
|
||||||
|
@ -54,8 +52,7 @@ void usage(FILE *fp)
|
||||||
|
|
||||||
int list = 0, verbose = 0, add = 0, create = 0;
|
int list = 0, verbose = 0, add = 0, create = 0;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
int i, c, c2, fileok, nc;
|
int i, c, c2, fileok, nc;
|
||||||
size_t n, n2;
|
size_t n, n2;
|
||||||
FILE *fp, *fpo = NULL;
|
FILE *fp, *fpo = NULL;
|
||||||
|
@ -95,17 +92,19 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (add) {
|
if (add) {
|
||||||
fpo = fopen(argv[2], "ab");
|
fpo = fopen(argv[2], "ab");
|
||||||
} else
|
} else if (create) {
|
||||||
if(create) {
|
|
||||||
fpo = fopen(argv[2], "wb");
|
fpo = fopen(argv[2], "wb");
|
||||||
}
|
}
|
||||||
if (fpo) {
|
if (fpo) {
|
||||||
if(!add) fputc(1,fpo); /* Version Byte */
|
if (!add)
|
||||||
|
fputc(1, fpo); /* Version Byte */
|
||||||
for (i = 3; i < argc; i++) {
|
for (i = 3; i < argc; i++) {
|
||||||
if(verbose) printf("%s\n",argv[i]);
|
if (verbose)
|
||||||
|
printf("%s\n", argv[i]);
|
||||||
fp = fopen(argv[i], "rb");
|
fp = fopen(argv[i], "rb");
|
||||||
if (fp) {
|
if (fp) {
|
||||||
while((s=strchr(argv[i],':'))) *s='/';
|
while ((s = strchr(argv[i], ':')))
|
||||||
|
*s = '/';
|
||||||
fprintf(fpo, "%s", argv[i]);
|
fprintf(fpo, "%s", argv[i]);
|
||||||
fputc(0, fpo);
|
fputc(0, fpo);
|
||||||
c = fgetc(fp);
|
c = fgetc(fp);
|
||||||
|
@ -127,9 +126,11 @@ int main(int argc, char *argv[])
|
||||||
c = c2;
|
c = c2;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fputc(0xf7,fpo); fputc(0,fpo);
|
fputc(0xf7, fpo);
|
||||||
|
fputc(0, fpo);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"Couldn't open file '%s' for reading!",argv[i]);
|
fprintf(stderr, "Couldn't open file '%s' for reading!",
|
||||||
|
argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fpo);
|
fclose(fpo);
|
||||||
|
@ -148,19 +149,24 @@ int main(int argc, char *argv[])
|
||||||
/* read name */
|
/* read name */
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((c = fgetc(fp))) {
|
while ((c = fgetc(fp))) {
|
||||||
if(c==EOF) break;
|
if (c == EOF)
|
||||||
|
break;
|
||||||
name[i++] = c;
|
name[i++] = c;
|
||||||
}
|
}
|
||||||
name[i++] = '\0';
|
name[i++] = '\0';
|
||||||
if (!c) { /* end of archive ? */
|
if (!c) { /* end of archive ? */
|
||||||
while((s=strchr(name,'/'))) *s=':';
|
while ((s = strchr(name, '/')))
|
||||||
|
*s = ':';
|
||||||
|
|
||||||
if(verbose+list) printf("%s\n",name);
|
if (verbose + list)
|
||||||
|
printf("%s\n", name);
|
||||||
|
|
||||||
if (!list) {
|
if (!list) {
|
||||||
fpo = fopen(name, "wb");
|
fpo = fopen(name, "wb");
|
||||||
if (!fpo) {
|
if (!fpo) {
|
||||||
fprintf(stderr,"Couldn't open output file %s !\n",name);
|
fprintf(stderr,
|
||||||
|
"Couldn't open output file %s !\n",
|
||||||
|
name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileok = 0;
|
fileok = 0;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,18 +20,16 @@
|
||||||
#define __XA65_VERSION_H__
|
#define __XA65_VERSION_H__
|
||||||
|
|
||||||
void version(const char *programname, const char *progversion,
|
void version(const char *programname, const char *progversion,
|
||||||
const char *authors, const char *copyright)
|
const char *authors, const char *copyright) {
|
||||||
{
|
fprintf(stdout, "%s (xa65) %s\n"
|
||||||
fprintf(stdout,
|
|
||||||
"%s (xa65) %s\n"
|
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"This is free software; see the source for "
|
"This is free software; see the source for "
|
||||||
"copying conditions. There is NO\n"
|
"copying conditions. There is NO\n"
|
||||||
"warranty; not even for MERCHANTABILIY or "
|
"warranty; not even for MERCHANTABILIY or "
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n",
|
"FITNESS FOR A PARTICULAR PURPOSE.\n", programname, progversion,
|
||||||
programname, progversion, authors, copyright);
|
authors, copyright);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XA65_VERSION_H__ */
|
#endif /* __XA65_VERSION_H__ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,19 +19,17 @@
|
||||||
#ifndef __XA65_VERSION_H__
|
#ifndef __XA65_VERSION_H__
|
||||||
#define __XA65_VERSION_H__
|
#define __XA65_VERSION_H__
|
||||||
|
|
||||||
void version(const char *programname, const char *version,
|
void version(const char *programname, const char *version, const char *authors,
|
||||||
const char *authors, const char *copyright)
|
const char *copyright) {
|
||||||
{
|
fprintf(stdout, "%s (xa65) %s\n"
|
||||||
fprintf(stdout,
|
|
||||||
"%s (xa65) %s\n"
|
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"This is free software; see the source for "
|
"This is free software; see the source for "
|
||||||
"copying conditions. There is NO\n"
|
"copying conditions. There is NO\n"
|
||||||
"warranty; not even for MERCHANTABILIY or "
|
"warranty; not even for MERCHANTABILIY or "
|
||||||
"FITNESS FOR A PARTICULAR PURPOSE.\n",
|
"FITNESS FOR A PARTICULAR PURPOSE.\n", programname, version,
|
||||||
programname, version, authors, copyright);
|
authors, copyright);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XA65_VERSION_H__ */
|
#endif /* __XA65_VERSION_H__ */
|
||||||
|
|
425
xa/src/xa.c
425
xa/src/xa.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
* maintained by Cameron Kaiser (ckaiser@floodgap.com)
|
* maintained by Cameron Kaiser (ckaiser@floodgap.com)
|
||||||
*
|
*
|
||||||
* Main program
|
* Main program
|
||||||
|
@ -115,8 +115,7 @@ int relmode=0;
|
||||||
|
|
||||||
int pc[SEG_MAX]; /* segments */
|
int pc[SEG_MAX]; /* segments */
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
int er = 1, i;
|
int er = 1, i;
|
||||||
signed char *s = NULL;
|
signed char *s = NULL;
|
||||||
char *tmpp;
|
char *tmpp;
|
||||||
|
@ -161,11 +160,8 @@ int main(int argc,char *argv[])
|
||||||
} else {
|
} else {
|
||||||
tmpp = argv[0];
|
tmpp = argv[0];
|
||||||
}
|
}
|
||||||
if( (!strcmp(tmpp,"xa65816"))
|
if ((!strcmp(tmpp, "xa65816")) || (!strcmp(tmpp, "XA65816"))
|
||||||
|| (!strcmp(tmpp,"XA65816"))
|
|| (!strcmp(tmpp, "xa816")) || (!strcmp(tmpp, "XA816"))) {
|
||||||
|| (!strcmp(tmpp,"xa816"))
|
|
||||||
|| (!strcmp(tmpp,"XA816"))
|
|
||||||
) {
|
|
||||||
w65816 = 1; /* allow 65816 per default */
|
w65816 = 1; /* allow 65816 per default */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +229,8 @@ int main(int argc,char *argv[])
|
||||||
"warning: extra characters to -p ignored\n");
|
"warning: extra characters to -p ignored\n");
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
fprintf(stderr, "Warning: -M is deprecated (use -XMASM) and will be removed in a future version\n");
|
fprintf(stderr,
|
||||||
|
"Warning: -M is deprecated (use -XMASM) and will be removed in a future version\n");
|
||||||
masm = 1; /* MASM compatibility mode */
|
masm = 1; /* MASM compatibility mode */
|
||||||
break;
|
break;
|
||||||
case 'X': /* compatibility across assemblers... */
|
case 'X': /* compatibility across assemblers... */
|
||||||
|
@ -245,7 +242,9 @@ int main(int argc,char *argv[])
|
||||||
name = argv[i] + 2;
|
name = argv[i] + 2;
|
||||||
}
|
}
|
||||||
if (set_compat(name) < 0) {
|
if (set_compat(name) < 0) {
|
||||||
fprintf(stderr, "Compatibility set '%s' unknown - ignoring! (check case?)\n", name);
|
fprintf(stderr,
|
||||||
|
"Compatibility set '%s' unknown - ignoring! (check case?)\n",
|
||||||
|
name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -253,7 +252,8 @@ int main(int argc,char *argv[])
|
||||||
{
|
{
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
if (argv[i][2] == 0) {
|
if (argv[i][2] == 0) {
|
||||||
if (i + 1 < argc) name = argv[++i];
|
if (i + 1 < argc)
|
||||||
|
name = argv[++i];
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "-O requires an argument\n");
|
fprintf(stderr, "-O requires an argument\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -262,7 +262,9 @@ int main(int argc,char *argv[])
|
||||||
name = argv[i] + 2;
|
name = argv[i] + 2;
|
||||||
}
|
}
|
||||||
if (set_charset(name) < 0) {
|
if (set_charset(name) < 0) {
|
||||||
fprintf(stderr, "Output charset name '%s' unknown - ignoring! (check case?)\n", name);
|
fprintf(stderr,
|
||||||
|
"Output charset name '%s' unknown - ignoring! (check case?)\n",
|
||||||
|
name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -270,19 +272,21 @@ int main(int argc,char *argv[])
|
||||||
is not necessary when _file_ starts at adr */
|
is not necessary when _file_ starts at adr */
|
||||||
romable = 2;
|
romable = 2;
|
||||||
if (argv[i][2] == 0) {
|
if (argv[i][2] == 0) {
|
||||||
if (i + 1 < argc) romaddr = atoi(argv[++i]);
|
if (i + 1 < argc)
|
||||||
|
romaddr = atoi(argv[++i]);
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "-A requires an argument\n");
|
fprintf(stderr, "-A requires an argument\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else romaddr = atoi(argv[i]+2);
|
romaddr = atoi(argv[i] + 2);
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
noglob = 1;
|
noglob = 1;
|
||||||
break;
|
break;
|
||||||
case 'L': /* define global label */
|
case 'L': /* define global label */
|
||||||
if(argv[i][2]) lg_set(argv[i]+2);
|
if (argv[i][2])
|
||||||
|
lg_set(argv[i] + 2);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
crossref = 1;
|
crossref = 1;
|
||||||
|
@ -295,7 +299,8 @@ int main(int argc,char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
s = (signed char*) strstr(argv[i] + 2, "=");
|
s = (signed char*) strstr(argv[i] + 2, "=");
|
||||||
if(s) *s = ' ';
|
if (s)
|
||||||
|
*s = ' ';
|
||||||
pp_define(argv[i] + 2);
|
pp_define(argv[i] + 2);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
|
@ -336,7 +341,8 @@ int main(int argc,char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
if (argv[i][2] == 0) {
|
if (argv[i][2] == 0) {
|
||||||
if (i + 1 < argc) reg_include(argv[++i]);
|
if (i + 1 < argc)
|
||||||
|
reg_include(argv[++i]);
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "-I requires an argument\n");
|
fprintf(stderr, "-I requires an argument\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -361,7 +367,8 @@ int main(int argc,char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (argv[i][2] == 0) {
|
if (argv[i][2] == 0) {
|
||||||
if (i + 1 < argc) ofile=argv[++i];
|
if (i + 1 < argc)
|
||||||
|
ofile = argv[++i];
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "-o requires an argument\n");
|
fprintf(stderr, "-o requires an argument\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -372,7 +379,8 @@ int main(int argc,char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (argv[i][2] == 0) {
|
if (argv[i][2] == 0) {
|
||||||
if (i + 1 < argc) lfile=argv[++i];
|
if (i + 1 < argc)
|
||||||
|
lfile = argv[++i];
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "-l requires an argument\n");
|
fprintf(stderr, "-l requires an argument\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -383,7 +391,8 @@ int main(int argc,char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (argv[i][2] == 0) {
|
if (argv[i][2] == 0) {
|
||||||
if (i + 1 < argc) efile=argv[++i];
|
if (i + 1 < argc)
|
||||||
|
efile = argv[++i];
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "-e requires an argument\n");
|
fprintf(stderr, "-e requires an argument\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -395,20 +404,28 @@ int main(int argc,char *argv[])
|
||||||
case 'b': /* set segment base addresses */
|
case 'b': /* set segment base addresses */
|
||||||
switch (argv[i][2]) {
|
switch (argv[i][2]) {
|
||||||
case 't':
|
case 't':
|
||||||
if(argv[i][3]==0) tbase = atoi(argv[++i]);
|
if (argv[i][3] == 0)
|
||||||
else tbase = atoi(argv[i]+3);
|
tbase = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
tbase = atoi(argv[i] + 3);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
if(argv[i][3]==0) dbase = atoi(argv[++i]);
|
if (argv[i][3] == 0)
|
||||||
else dbase = atoi(argv[i]+3);
|
dbase = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
dbase = atoi(argv[i] + 3);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if(argv[i][3]==0) bbase = atoi(argv[++i]);
|
if (argv[i][3] == 0)
|
||||||
else bbase = atoi(argv[i]+3);
|
bbase = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
bbase = atoi(argv[i] + 3);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
if(argv[i][3]==0) zbase = atoi(argv[++i]);
|
if (argv[i][3] == 0)
|
||||||
else zbase = atoi(argv[i]+3);
|
zbase = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
zbase = atoi(argv[i] + 3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown segment type '%c' - ignoring!\n",
|
fprintf(stderr, "unknown segment type '%c' - ignoring!\n",
|
||||||
|
@ -417,10 +434,12 @@ int main(int argc,char *argv[])
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
fprintf(stderr, "Single dash '-' on command line - ignoring!\n");
|
fprintf(stderr,
|
||||||
|
"Single dash '-' on command line - ignoring!\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unknown option '%c' - ignoring!\n",argv[i][1]);
|
fprintf(stderr, "Unknown option '%c' - ignoring!\n",
|
||||||
|
argv[i][1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { /* no option -> filename */
|
} else { /* no option -> filename */
|
||||||
|
@ -429,7 +448,8 @@ int main(int argc,char *argv[])
|
||||||
mifiles += 5;
|
mifiles += 5;
|
||||||
ifiles = realloc(ifiles, mifiles * sizeof(char*));
|
ifiles = realloc(ifiles, mifiles * sizeof(char*));
|
||||||
if (!ifiles) {
|
if (!ifiles) {
|
||||||
fprintf(stderr, "Oops: couldn't alloc enough mem for filelist table..!\n");
|
fprintf(stderr,
|
||||||
|
"Oops: couldn't alloc enough mem for filelist table..!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +461,8 @@ int main(int argc,char *argv[])
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verbose) fprintf(stderr, "%s\n",copyright);
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s\n", copyright);
|
||||||
|
|
||||||
if (printfile != NULL && !strcmp(printfile, "-")) {
|
if (printfile != NULL && !strcmp(printfile, "-")) {
|
||||||
printfile = NULL;
|
printfile = NULL;
|
||||||
|
@ -462,27 +483,26 @@ int main(int argc,char *argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(verbose) fprintf(stderr, "%s\n",copyright);
|
if (verbose)
|
||||||
|
fprintf(stderr, "%s\n", copyright);
|
||||||
|
|
||||||
if(1 /*!m_init()*/)
|
if (1 /*!m_init()*/) {
|
||||||
{
|
if (1 /*!b_init()*/) {
|
||||||
if(1 /*!b_init()*/)
|
if (1 /*!l_init()*/) {
|
||||||
{
|
|
||||||
if(1 /*!l_init()*/)
|
|
||||||
{
|
|
||||||
/*if(!pp_init())*/
|
/*if(!pp_init())*/
|
||||||
{
|
{
|
||||||
if(!x_init())
|
if (!x_init()) {
|
||||||
{
|
|
||||||
/* if(fperr) fprintf(fperr,"%s\n",copyright); */
|
/* if(fperr) fprintf(fperr,"%s\n",copyright); */
|
||||||
if(verbose) logout(ctime(&tim1));
|
if (verbose)
|
||||||
|
logout(ctime(&tim1));
|
||||||
|
|
||||||
list_setfile(fplist);
|
list_setfile(fplist);
|
||||||
|
|
||||||
/* Pass 1 */
|
/* Pass 1 */
|
||||||
|
|
||||||
pc[SEG_ABS] = 0; /* abs addressing */
|
pc[SEG_ABS] = 0; /* abs addressing */
|
||||||
seg_start(fmode, tbase, dbase, bbase, zbase, 0, relmode);
|
seg_start(fmode, tbase, dbase, bbase, zbase, 0,
|
||||||
|
relmode);
|
||||||
|
|
||||||
if (relmode) {
|
if (relmode) {
|
||||||
r_mode(RMODE_RELOC);
|
r_mode(RMODE_RELOC);
|
||||||
|
@ -495,62 +515,79 @@ int main(int argc,char *argv[])
|
||||||
|
|
||||||
nolink = no_link;
|
nolink = no_link;
|
||||||
|
|
||||||
for (i=0; i<nifiles; i++)
|
for (i = 0; i < nifiles; i++) {
|
||||||
{
|
|
||||||
ifile = ifiles[i];
|
ifile = ifiles[i];
|
||||||
|
|
||||||
sprintf(out, "xAss65: Pass 1: %s\n", ifile);
|
sprintf(out, "xAss65: Pass 1: %s\n", ifile);
|
||||||
if(verbose) logout(out);
|
if (verbose)
|
||||||
|
logout(out);
|
||||||
|
|
||||||
er = pp_open(ifile);
|
er = pp_open(ifile);
|
||||||
puttmpw(0);
|
puttmpw(0);
|
||||||
puttmp(T_FILE);
|
puttmp(T_FILE);
|
||||||
puttmp(0);
|
puttmp(0);
|
||||||
puttmp(0);
|
puttmp(0);
|
||||||
puttmps((signed char*)&ifile, sizeof(filep->fname));
|
puttmps((signed char*) &ifile,
|
||||||
|
sizeof(filep->fname));
|
||||||
|
|
||||||
if (!er) {
|
if (!er) {
|
||||||
er = pass1();
|
er = pass1();
|
||||||
pp_close();
|
pp_close();
|
||||||
} else {
|
} else {
|
||||||
sprintf(out, "Couldn't open source file '%s'!\n", ifile);
|
sprintf(out,
|
||||||
|
"Couldn't open source file '%s'!\n",
|
||||||
|
ifile);
|
||||||
logout(out);
|
logout(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((er = b_depth())) {
|
if ((er = b_depth())) {
|
||||||
sprintf(out,"Still %d blocks open at end of file!\n",er);
|
sprintf(out,
|
||||||
|
"Still %d blocks open at end of file!\n",
|
||||||
|
er);
|
||||||
logout(out);
|
logout(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tbase & (align - 1)) {
|
if (tbase & (align - 1)) {
|
||||||
sprintf(out,"Warning: text segment ($%04x) start address doesn't align to %d!\n", tbase, align);
|
sprintf(out,
|
||||||
|
"Warning: text segment ($%04x) start address doesn't align to %d!\n",
|
||||||
|
tbase, align);
|
||||||
logout(out);
|
logout(out);
|
||||||
}
|
}
|
||||||
if (dbase & (align - 1)) {
|
if (dbase & (align - 1)) {
|
||||||
sprintf(out,"Warning: data segment ($%04x) start address doesn't align to %d!\n", dbase, align);
|
sprintf(out,
|
||||||
|
"Warning: data segment ($%04x) start address doesn't align to %d!\n",
|
||||||
|
dbase, align);
|
||||||
logout(out);
|
logout(out);
|
||||||
}
|
}
|
||||||
if (bbase & (align - 1)) {
|
if (bbase & (align - 1)) {
|
||||||
sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align);
|
sprintf(out,
|
||||||
|
"Warning: bss segment ($%04x) start address doesn't align to %d!\n",
|
||||||
|
bbase, align);
|
||||||
logout(out);
|
logout(out);
|
||||||
}
|
}
|
||||||
if (n65816 > 0)
|
if (n65816 > 0)
|
||||||
fmode |= 0x8000;
|
fmode |= 0x8000;
|
||||||
switch (align) {
|
switch (align) {
|
||||||
case 1: break;
|
case 1:
|
||||||
case 2: fmode |= 1; break;
|
break;
|
||||||
case 4: fmode |= 2; break;
|
case 2:
|
||||||
case 256: fmode |=3; break;
|
fmode |= 1;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
fmode |= 2;
|
||||||
|
break;
|
||||||
|
case 256:
|
||||||
|
fmode |= 3;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!er) && relmode)
|
if ((!er) && relmode)
|
||||||
h_write(fpout, fmode, tlen, dlen, blen, zlen, 0);
|
h_write(fpout, fmode, tlen, dlen, blen, zlen, 0);
|
||||||
|
|
||||||
|
if (!er) {
|
||||||
if(!er)
|
if (verbose)
|
||||||
{
|
logout("xAss65: Pass 2:\n");
|
||||||
if(verbose) logout("xAss65: Pass 2:\n");
|
|
||||||
|
|
||||||
list_start(listformat);
|
list_start(listformat);
|
||||||
|
|
||||||
|
@ -569,16 +606,23 @@ int main(int argc,char *argv[])
|
||||||
list_end();
|
list_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fplab) printllist(fplab);
|
if (fplab)
|
||||||
|
printllist(fplab);
|
||||||
tim2 = time(NULL);
|
tim2 = time(NULL);
|
||||||
if(verbose) printstat();
|
if (verbose)
|
||||||
|
printstat();
|
||||||
|
|
||||||
if((!er) && relmode) seg_end(fpout); /* write reloc/label info */
|
if ((!er) && relmode)
|
||||||
|
seg_end(fpout); /* write reloc/label info */
|
||||||
|
|
||||||
if(fplist && fplist!=stdout) fclose(fplist);
|
if (fplist && fplist != stdout)
|
||||||
if(fperr) fclose(fperr);
|
fclose(fplist);
|
||||||
if(fplab) fclose(fplab);
|
if (fperr)
|
||||||
if(fpout && fpout!=stdout) fclose(fpout);
|
fclose(fperr);
|
||||||
|
if (fplab)
|
||||||
|
fclose(fplab);
|
||||||
|
if (fpout && fpout != stdout)
|
||||||
|
fclose(fpout);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logout("fatal: x: no memory!\n");
|
logout("fatal: x: no memory!\n");
|
||||||
|
@ -598,8 +642,7 @@ int main(int argc,char *argv[])
|
||||||
logout("Not enough memory available!\n");
|
logout("Not enough memory available!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ner || er)
|
if (ner || er) {
|
||||||
{
|
|
||||||
if (ner_max > 0) {
|
if (ner_max > 0) {
|
||||||
fprintf(stderr, "Break after %d error%c\n", ner, ner ? 's' : 0);
|
fprintf(stderr, "Break after %d error%c\n", ner, ner ? 's' : 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -617,39 +660,41 @@ int main(int argc,char *argv[])
|
||||||
return ((er || ner) ? 1 : 0);
|
return ((er || ner) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printstat(void)
|
static void printstat(void) {
|
||||||
{
|
|
||||||
logout("Statistics:\n");
|
logout("Statistics:\n");
|
||||||
sprintf(out," %8d of %8d label used\n",ga_lab(),gm_lab()); logout(out);
|
sprintf(out, " %8d of %8d label used\n", ga_lab(), gm_lab());
|
||||||
sprintf(out," %8ld of %8ld byte label-memory used\n",ga_labm(),gm_labm()); logout(out);
|
logout(out);
|
||||||
sprintf(out," %8d of %8d PP-defs used\n",ga_pp(),gm_pp()); logout(out);
|
sprintf(out, " %8ld of %8ld byte label-memory used\n", ga_labm(),
|
||||||
sprintf(out," %8ld of %8ld byte PP-memory used\n",ga_ppm(),gm_ppm()); logout(out);
|
gm_labm());
|
||||||
sprintf(out," %8ld of %8ld byte buffer memory used\n",ga_p1(),gm_p1()); logout(out);
|
logout(out);
|
||||||
sprintf(out," %8d blocks used\n",ga_blk()); logout(out);
|
sprintf(out, " %8d of %8d PP-defs used\n", ga_pp(), gm_pp());
|
||||||
sprintf(out," %8ld seconds used\n",(long)difftime(tim2,tim1)); logout(out);
|
logout(out);
|
||||||
|
sprintf(out, " %8ld of %8ld byte PP-memory used\n", ga_ppm(), gm_ppm());
|
||||||
|
logout(out);
|
||||||
|
sprintf(out, " %8ld of %8ld byte buffer memory used\n", ga_p1(), gm_p1());
|
||||||
|
logout(out);
|
||||||
|
sprintf(out, " %8d blocks used\n", ga_blk());
|
||||||
|
logout(out);
|
||||||
|
sprintf(out, " %8ld seconds used\n", (long) difftime(tim2, tim1));
|
||||||
|
logout(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
int h_length(void) {
|
int h_length(void) {
|
||||||
return 26 + o_length();
|
return 26 + o_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setfext(char *s, char *ext) {
|
||||||
static int setfext(char *s, char *ext)
|
|
||||||
{
|
|
||||||
int j, i = (int) strlen(s);
|
int j, i = (int) strlen(s);
|
||||||
|
|
||||||
if (i > MAXLINE - 5)
|
if (i > MAXLINE - 5)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
for(j=i-1;j>=0;j--)
|
for (j = i - 1; j >= 0; j--) {
|
||||||
{
|
if (s[j] == DIRCHAR) {
|
||||||
if(s[j]==DIRCHAR)
|
|
||||||
{
|
|
||||||
strcpy(s + i, ext);
|
strcpy(s + i, ext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(s[j]=='.')
|
if (s[j] == '.') {
|
||||||
{
|
|
||||||
strcpy(s + j, ext);
|
strcpy(s + j, ext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -660,18 +705,14 @@ static int setfext(char *s, char *ext)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long ga_p1(void) {
|
||||||
static long ga_p1(void)
|
|
||||||
{
|
|
||||||
return (afile->mn.tmpz);
|
return (afile->mn.tmpz);
|
||||||
}
|
}
|
||||||
static long gm_p1(void)
|
static long gm_p1(void) {
|
||||||
{
|
|
||||||
return (TMPMEM);
|
return (TMPMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pass2(void)
|
static int pass2(void) {
|
||||||
{
|
|
||||||
int c, er, l, ll, i, al;
|
int c, er, l, ll, i, al;
|
||||||
Datei datei;
|
Datei datei;
|
||||||
signed char *dataseg = NULL;
|
signed char *dataseg = NULL;
|
||||||
|
@ -689,8 +730,7 @@ static int pass2(void)
|
||||||
filep = &datei;
|
filep = &datei;
|
||||||
afile->mn.tmpe = 0L;
|
afile->mn.tmpe = 0L;
|
||||||
|
|
||||||
while((ner_max==0 || ner<ner_max) && afile->mn.tmpe<afile->mn.tmpz)
|
while ((ner_max == 0 || ner < ner_max) && afile->mn.tmpe < afile->mn.tmpz) {
|
||||||
{
|
|
||||||
// get the length of the entry (now two byte - need to handle the sign)
|
// get the length of the entry (now two byte - need to handle the sign)
|
||||||
l = 255 & afile->mn.tmp[afile->mn.tmpe++];
|
l = 255 & afile->mn.tmp[afile->mn.tmpe++];
|
||||||
l |= afile->mn.tmp[afile->mn.tmpe++] << 8;
|
l |= afile->mn.tmp[afile->mn.tmpe++] << 8;
|
||||||
|
@ -698,37 +738,32 @@ static int pass2(void)
|
||||||
|
|
||||||
//printf("%p: l=%d first=%02x\n", afile->mn.tmp+afile->mn.tmpe-1, l, 0xff & afile->mn.tmp[afile->mn.tmpe]);
|
//printf("%p: l=%d first=%02x\n", afile->mn.tmp+afile->mn.tmpe-1, l, 0xff & afile->mn.tmp[afile->mn.tmpe]);
|
||||||
|
|
||||||
if(!l)
|
if (!l) {
|
||||||
{
|
if (afile->mn.tmp[afile->mn.tmpe] == T_LINE) {
|
||||||
if(afile->mn.tmp[afile->mn.tmpe]==T_LINE)
|
datei.fline = (afile->mn.tmp[afile->mn.tmpe + 1] & 255)
|
||||||
{
|
+ (afile->mn.tmp[afile->mn.tmpe + 2] << 8);
|
||||||
datei.fline=(afile->mn.tmp[afile->mn.tmpe+1]&255)+(afile->mn.tmp[afile->mn.tmpe+2]<<8);
|
|
||||||
afile->mn.tmpe += 3;
|
afile->mn.tmpe += 3;
|
||||||
list_line(datei.fline); /* set line number of next listing output */
|
list_line(datei.fline); /* set line number of next listing output */
|
||||||
} else
|
} else if (afile->mn.tmp[afile->mn.tmpe] == T_FILE) {
|
||||||
if(afile->mn.tmp[afile->mn.tmpe]==T_FILE)
|
|
||||||
{
|
|
||||||
// copy the current line number from the current file descriptor
|
// copy the current line number from the current file descriptor
|
||||||
datei.fline=(afile->mn.tmp[afile->mn.tmpe+1]&255)+(afile->mn.tmp[afile->mn.tmpe+2]<<8);
|
datei.fline = (afile->mn.tmp[afile->mn.tmpe + 1] & 255)
|
||||||
|
+ (afile->mn.tmp[afile->mn.tmpe + 2] << 8);
|
||||||
// copy the pointer to the file name in the current file descriptor
|
// copy the pointer to the file name in the current file descriptor
|
||||||
// Note: the filename in the current file descriptor is separately malloc'd and
|
// Note: the filename in the current file descriptor is separately malloc'd and
|
||||||
// thus save to store the pointer
|
// thus save to store the pointer
|
||||||
memcpy(&datei.fname, afile->mn.tmp+afile->mn.tmpe+3, sizeof(datei.fname));
|
memcpy(&datei.fname, afile->mn.tmp + afile->mn.tmpe + 3,
|
||||||
|
sizeof(datei.fname));
|
||||||
afile->mn.tmpe += 3 + sizeof(datei.fname);
|
afile->mn.tmpe += 3 + sizeof(datei.fname);
|
||||||
|
|
||||||
list_filename(datei.fname); /* set file name of next listing output */
|
list_filename(datei.fname); /* set file name of next listing output */
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
/* do not attempt address mode optimization on pass 2 */
|
/* do not attempt address mode optimization on pass 2 */
|
||||||
|
|
||||||
/* t_p2_l() includes the listing call to do_listing() */
|
/* t_p2_l() includes the listing call to do_listing() */
|
||||||
er = t_p2_l(afile->mn.tmp + afile->mn.tmpe, &ll, &al);
|
er = t_p2_l(afile->mn.tmp + afile->mn.tmpe, &ll, &al);
|
||||||
if(er==E_NOLINE)
|
if (er == E_NOLINE) {
|
||||||
{
|
} else if (er == E_OK) {
|
||||||
} else
|
|
||||||
if(er==E_OK)
|
|
||||||
{
|
|
||||||
if (segment < SEG_DATA) {
|
if (segment < SEG_DATA) {
|
||||||
for (i = 0; i < ll; i++)
|
for (i = 0; i < ll; i++)
|
||||||
chrput(afile->mn.tmp[afile->mn.tmpe + i]);
|
chrput(afile->mn.tmp[afile->mn.tmpe + i]);
|
||||||
|
@ -736,9 +771,7 @@ static int pass2(void)
|
||||||
memcpy(datap, afile->mn.tmp + afile->mn.tmpe, ll);
|
memcpy(datap, afile->mn.tmp + afile->mn.tmpe, ll);
|
||||||
datap += ll;
|
datap += ll;
|
||||||
}
|
}
|
||||||
} else
|
} else if (er == E_DSB) {
|
||||||
if(er==E_DSB)
|
|
||||||
{
|
|
||||||
c = afile->mn.tmp[afile->mn.tmpe];
|
c = afile->mn.tmp[afile->mn.tmpe];
|
||||||
if (segment < SEG_DATA) {
|
if (segment < SEG_DATA) {
|
||||||
/*printf("E_DSB, ll=%d, l=%d, c=%c\n",ll,l,afile->mn.tmp[afile->mn.tmpe]);*/
|
/*printf("E_DSB, ll=%d, l=%d, c=%c\n",ll,l,afile->mn.tmp[afile->mn.tmpe]);*/
|
||||||
|
@ -765,15 +798,14 @@ fprintf(stderr, "%i: %02x\n", i, afile->mn.tmp[afile->mn.tmpe+i]);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
offset = afile->mn.tmp[i] +
|
offset = afile->mn.tmp[i] + (afile->mn.tmp[i + 1] << 8)
|
||||||
(afile->mn.tmp[i+1] << 8) +
|
+ (afile->mn.tmp[i + 2] << 16);
|
||||||
(afile->mn.tmp[i+2] << 16);
|
fstart = afile->mn.tmp[i + 3] + 1 + (afile->mn.tmp[i + 4] << 8);
|
||||||
fstart = afile->mn.tmp[i+3] + 1 +
|
|
||||||
(afile->mn.tmp[i+4] << 8);
|
|
||||||
/* usually redundant but here for single-char names
|
/* usually redundant but here for single-char names
|
||||||
that get interpreted as chars */
|
that get interpreted as chars */
|
||||||
flen = afile->mn.tmp[i + 5];
|
flen = afile->mn.tmp[i + 5];
|
||||||
if (flen > 1) fstart++;
|
if (flen > 1)
|
||||||
|
fstart++;
|
||||||
/* now fstart points either to string past quote and
|
/* now fstart points either to string past quote and
|
||||||
length mark, OR, single char byte */
|
length mark, OR, single char byte */
|
||||||
/*
|
/*
|
||||||
|
@ -818,16 +850,15 @@ fprintf(stderr, "offset = %i length = %i fstart = %i flen = %i charo = %c\n",
|
||||||
}
|
}
|
||||||
if (relmode) {
|
if (relmode) {
|
||||||
if ((ll = fwrite(dataseg, 1, dlen, fpout)) < dlen) {
|
if ((ll = fwrite(dataseg, 1, dlen, fpout)) < dlen) {
|
||||||
fprintf(stderr, "Problems writing %d bytes, return gives %d\n",dlen,ll);
|
fprintf(stderr, "Problems writing %d bytes, return gives %d\n",
|
||||||
|
dlen, ll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ner);
|
return (ner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pass1(void) {
|
||||||
static int pass1(void)
|
|
||||||
{
|
|
||||||
signed char o[2 * MAXLINE]; /* doubled for token listing */
|
signed char o[2 * MAXLINE]; /* doubled for token listing */
|
||||||
int l, er, al;
|
int l, er, al;
|
||||||
|
|
||||||
|
@ -837,38 +868,39 @@ static int pass1(void)
|
||||||
ner = 0;
|
ner = 0;
|
||||||
|
|
||||||
/*FIXIT*/
|
/*FIXIT*/
|
||||||
while(!(er=xa_getline(s)))
|
while (!(er = xa_getline(s))) {
|
||||||
{
|
|
||||||
er = t_p1((signed char*) s, o, &l, &al);
|
er = t_p1((signed char*) s, o, &l, &al);
|
||||||
switch (segment) {
|
switch (segment) {
|
||||||
case SEG_ABS:
|
case SEG_ABS:
|
||||||
case SEG_TEXT: tlen += al; break;
|
case SEG_TEXT:
|
||||||
case SEG_DATA: dlen += al; break;
|
tlen += al;
|
||||||
case SEG_BSS : blen += al; break;
|
break;
|
||||||
case SEG_ZERO: zlen += al; break;
|
case SEG_DATA:
|
||||||
|
dlen += al;
|
||||||
|
break;
|
||||||
|
case SEG_BSS:
|
||||||
|
blen += al;
|
||||||
|
break;
|
||||||
|
case SEG_ZERO:
|
||||||
|
zlen += al;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf(": er= %d, l=%d\n",er,l);
|
//printf(": er= %d, l=%d\n",er,l);
|
||||||
|
|
||||||
if(l)
|
if (l) {
|
||||||
{
|
if (er) {
|
||||||
if(er)
|
if (er == E_OKDEF) {
|
||||||
{
|
|
||||||
if(er==E_OKDEF)
|
|
||||||
{
|
|
||||||
if (!(er = puttmpw(l)))
|
if (!(er = puttmpw(l)))
|
||||||
er = puttmps(o, l);
|
er = puttmps(o, l);
|
||||||
} else
|
} else if (er == E_NOLINE)
|
||||||
if(er==E_NOLINE)
|
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
if (!(er = puttmpw(-l)))
|
if (!(er = puttmpw(-l)))
|
||||||
er = puttmps(o, l);
|
er = puttmps(o, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(er)
|
if (er) {
|
||||||
{
|
|
||||||
lineout();
|
lineout();
|
||||||
errout(er);
|
errout(er);
|
||||||
}
|
}
|
||||||
|
@ -881,8 +913,6 @@ static int pass1(void)
|
||||||
errout(er);
|
errout(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* { int i; printf("Pass 1 \n");
|
/* { int i; printf("Pass 1 \n");
|
||||||
for(i=0;i<afile->mn.tmpz;i++)
|
for(i=0;i<afile->mn.tmpz;i++)
|
||||||
fprintf(stderr, " %02x",255 & afile->mn.tmp[i]);
|
fprintf(stderr, " %02x",255 & afile->mn.tmp[i]);
|
||||||
|
@ -891,21 +921,17 @@ static int pass1(void)
|
||||||
return (ner);
|
return (ner);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage(int default816, FILE *fp)
|
static void usage(int default816, FILE *fp) {
|
||||||
{
|
fprintf(fp, "Usage: %s [options] file\n"
|
||||||
fprintf(fp,
|
|
||||||
"Usage: %s [options] file\n"
|
|
||||||
"Cross-assembler for 65xx/R65C02/65816\n"
|
"Cross-assembler for 65xx/R65C02/65816\n"
|
||||||
"\n",
|
"\n",
|
||||||
programname);
|
programname);
|
||||||
fprintf(fp,
|
fprintf(fp, " -v verbose output\n"
|
||||||
" -v verbose output\n"
|
|
||||||
" -E do not break after 20 errors, but show all\n"
|
" -E do not break after 20 errors, but show all\n"
|
||||||
" -C no CMOS-opcodes\n"
|
" -C no CMOS-opcodes\n"
|
||||||
" -W no 65816-opcodes%s\n"
|
" -W no 65816-opcodes%s\n"
|
||||||
" -w allow 65816-opcodes%s\n",
|
" -w allow 65816-opcodes%s\n",
|
||||||
default816 ? "" : " (default)",
|
default816 ? "" : " (default)", default816 ? " (default)" : "");
|
||||||
default816 ? " (default)" : "");
|
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
" -B show lines with block open/close\n"
|
" -B show lines with block open/close\n"
|
||||||
" -c produce `o65' object instead of executable files (i.e. don't link)\n"
|
" -c produce `o65' object instead of executable files (i.e. don't link)\n"
|
||||||
|
@ -944,8 +970,7 @@ static void usage(int default816, FILE *fp)
|
||||||
" --help display this help and exit\n");
|
" --help display this help and exit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *ertxt[] = {
|
static char *ertxt[] = { "Syntax", // E_SYNTAX =-1
|
||||||
"Syntax", // E_SYNTAX =-1
|
|
||||||
"Label already defined", // E_LABDEF =-2
|
"Label already defined", // E_LABDEF =-2
|
||||||
"Label not defined", // E_NODEF =-3
|
"Label not defined", // E_NODEF =-3
|
||||||
"Label table full", // E_LABFULL =-4
|
"Label table full", // E_LABFULL =-4
|
||||||
|
@ -1031,8 +1056,7 @@ static char *ertxt[] = {
|
||||||
static int gl;
|
static int gl;
|
||||||
static int gf;
|
static int gf;
|
||||||
|
|
||||||
static int x_init(void)
|
static int x_init(void) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
#if 0
|
#if 0
|
||||||
int er=0;
|
int er=0;
|
||||||
|
@ -1044,28 +1068,24 @@ static int x_init(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int puttmp(int c)
|
static int puttmp(int c) {
|
||||||
{
|
|
||||||
int er = E_NOMEM;
|
int er = E_NOMEM;
|
||||||
|
|
||||||
//printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz);
|
//printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz);
|
||||||
|
|
||||||
if(afile->mn.tmpz<TMPMEM)
|
if (afile->mn.tmpz < TMPMEM) {
|
||||||
{
|
|
||||||
afile->mn.tmp[afile->mn.tmpz++] = c;
|
afile->mn.tmp[afile->mn.tmpz++] = c;
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
}
|
}
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int puttmpw(int c)
|
static int puttmpw(int c) {
|
||||||
{
|
|
||||||
int er = E_NOMEM;
|
int er = E_NOMEM;
|
||||||
|
|
||||||
//printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz);
|
//printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz);
|
||||||
|
|
||||||
if(afile->mn.tmpz<TMPMEM-1)
|
if (afile->mn.tmpz < TMPMEM - 1) {
|
||||||
{
|
|
||||||
afile->mn.tmp[afile->mn.tmpz++] = c & 0xff;
|
afile->mn.tmp[afile->mn.tmpz++] = c & 0xff;
|
||||||
afile->mn.tmp[afile->mn.tmpz++] = (c >> 8) & 0xff;
|
afile->mn.tmp[afile->mn.tmpz++] = (c >> 8) & 0xff;
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
|
@ -1073,14 +1093,12 @@ static int puttmpw(int c)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int puttmps(signed char *s, int l)
|
static int puttmps(signed char *s, int l) {
|
||||||
{
|
|
||||||
int i = 0, er = E_NOMEM;
|
int i = 0, er = E_NOMEM;
|
||||||
|
|
||||||
// printf("puttmps %d bytes from %p to %p:", l, s, afile->mn.tmp+afile->mn.tmpz);
|
// printf("puttmps %d bytes from %p to %p:", l, s, afile->mn.tmp+afile->mn.tmpz);
|
||||||
|
|
||||||
if(afile->mn.tmpz+l<TMPMEM)
|
if (afile->mn.tmpz + l < TMPMEM) {
|
||||||
{
|
|
||||||
while (i < l) {
|
while (i < l) {
|
||||||
//printf(" %02x", 0xff & s[i]);
|
//printf(" %02x", 0xff & s[i]);
|
||||||
afile->mn.tmp[afile->mn.tmpz++] = s[i++];
|
afile->mn.tmp[afile->mn.tmpz++] = s[i++];
|
||||||
|
@ -1094,8 +1112,7 @@ static int puttmps(signed char *s, int l)
|
||||||
|
|
||||||
static char l[MAXLINE];
|
static char l[MAXLINE];
|
||||||
|
|
||||||
static int xa_getline(char *s)
|
static int xa_getline(char *s) {
|
||||||
{
|
|
||||||
static int ec;
|
static int ec;
|
||||||
|
|
||||||
static int i, c;
|
static int i, c;
|
||||||
|
@ -1104,10 +1121,8 @@ static int xa_getline(char *s)
|
||||||
j = hkfl = comcom = 0;
|
j = hkfl = comcom = 0;
|
||||||
ec = E_OK;
|
ec = E_OK;
|
||||||
|
|
||||||
if(!gl)
|
if (!gl) {
|
||||||
{
|
do {
|
||||||
do
|
|
||||||
{
|
|
||||||
ec = pgetline(l);
|
ec = pgetline(l);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (l[i] == ' ')
|
while (l[i] == ' ')
|
||||||
|
@ -1116,17 +1131,13 @@ static int xa_getline(char *s)
|
||||||
i++;
|
i++;
|
||||||
gf = 1;
|
gf = 1;
|
||||||
|
|
||||||
if(ec==E_NEWLINE)
|
if (ec == E_NEWLINE) {
|
||||||
{
|
|
||||||
puttmpw(0);
|
puttmpw(0);
|
||||||
puttmp(T_LINE);
|
puttmp(T_LINE);
|
||||||
puttmpw(filep->fline);
|
puttmpw(filep->fline);
|
||||||
ec = E_OK;
|
ec = E_OK;
|
||||||
|
|
||||||
}
|
} else if (ec == E_NEWFILE) {
|
||||||
else
|
|
||||||
if(ec==E_NEWFILE)
|
|
||||||
{
|
|
||||||
puttmpw(0);
|
puttmpw(0);
|
||||||
puttmp(T_FILE);
|
puttmp(T_FILE);
|
||||||
puttmpw(filep->fline);
|
puttmpw(filep->fline);
|
||||||
|
@ -1137,8 +1148,7 @@ static int xa_getline(char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
gl = 0;
|
gl = 0;
|
||||||
if(!ec || ec==E_EOF)
|
if (!ec || ec == E_EOF) {
|
||||||
{
|
|
||||||
int startofline = 1;
|
int startofline = 1;
|
||||||
do {
|
do {
|
||||||
c = s[j] = l[i++];
|
c = s[j] = l[i++];
|
||||||
|
@ -1158,8 +1168,8 @@ static int xa_getline(char *s)
|
||||||
/* if the next char is a "=" - so that we have a ":=" - and we
|
/* if the next char is a "=" - so that we have a ":=" - and we
|
||||||
we have ca65 compatibility, we ignore the colon */
|
we have ca65 compatibility, we ignore the colon */
|
||||||
// also check for ":+" and ":-"
|
// also check for ":+" and ":-"
|
||||||
|
if (((!startofline) && l[i] != '=' && l[i] != '+' && l[i] != '-')
|
||||||
if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !ca65 || comcom) {
|
|| !ca65 || comcom) {
|
||||||
/* but otherwise we check if it is in a comment and we have
|
/* but otherwise we check if it is in a comment and we have
|
||||||
MASM or CA65 compatibility, then we ignore the colon as well */
|
MASM or CA65 compatibility, then we ignore the colon as well */
|
||||||
if (!comcom || !(masm || ca65)) {
|
if (!comcom || !(masm || ca65)) {
|
||||||
|
@ -1190,26 +1200,23 @@ void set_align(int a) {
|
||||||
align = (a > align) ? a : align;
|
align = (a > align) ? a : align;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lineout(void)
|
static void lineout(void) {
|
||||||
{
|
if (gf) {
|
||||||
if(gf)
|
|
||||||
{
|
|
||||||
logout(filep->flinep);
|
logout(filep->flinep);
|
||||||
logout("\n");
|
logout("\n");
|
||||||
gf = 0;
|
gf = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void errout(int er)
|
void errout(int er) {
|
||||||
{
|
|
||||||
if (er <= -ANZERR || er > -1) {
|
if (er <= -ANZERR || er > -1) {
|
||||||
if (er >= -(ANZERR + ANZWARN) && er <= -ANZERR) {
|
if (er >= -(ANZERR + ANZWARN) && er <= -ANZERR) {
|
||||||
sprintf(out,"%s:line %d: %04x: Warning - %s\n",
|
sprintf(out, "%s:line %d: %04x: Warning - %s\n", filep->fname,
|
||||||
filep->fname, filep->fline, pc[segment], ertxt[(-er)-1]);
|
filep->fline, pc[segment], ertxt[(-er) - 1]);
|
||||||
} else {
|
} else {
|
||||||
/* sprintf(out,"%s:Zeile %d: %04x:Unbekannter Fehler Nr.: %d\n",*/
|
/* sprintf(out,"%s:Zeile %d: %04x:Unbekannter Fehler Nr.: %d\n",*/
|
||||||
sprintf(out,"%s:line %d: %04x: Unknown error # %d\n",
|
sprintf(out, "%s:line %d: %04x: Unknown error # %d\n", filep->fname,
|
||||||
filep->fname,filep->fline,pc[segment],er);
|
filep->fline, pc[segment], er);
|
||||||
ner++;
|
ner++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1217,23 +1224,21 @@ void errout(int er)
|
||||||
sprintf(out, "%s:line %d: %04x:Label '%s' not defined\n",
|
sprintf(out, "%s:line %d: %04x:Label '%s' not defined\n",
|
||||||
filep->fname, filep->fline, pc[segment], lz);
|
filep->fname, filep->fline, pc[segment], lz);
|
||||||
else
|
else
|
||||||
sprintf(out,"%s:line %d: %04x:%s error\n",
|
sprintf(out, "%s:line %d: %04x:%s error\n", filep->fname,
|
||||||
filep->fname,filep->fline,pc[segment],ertxt[(-er)-1]);
|
filep->fline, pc[segment], ertxt[(-er) - 1]);
|
||||||
|
|
||||||
ner++;
|
ner++;
|
||||||
}
|
}
|
||||||
logout(out);
|
logout(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chrput(int c)
|
static void chrput(int c) {
|
||||||
{
|
|
||||||
/* printf(" %02x",c&255);*/
|
/* printf(" %02x",c&255);*/
|
||||||
|
|
||||||
putc(c & 0x00ff, fpout);
|
putc(c & 0x00ff, fpout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logout(char *s)
|
void logout(char *s) {
|
||||||
{
|
|
||||||
fprintf(stderr, "%s", s);
|
fprintf(stderr, "%s", s);
|
||||||
if (fperr)
|
if (fperr)
|
||||||
fprintf(fperr, "%s", s);
|
fprintf(fperr, "%s", s);
|
||||||
|
@ -1246,13 +1251,8 @@ typedef struct {
|
||||||
int *flag;
|
int *flag;
|
||||||
} compat_set;
|
} compat_set;
|
||||||
|
|
||||||
static compat_set compat_sets[] = {
|
static compat_set compat_sets[] = { { "MASM", &masm }, { "CA65", &ca65 }, { "C",
|
||||||
{ "MASM", &masm },
|
&ctypes }, { "XA23", &xa23 }, { NULL, NULL } };
|
||||||
{ "CA65", &ca65 },
|
|
||||||
{ "C", &ctypes },
|
|
||||||
{ "XA23", &xa23 },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
int set_compat(char *compat_name) {
|
int set_compat(char *compat_name) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -1262,8 +1262,8 @@ int set_compat(char *compat_name) {
|
||||||
(*compat_sets[i].flag) = 1;
|
(*compat_sets[i].flag) = 1;
|
||||||
|
|
||||||
/* warn on old versions of xa */
|
/* warn on old versions of xa */
|
||||||
if (xa23) fprintf(stderr,
|
if (xa23)
|
||||||
"Warning: -XXA23 is explicitly deprecated\n");
|
fprintf(stderr, "Warning: -XXA23 is explicitly deprecated\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1272,4 +1272,3 @@ int set_compat(char *compat_name) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
90
xa/src/xaa.c
90
xa/src/xaa.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* Preprocessing arithmetic module
|
* Preprocessing arithmetic module
|
||||||
*
|
*
|
||||||
|
@ -30,7 +30,8 @@
|
||||||
#include "xaa.h"
|
#include "xaa.h"
|
||||||
#include "xat.h"
|
#include "xat.h"
|
||||||
|
|
||||||
static int pr[]= { P_START,P_ADD,P_ADD,P_MULT,P_MULT,P_SHIFT,P_SHIFT,P_CMP,
|
static int pr[] = { P_START, P_ADD, P_ADD, P_MULT, P_MULT, P_SHIFT, P_SHIFT,
|
||||||
|
P_CMP,
|
||||||
P_CMP, P_EQU, P_CMP, P_CMP, P_EQU, P_AND, P_XOR, P_OR,
|
P_CMP, P_EQU, P_CMP, P_CMP, P_EQU, P_AND, P_XOR, P_OR,
|
||||||
P_LAND, P_LOR, P_EQU, P_START };
|
P_LAND, P_LOR, P_EQU, P_START };
|
||||||
|
|
||||||
|
@ -42,8 +43,7 @@ static int get_op(signed char*,int*);
|
||||||
static int do_op(int*, int, int);
|
static int do_op(int*, int, int);
|
||||||
|
|
||||||
/* s = string, v = variable */
|
/* s = string, v = variable */
|
||||||
int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f)
|
int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f) {
|
||||||
{
|
|
||||||
int er = E_OK;
|
int er = E_OK;
|
||||||
int afl = 0, bfl;
|
int afl = 0, bfl;
|
||||||
|
|
||||||
|
@ -53,8 +53,7 @@ int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f)
|
||||||
pp = 0;
|
pp = 0;
|
||||||
pcc = xpc;
|
pcc = xpc;
|
||||||
|
|
||||||
if(s[0]=='<')
|
if (s[0] == '<') {
|
||||||
{
|
|
||||||
pp++;
|
pp++;
|
||||||
er = ag_term(s, P_START, v, &afl, label);
|
er = ag_term(s, P_START, v, &afl, label);
|
||||||
bfl = afl & (A_MASK >> 8);
|
bfl = afl & (A_MASK >> 8);
|
||||||
|
@ -62,11 +61,10 @@ int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f)
|
||||||
/*fprintf(stderr,"low byte relocation for a high byte - won't work!\n");*/
|
/*fprintf(stderr,"low byte relocation for a high byte - won't work!\n");*/
|
||||||
errout(W_LOWACC);
|
errout(W_LOWACC);
|
||||||
}
|
}
|
||||||
if(afl) *pfl=A_LOW | ((afl<<8) & A_FMASK);
|
if (afl)
|
||||||
|
*pfl = A_LOW | ((afl << 8) & A_FMASK);
|
||||||
*v = *v & 255;
|
*v = *v & 255;
|
||||||
} else
|
} else if (s[pp] == '>') {
|
||||||
if(s[pp]=='>')
|
|
||||||
{
|
|
||||||
pp++;
|
pp++;
|
||||||
er = ag_term(s, P_START, v, &afl, label);
|
er = ag_term(s, P_START, v, &afl, label);
|
||||||
bfl = afl & (A_MASK >> 8);
|
bfl = afl & (A_MASK >> 8);
|
||||||
|
@ -74,18 +72,18 @@ int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f)
|
||||||
/*fprintf(stderr,"high byte relocation for a low byte - won't work!\n");*/
|
/*fprintf(stderr,"high byte relocation for a low byte - won't work!\n");*/
|
||||||
errout(W_HIGHACC);
|
errout(W_HIGHACC);
|
||||||
}
|
}
|
||||||
if(afl) *pfl=A_HIGH | ((afl<<8) & A_FMASK) | (*v & 255);
|
if (afl)
|
||||||
|
*pfl = A_HIGH | ((afl << 8) & A_FMASK) | (*v & 255);
|
||||||
*v = (*v >> 8) & 255;
|
*v = (*v >> 8) & 255;
|
||||||
}
|
} else if (s[pp] != T_END) {
|
||||||
else
|
|
||||||
if(s[pp]!=T_END) {
|
|
||||||
er = ag_term(s, P_START, v, &afl, label);
|
er = ag_term(s, P_START, v, &afl, label);
|
||||||
bfl = afl & (A_MASK >> 8);
|
bfl = afl & (A_MASK >> 8);
|
||||||
if (bfl && (bfl != (A_ADR >> 8))) {
|
if (bfl && (bfl != (A_ADR >> 8))) {
|
||||||
/*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/
|
/*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/
|
||||||
errout(W_ADDRACC);
|
errout(W_ADDRACC);
|
||||||
}
|
}
|
||||||
if(afl) *pfl = A_ADR | ((afl<<8) & A_FMASK);
|
if (afl)
|
||||||
|
*pfl = A_ADR | ((afl << 8) & A_FMASK);
|
||||||
} else {
|
} else {
|
||||||
er = E_SYNTAX;
|
er = E_SYNTAX;
|
||||||
}
|
}
|
||||||
|
@ -95,16 +93,14 @@ int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
|
static int ag_term(signed char *s, int p, int *v, int *nafl, int *label) {
|
||||||
{
|
|
||||||
int er = E_OK, o, w, mf = 1, afl;
|
int er = E_OK, o, w, mf = 1, afl;
|
||||||
|
|
||||||
afl = 0;
|
afl = 0;
|
||||||
|
|
||||||
//fprintf(stderr, "ag_term(%02x %02x %02x %02x %02x %02x\n",s[0],s[1],s[2],s[3],s[4],s[5]);
|
//fprintf(stderr, "ag_term(%02x %02x %02x %02x %02x %02x\n",s[0],s[1],s[2],s[3],s[4],s[5]);
|
||||||
|
|
||||||
while(s[pp]=='-')
|
while (s[pp] == '-') {
|
||||||
{
|
|
||||||
pp++;
|
pp++;
|
||||||
mf = -mf;
|
mf = -mf;
|
||||||
}
|
}
|
||||||
|
@ -123,19 +119,15 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
|
||||||
*v = !(*v);
|
*v = !(*v);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if(s[pp]=='(')
|
if (s[pp] == '(') {
|
||||||
{
|
|
||||||
pp++;
|
pp++;
|
||||||
if(!(er=ag_term(s,P_START,v,&afl,label)))
|
if (!(er = ag_term(s, P_START, v, &afl, label))) {
|
||||||
{
|
|
||||||
if (s[pp] != ')')
|
if (s[pp] != ')')
|
||||||
er = E_SYNTAX;
|
er = E_SYNTAX;
|
||||||
else
|
else
|
||||||
pp++;
|
pp++;
|
||||||
}
|
}
|
||||||
} else
|
} else if (s[pp] == T_LABEL) {
|
||||||
if(s[pp]==T_LABEL)
|
|
||||||
{
|
|
||||||
er = l_get(cval(s + pp + 1), v, &afl);
|
er = l_get(cval(s + pp + 1), v, &afl);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -153,10 +145,7 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pp += 3;
|
pp += 3;
|
||||||
}
|
} else if (s[pp] == T_VALUE || s[pp] == T_CAST) {
|
||||||
else
|
|
||||||
if(s[pp]==T_VALUE || s[pp] == T_CAST)
|
|
||||||
{
|
|
||||||
while (s[pp] == T_CAST) {
|
while (s[pp] == T_CAST) {
|
||||||
pp += 2;
|
pp += 2;
|
||||||
}
|
}
|
||||||
|
@ -165,48 +154,38 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
|
||||||
/*
|
/*
|
||||||
printf("value: v=%04x\n",*v);
|
printf("value: v=%04x\n",*v);
|
||||||
*/
|
*/
|
||||||
}
|
} else if (s[pp] == T_POINTER) {
|
||||||
else
|
|
||||||
if(s[pp]==T_POINTER)
|
|
||||||
{
|
|
||||||
afl = s[pp + 1];
|
afl = s[pp + 1];
|
||||||
*v = cval(s + pp + 2);
|
*v = cval(s + pp + 2);
|
||||||
pp += 6;
|
pp += 6;
|
||||||
/*
|
/*
|
||||||
printf("pointer: v=%04x, afl=%04x\n",*v,afl);
|
printf("pointer: v=%04x, afl=%04x\n",*v,afl);
|
||||||
*/
|
*/
|
||||||
}
|
} else if (s[pp] == '*') {
|
||||||
else
|
|
||||||
if(s[pp]=='*')
|
|
||||||
{
|
|
||||||
*v = pcc;
|
*v = pcc;
|
||||||
pp++;
|
pp++;
|
||||||
afl = segment;
|
afl = segment;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
er = E_SYNTAX;
|
er = E_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
*v *= mf;
|
*v *= mf;
|
||||||
|
|
||||||
while(!er && s[pp]!=')' && s[pp]!=']' && s[pp]!=',' && s[pp]!=T_END && s[pp]!=T_COMMENT)
|
while (!er && s[pp] != ')' && s[pp] != ']' && s[pp] != ',' && s[pp] != T_END
|
||||||
{
|
&& s[pp] != T_COMMENT) {
|
||||||
//fprintf(stderr, "ag_term while: s[pp=%d]=%02x\n", pp, s[pp]);
|
//fprintf(stderr, "ag_term while: s[pp=%d]=%02x\n", pp, s[pp]);
|
||||||
er = get_op(s, &o);
|
er = get_op(s, &o);
|
||||||
|
|
||||||
if(!er && pr[o]>p)
|
if (!er && pr[o] > p) {
|
||||||
{
|
|
||||||
pp += 1;
|
pp += 1;
|
||||||
if(!(er=ag_term(s,pr[o],&w, nafl, label)))
|
if (!(er = ag_term(s, pr[o], &w, nafl, label))) {
|
||||||
{
|
|
||||||
if (afl || *nafl) { /* check pointer arithmetic */
|
if (afl || *nafl) { /* check pointer arithmetic */
|
||||||
if((afl == *nafl) && (afl!=SEG_UNDEFZP) && (afl!=SEG_UNDEF) && o==2) {
|
if ((afl == *nafl) && (afl != SEG_UNDEFZP)
|
||||||
|
&& (afl != SEG_UNDEF) && o == 2) {
|
||||||
afl = 0; /* subtract two pointers */
|
afl = 0; /* subtract two pointers */
|
||||||
} else
|
} else if (((afl && !*nafl) || (*nafl && !afl)) && o == 1) {
|
||||||
if(((afl && !*nafl) || (*nafl && !afl)) && o==1) {
|
|
||||||
afl = (afl | *nafl); /* add constant to pointer */
|
afl = (afl | *nafl); /* add constant to pointer */
|
||||||
} else
|
} else if ((afl && !*nafl) && o == 2) {
|
||||||
if((afl && !*nafl) && o==2) {
|
|
||||||
afl = (afl | *nafl); /* subtract constant from pointer */
|
afl = (afl | *nafl); /* subtract constant from pointer */
|
||||||
} else {
|
} else {
|
||||||
if ((!afl && *nafl) && o == 2) {
|
if ((!afl && *nafl) && o == 2) {
|
||||||
|
@ -224,7 +203,8 @@ printf("pointer: v=%04x, afl=%04x\n",*v,afl);
|
||||||
afl = 0;
|
afl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!er) er=do_op(v,w,o);
|
if (!er)
|
||||||
|
er = do_op(v, w, o);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -234,8 +214,7 @@ printf("pointer: v=%04x, afl=%04x\n",*v,afl);
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_op(signed char *s, int *o)
|
static int get_op(signed char *s, int *o) {
|
||||||
{
|
|
||||||
int er;
|
int er;
|
||||||
|
|
||||||
*o = s[pp];
|
*o = s[pp];
|
||||||
|
@ -256,8 +235,7 @@ static int get_op(signed char *s, int *o)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_op(int *w,int w2,int o)
|
static int do_op(int *w, int w2, int o) {
|
||||||
{
|
|
||||||
int er = E_OK;
|
int er = E_OK;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
#define __XA65_XAA_H__
|
#define __XA65_XAA_H__
|
||||||
|
|
||||||
/* f = 0 -> label must exist; f = 1 -> SEG_UNDEF entry */
|
/* f = 0 -> label must exist; f = 1 -> SEG_UNDEF entry */
|
||||||
int a_term(signed char *s, int *v, int *l, int xpc, int *afl,
|
int a_term(signed char *s, int *v, int *l, int xpc, int *afl, int *label,
|
||||||
int *label, int f);
|
int f);
|
||||||
|
|
||||||
#endif /* __XA65_XAA_H__ */
|
#endif /* __XA65_XAA_H__ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 Andre Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
* Maintained by Cameron Kaiser
|
* Maintained by Cameron Kaiser
|
||||||
*
|
*
|
||||||
* Charset conversion module
|
* Charset conversion module
|
||||||
|
@ -20,7 +20,6 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -98,13 +97,9 @@ typedef struct {
|
||||||
signed char (*func)(signed char);
|
signed char (*func)(signed char);
|
||||||
} charset;
|
} charset;
|
||||||
|
|
||||||
static charset charsets[] = {
|
static charset charsets[] = { { "ASCII", convert_char_ascii }, { "PETSCII",
|
||||||
{ "ASCII", convert_char_ascii },
|
convert_char_petscii }, { "PETSCREEN", convert_char_petscreen }, {
|
||||||
{ "PETSCII", convert_char_petscii },
|
"HIGH", convert_char_high }, { NULL, NULL } };
|
||||||
{ "PETSCREEN", convert_char_petscreen },
|
|
||||||
{ "HIGH", convert_char_high },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
int set_charset(char *charset_name) {
|
int set_charset(char *charset_name) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -122,4 +117,3 @@ signed char convert_char(signed char c) {
|
||||||
return convert_func(c);
|
return convert_func(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-2006 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-2006 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
* Maintained by Cameron Kaiser
|
* Maintained by Cameron Kaiser
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -38,10 +38,7 @@
|
||||||
#define TMPMEM 2000000L /* temporary memory buffer from Pass1 to Pass 2 (includes all source, thus enlarged) */
|
#define TMPMEM 2000000L /* temporary memory buffer from Pass1 to Pass 2 (includes all source, thus enlarged) */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STD = 0,
|
STD = 0, CHEAP = 1, UNNAMED = 2, UNNAMED_DEF = 3
|
||||||
CHEAP = 1,
|
|
||||||
UNNAMED = 2,
|
|
||||||
UNNAMED_DEF = 3
|
|
||||||
} xalabel_t;
|
} xalabel_t;
|
||||||
|
|
||||||
typedef struct LabOcc {
|
typedef struct LabOcc {
|
||||||
|
@ -83,7 +80,6 @@ typedef struct {
|
||||||
int nextindex;
|
int nextindex;
|
||||||
} List;
|
} List;
|
||||||
|
|
||||||
|
|
||||||
#define MEMLEN (4 + TMPMEM + MAXPP + LABMEM + \
|
#define MEMLEN (4 + TMPMEM + MAXPP + LABMEM + \
|
||||||
(long)(sizeof (Labtab) * ANZLAB) + \
|
(long)(sizeof (Labtab) * ANZLAB) + \
|
||||||
(long)(sizeof (List) * ANZDEF))
|
(long)(sizeof (List) * ANZDEF))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
221
xa/src/xal.c
221
xa/src/xal.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* Label management module (also see xau.c)
|
* Label management module (also see xau.c)
|
||||||
*
|
*
|
||||||
|
@ -58,45 +58,37 @@ static int cll_get();
|
||||||
static void cll_clear();
|
static void cll_clear();
|
||||||
static int cll_getcur();
|
static int cll_getcur();
|
||||||
|
|
||||||
|
|
||||||
static Labtab *ltp;
|
static Labtab *ltp;
|
||||||
|
|
||||||
int l_init(void)
|
int l_init(void) {
|
||||||
{
|
|
||||||
cll_init();
|
cll_init();
|
||||||
//unn_init();
|
//unn_init();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ga_lab(void)
|
int ga_lab(void) {
|
||||||
{
|
|
||||||
return (afile->la.lti);
|
return (afile->la.lti);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gm_lab(void)
|
int gm_lab(void) {
|
||||||
{
|
|
||||||
return (ANZLAB);
|
return (ANZLAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
long gm_labm(void)
|
long gm_labm(void) {
|
||||||
{
|
|
||||||
return ((long) LABMEM);
|
return ((long) LABMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
long ga_labm(void)
|
long ga_labm(void) {
|
||||||
{
|
|
||||||
return (0 /*lni*/);
|
return (0 /*lni*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printllist(fp)
|
void printllist(fp)
|
||||||
FILE *fp;
|
FILE *fp; {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
LabOcc *p;
|
LabOcc *p;
|
||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
|
|
||||||
for(i=0;i<afile->la.lti;i++)
|
for (i = 0; i < afile->la.lti; i++) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + i;
|
ltp = afile->la.lt + i;
|
||||||
fprintf(fp, "%s, 0x%04x, %d, 0x%04x\n", ltp->n, ltp->val, ltp->blk,
|
fprintf(fp, "%s, 0x%04x, %d, 0x%04x\n", ltp->n, ltp->val, ltp->blk,
|
||||||
ltp->afl);
|
ltp->afl);
|
||||||
|
@ -104,7 +96,8 @@ FILE *fp;
|
||||||
if (p) {
|
if (p) {
|
||||||
while (p) {
|
while (p) {
|
||||||
if (fname != p->fname) {
|
if (fname != p->fname) {
|
||||||
if(p!=ltp->occlist) fprintf(fp,"\n");
|
if (p != ltp->occlist)
|
||||||
|
fprintf(fp, "\n");
|
||||||
fprintf(fp, " %s", p->fname);
|
fprintf(fp, " %s", p->fname);
|
||||||
fname = p->fname;
|
fname = p->fname;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +200,6 @@ int lg_toglobal(char *s ) {
|
||||||
return er;
|
return er;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* define a global zeropage label (from the .importzp pseudo opcode))
|
* define a global zeropage label (from the .importzp pseudo opcode))
|
||||||
* "s" is a pointer to the first label character, end is at \0
|
* "s" is a pointer to the first label character, end is at \0
|
||||||
|
@ -225,8 +217,7 @@ int lg_importzp(int n) {
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
|
|
||||||
int l_def(char *s, int *l, int *x, int *f)
|
int l_def(char *s, int *l, int *x, int *f) {
|
||||||
{
|
|
||||||
int n, er, b, i = 0;
|
int n, er, b, i = 0;
|
||||||
xalabel_t cll_fl;
|
xalabel_t cll_fl;
|
||||||
|
|
||||||
|
@ -242,28 +233,22 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||||
//n++; /* block number b is absolute */
|
//n++; /* block number b is absolute */
|
||||||
//b=unn_get(); /* current (possibly newly allocated) unnamed label block */
|
//b=unn_get(); /* current (possibly newly allocated) unnamed label block */
|
||||||
cll_fl = UNNAMED; // keep the cheap local label block
|
cll_fl = UNNAMED; // keep the cheap local label block
|
||||||
} else
|
} else if (s[0] == '-') {
|
||||||
if(s[0]=='-')
|
|
||||||
{
|
|
||||||
*f += 1; /* label is being redefined */
|
*f += 1; /* label is being redefined */
|
||||||
i++;
|
i++;
|
||||||
} else
|
} else if (s[0] == '@') {
|
||||||
if(s[0]=='@')
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
n++; /* block number b is absolute */
|
n++; /* block number b is absolute */
|
||||||
b = cll_get(); /* current (possibly newly allocated) cheap label block */
|
b = cll_get(); /* current (possibly newly allocated) cheap label block */
|
||||||
cll_fl = CHEAP; /* do not clear the cll block again... */
|
cll_fl = CHEAP; /* do not clear the cll block again... */
|
||||||
} else
|
} else if (s[0] == '+') {
|
||||||
if(s[0]=='+')
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
n++; /* block number b is absolute */
|
n++; /* block number b is absolute */
|
||||||
b = 0; /* global block number */
|
b = 0; /* global block number */
|
||||||
}
|
}
|
||||||
while(s[i]=='&')
|
while (s[i] == '&') {
|
||||||
{
|
if (n)
|
||||||
if (n) b=0; /* reset block number */
|
b = 0; /* reset block number */
|
||||||
n = 0; /* block number is relative */
|
n = 0; /* block number is relative */
|
||||||
i++;
|
i++;
|
||||||
b++; /* one (more) level up the block stack */
|
b++; /* one (more) level up the block stack */
|
||||||
|
@ -278,29 +263,25 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||||
cll_clear();
|
cll_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!isalpha(s[i])) && (s[i]!='_') && !(ca65 && ((cll_fl == UNNAMED) || isdigit(s[i])) ) ) {
|
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]);
|
//printf("SYNTAX cll_fl=%d, i=%d, s[i]=%02x (%c)\n", cll_fl, i, s[i], s[i]);
|
||||||
er = E_SYNTAX;
|
er = E_SYNTAX;
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
er = E_NODEF;
|
er = E_NODEF;
|
||||||
if (cll_fl != UNNAMED) {
|
if (cll_fl != UNNAMED) {
|
||||||
er = ll_search(s + i, &n, cll_fl);
|
er = ll_search(s + i, &n, cll_fl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(er==E_OK)
|
if (er == E_OK) {
|
||||||
{
|
|
||||||
//printf("l_def OK: cll_fl=%d, i=%d, s=%s\n", cll_fl, i, s);
|
//printf("l_def OK: cll_fl=%d, i=%d, s=%s\n", cll_fl, i, s);
|
||||||
/* we actually found an existing label in the same scope */
|
/* we actually found an existing label in the same scope */
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
|
|
||||||
if(*f)
|
if (*f) {
|
||||||
{
|
|
||||||
/* redefinition of label */
|
/* redefinition of label */
|
||||||
*l = ltp->len + i;
|
*l = ltp->len + i;
|
||||||
} else
|
} else if (ltp->fl == 0) {
|
||||||
if(ltp->fl == 0)
|
|
||||||
{
|
|
||||||
/* label has not been defined yet, (e.g. pass1 forward ref), so we try to set it. */
|
/* label has not been defined yet, (e.g. pass1 forward ref), so we try to set it. */
|
||||||
*l = ltp->len + i;
|
*l = ltp->len + i;
|
||||||
if (b_ltest(ltp->blk, b))
|
if (b_ltest(ltp->blk, b))
|
||||||
|
@ -308,9 +289,7 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||||
else
|
else
|
||||||
ltp->blk = b;
|
ltp->blk = b;
|
||||||
|
|
||||||
} else
|
} else if (ltp->fl == 3) {
|
||||||
if(ltp->fl == 3)
|
|
||||||
{
|
|
||||||
/* label has been defined as -U undef'd label so far - we need to check */
|
/* label has been defined as -U undef'd label so far - we need to check */
|
||||||
*l = ltp->len + i;
|
*l = ltp->len + i;
|
||||||
if (b_ltest(ltp->origblk, b))
|
if (b_ltest(ltp->origblk, b))
|
||||||
|
@ -320,9 +299,7 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||||
|
|
||||||
} else
|
} else
|
||||||
er = E_LABDEF;
|
er = E_LABDEF;
|
||||||
} else
|
} else if (er == E_NODEF) {
|
||||||
if(er==E_NODEF)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!(er = ll_def(s + i, &n, b, cll_fl))) /* store the label in the table of labels */
|
if (!(er = ll_def(s + i, &n, b, cll_fl))) /* store the label in the table of labels */
|
||||||
{
|
{
|
||||||
|
@ -339,8 +316,7 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_search(char *s, int *l, int *x, int *v, int *afl)
|
int l_search(char *s, int *l, int *x, int *v, int *afl) {
|
||||||
{
|
|
||||||
int n, er, b;
|
int n, er, b;
|
||||||
xalabel_t cll_fl;
|
xalabel_t cll_fl;
|
||||||
|
|
||||||
|
@ -351,8 +327,7 @@ int l_search(char *s, int *l, int *x, int *v, int *afl)
|
||||||
if (s[0] == '@') {
|
if (s[0] == '@') {
|
||||||
cll_fl = CHEAP;
|
cll_fl = CHEAP;
|
||||||
s++;
|
s++;
|
||||||
} else
|
} else if (s[0] == ':') {
|
||||||
if (s[0]==':') {
|
|
||||||
cll_fl = UNNAMED_DEF;
|
cll_fl = UNNAMED_DEF;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
@ -363,27 +338,21 @@ int l_search(char *s, int *l, int *x, int *v, int *afl)
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("l_search: lab=%s(afl=%d, er=%d, cll_fl=%d, cll_cur=%d)\n",s,*afl,er, cll_fl, cll_getcur());
|
//printf("l_search: lab=%s(afl=%d, er=%d, cll_fl=%d, cll_cur=%d)\n",s,*afl,er, cll_fl, cll_getcur());
|
||||||
if(er==E_OK)
|
if (er == E_OK) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
*l = ltp->len + ((cll_fl == STD) ? 0 : 1);
|
*l = ltp->len + ((cll_fl == STD) ? 0 : 1);
|
||||||
if(ltp->fl == 1)
|
if (ltp->fl == 1) {
|
||||||
{
|
|
||||||
l_get(n, v, afl);/* *v=lt[n].val;*/
|
l_get(n, v, afl);/* *v=lt[n].val;*/
|
||||||
*x = n;
|
*x = n;
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
er = E_NODEF;
|
er = E_NODEF;
|
||||||
lz = ltp->n;
|
lz = ltp->n;
|
||||||
*x = n;
|
*x = n;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cll_fl == CHEAP) {
|
if (cll_fl == CHEAP) {
|
||||||
b = cll_get();
|
b = cll_get();
|
||||||
} else
|
} else if (cll_fl == UNNAMED_DEF) {
|
||||||
if(cll_fl == UNNAMED_DEF) {
|
|
||||||
b_get(&b); // b=unn_get();
|
b_get(&b); // b=unn_get();
|
||||||
} else {
|
} else {
|
||||||
b_get(&b);
|
b_get(&b);
|
||||||
|
@ -397,8 +366,7 @@ int l_search(char *s, int *l, int *x, int *v, int *afl)
|
||||||
*l = ltp->len + ((cll_fl == STD) ? 0 : 1);
|
*l = ltp->len + ((cll_fl == STD) ? 0 : 1);
|
||||||
//*l=ltp->len + cll_fl;
|
//*l=ltp->len + cll_fl;
|
||||||
|
|
||||||
if(!er)
|
if (!er) {
|
||||||
{
|
|
||||||
er = E_NODEF;
|
er = E_NODEF;
|
||||||
lz = ltp->n;
|
lz = ltp->n;
|
||||||
}
|
}
|
||||||
|
@ -406,8 +374,7 @@ int l_search(char *s, int *l, int *x, int *v, int *afl)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_vget(int n, int *v, char **s)
|
int l_vget(int n, int *v, char **s) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
(*v) = ltp->val;
|
(*v) = ltp->val;
|
||||||
*s = ltp->n;
|
*s = ltp->n;
|
||||||
|
@ -423,7 +390,8 @@ void l_addocc(int n, int *v, int *afl) {
|
||||||
pp = NULL;
|
pp = NULL;
|
||||||
p = ltp->occlist;
|
p = ltp->occlist;
|
||||||
while (p) {
|
while (p) {
|
||||||
if (p->line == filep->fline && p->fname == filep->fname) return;
|
if (p->line == filep->fline && p->fname == filep->fname)
|
||||||
|
return;
|
||||||
pp = p;
|
pp = p;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +413,8 @@ void l_addocc(int n, int *v, int *afl) {
|
||||||
/* for the list functionality */
|
/* for the list functionality */
|
||||||
char* l_get_name(int n, xalabel_t *is_cll) {
|
char* l_get_name(int n, xalabel_t *is_cll) {
|
||||||
if (n > afile->la.ltm) {
|
if (n > afile->la.ltm) {
|
||||||
fprintf(stderr, "Corrupted structures! n=%d, but max=%d\n", n, afile->la.ltm);
|
fprintf(stderr, "Corrupted structures! n=%d, but max=%d\n", n,
|
||||||
|
afile->la.ltm);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
|
@ -465,8 +434,7 @@ static int resolve_unnamed() {
|
||||||
nextp = -1;
|
nextp = -1;
|
||||||
if (c == '+') {
|
if (c == '+') {
|
||||||
nextp = ltp->blknext;
|
nextp = ltp->blknext;
|
||||||
} else
|
} else if (c == '-') {
|
||||||
if (c == '-') {
|
|
||||||
nextp = ltp->blkprev;
|
nextp = ltp->blkprev;
|
||||||
}
|
}
|
||||||
//printf("::: nextp=%d\n", nextp);
|
//printf("::: nextp=%d\n", nextp);
|
||||||
|
@ -488,16 +456,13 @@ char *l_get_unique_name(int n) {
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
|
|
||||||
if (ltp->is_cll == CHEAP || ltp->is_cll == STD) {
|
if (ltp->is_cll == CHEAP || ltp->is_cll == STD) {
|
||||||
sprintf(buf, "%d%c%s", ltp->blk,
|
sprintf(buf, "%d%c%s", ltp->blk, (ltp->is_cll == CHEAP) ? 'C' : '_',
|
||||||
(ltp->is_cll == CHEAP) ? 'C' : '_',
|
|
||||||
ltp->n);
|
ltp->n);
|
||||||
} else
|
} else if (ltp->is_cll == UNNAMED) {
|
||||||
if (ltp->is_cll == UNNAMED) {
|
|
||||||
// definition of unnamed label - name is NULL
|
// definition of unnamed label - name is NULL
|
||||||
// so use the actual index
|
// so use the actual index
|
||||||
sprintf(buf, "%dU%d", ltp->blk, n);
|
sprintf(buf, "%dU%d", ltp->blk, n);
|
||||||
} else
|
} else if (ltp->is_cll == UNNAMED_DEF) {
|
||||||
if (ltp->is_cll == UNNAMED_DEF) {
|
|
||||||
// we actually need to find the correct label from the "+" and "-"
|
// we actually need to find the correct label from the "+" and "-"
|
||||||
// in the name
|
// in the name
|
||||||
int tmp = resolve_unnamed();
|
int tmp = resolve_unnamed();
|
||||||
|
@ -512,15 +477,16 @@ char *l_get_unique_name(int n) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_get(int n, int *v, int *afl)
|
int l_get(int n, int *v, int *afl) {
|
||||||
{
|
if (crossref)
|
||||||
if(crossref) l_addocc(n,v,afl);
|
l_addocc(n, v, afl);
|
||||||
|
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
|
|
||||||
if (ltp->is_cll == UNNAMED_DEF) {
|
if (ltp->is_cll == UNNAMED_DEF) {
|
||||||
int tmp = resolve_unnamed();
|
int tmp = resolve_unnamed();
|
||||||
if (tmp == -1) return E_NODEF;
|
if (tmp == -1)
|
||||||
|
return E_NODEF;
|
||||||
// now ltp is set to the actual label
|
// now ltp is set to the actual label
|
||||||
}
|
}
|
||||||
(*v) = ltp->val;
|
(*v) = ltp->val;
|
||||||
|
@ -530,8 +496,7 @@ int l_get(int n, int *v, int *afl)
|
||||||
return ((ltp->fl == 1) ? E_OK : E_NODEF);
|
return ((ltp->fl == 1) ? E_OK : E_NODEF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void l_set(int n, int v, int afl)
|
void l_set(int n, int v, int afl) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
ltp->val = v;
|
ltp->val = v;
|
||||||
ltp->fl = 1;
|
ltp->fl = 1;
|
||||||
|
@ -540,11 +505,9 @@ void l_set(int n, int v, int afl)
|
||||||
//printf("l_set('%s'(%d), v=$%04x, afl=%d\n",ltp->n, n, v, afl);
|
//printf("l_set('%s'(%d), v=$%04x, afl=%d\n",ltp->n, n, v, afl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ll_exblk(int a, int b)
|
static void ll_exblk(int a, int b) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<afile->la.lti;i++)
|
for (i = 0; i < afile->la.lti; i++) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + i;
|
ltp = afile->la.lt + i;
|
||||||
if ((!ltp->fl) && (ltp->blk == a))
|
if ((!ltp->fl) && (ltp->blk == a))
|
||||||
ltp->blk = b;
|
ltp->blk = b;
|
||||||
|
@ -552,8 +515,7 @@ static void ll_exblk(int a, int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* defines next label, returns new label number in out param n */
|
/* defines next label, returns new label number in out param n */
|
||||||
static int ll_def(char *s, int *n, int b, xalabel_t ltype)
|
static int ll_def(char *s, int *n, int b, xalabel_t ltype) {
|
||||||
{
|
|
||||||
int j = 0, er = E_NOMEM, hash;
|
int j = 0, er = E_NOMEM, hash;
|
||||||
char *s2 = NULL;
|
char *s2 = NULL;
|
||||||
|
|
||||||
|
@ -583,10 +545,12 @@ static int ll_def(char *s, int *n, int b, xalabel_t ltype)
|
||||||
// alloc space and copy over name
|
// alloc space and copy over name
|
||||||
if (ltype == UNNAMED_DEF) {
|
if (ltype == UNNAMED_DEF) {
|
||||||
// unnamed lables are like ":--" or ":+" with variable length
|
// unnamed lables are like ":--" or ":+" with variable length
|
||||||
while((s[j]!='\0') && (s[j]=='+' || s[j]=='-')) j++;
|
while ((s[j] != '\0') && (s[j] == '+' || s[j] == '-'))
|
||||||
|
j++;
|
||||||
} else {
|
} else {
|
||||||
// standard (and cheap) labels are normal text
|
// standard (and cheap) labels are normal text
|
||||||
while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
|
while ((s[j] != '\0') && (isalnum(s[j]) || (s[j] == '_')))
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
s2 = malloc(j + 1);
|
s2 = malloc(j + 1);
|
||||||
if (!s2) {
|
if (!s2) {
|
||||||
|
@ -638,35 +602,34 @@ int ll_search(char *s, int *n, xalabel_t cll_fl) /* search Label in Tab
|
||||||
{
|
{
|
||||||
int i, j = 0, k, er = E_NODEF, hash;
|
int i, j = 0, k, er = E_NODEF, hash;
|
||||||
|
|
||||||
while(s[j] && (isalnum(s[j])||(s[j]=='_'))) j++;
|
while (s[j] && (isalnum(s[j]) || (s[j] == '_')))
|
||||||
|
j++;
|
||||||
|
|
||||||
hash = hashcode(s, j);
|
hash = hashcode(s, j);
|
||||||
i = afile->la.hashindex[hash];
|
i = afile->la.hashindex[hash];
|
||||||
|
|
||||||
if(i>=afile->la.ltm) return E_NODEF;
|
if (i >= afile->la.ltm)
|
||||||
|
return E_NODEF;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + i;
|
ltp = afile->la.lt + i;
|
||||||
|
|
||||||
if(j==ltp->len)
|
if (j == ltp->len) {
|
||||||
{
|
for (k = 0; (k < j) && (ltp->n[k] == s[k]); k++)
|
||||||
for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
|
;
|
||||||
|
|
||||||
if ((j == k) && cll_fl == CHEAP) {
|
if ((j == k) && cll_fl == CHEAP) {
|
||||||
if (ltp->blk == cll_getcur()) {
|
if (ltp->blk == cll_getcur()) {
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else if (cll_fl == UNNAMED) {
|
||||||
if (cll_fl == UNNAMED) {
|
|
||||||
// TODO
|
// TODO
|
||||||
} else {
|
} else {
|
||||||
//printf("ll_search:match labels %s with %p (%s) from block %d, block check is %d\n", s, ltp, ltp->n, ltp->blk, b_test(ltp->blk));
|
//printf("ll_search:match labels %s with %p (%s) from block %d, block check is %d\n", s, ltp, ltp->n, ltp->blk, b_test(ltp->blk));
|
||||||
/* check if the found label is in any of the blocks in the
|
/* check if the found label is in any of the blocks in the
|
||||||
current block stack */
|
current block stack */
|
||||||
if((j==k)&&(!b_test(ltp->blk)))
|
if ((j == k) && (!b_test(ltp->blk))) {
|
||||||
{
|
|
||||||
/* ok, label found and it is reachable (its block nr is in the current block stack */
|
/* ok, label found and it is reachable (its block nr is in the current block stack */
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
break;
|
break;
|
||||||
|
@ -694,12 +657,10 @@ int ll_search(char *s, int *n, xalabel_t cll_fl) /* search Label in Tab
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ll_pdef(char *t)
|
int ll_pdef(char *t) {
|
||||||
{
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if(ll_search(t,&n, STD)==E_OK)
|
if (ll_search(t, &n, STD) == E_OK) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + n;
|
ltp = afile->la.lt + n;
|
||||||
if (ltp->fl)
|
if (ltp->fl)
|
||||||
return (E_OK);
|
return (E_OK);
|
||||||
|
@ -710,8 +671,7 @@ int ll_pdef(char *t)
|
||||||
/*
|
/*
|
||||||
* Write out the list of global labels in an o65 file
|
* Write out the list of global labels in an o65 file
|
||||||
*/
|
*/
|
||||||
int l_write(FILE *fp)
|
int l_write(FILE *fp) {
|
||||||
{
|
|
||||||
int i, afl, n = 0;
|
int i, afl, n = 0;
|
||||||
|
|
||||||
if (noglob) {
|
if (noglob) {
|
||||||
|
@ -730,8 +690,7 @@ int l_write(FILE *fp)
|
||||||
fputc(n & 255, fp);
|
fputc(n & 255, fp);
|
||||||
fputc((n >> 8) & 255, fp);
|
fputc((n >> 8) & 255, fp);
|
||||||
// iterate over labels and write out label
|
// iterate over labels and write out label
|
||||||
for (i=0;i<afile->la.lti;i++)
|
for (i = 0; i < afile->la.lti; i++) {
|
||||||
{
|
|
||||||
ltp = afile->la.lt + i;
|
ltp = afile->la.lt + i;
|
||||||
if ((!ltp->blk) && (ltp->fl == 1)) {
|
if ((!ltp->blk) && (ltp->fl == 1)) {
|
||||||
// write global name
|
// write global name
|
||||||
|
@ -778,8 +737,7 @@ static int labind; /* last allocated label, -1 none yet alloc'd - used for linki
|
||||||
static int bi; /* length of the block stack (minus 1, i.e. bi[bi] has the innermost block) */
|
static int bi; /* length of the block stack (minus 1, i.e. bi[bi] has the innermost block) */
|
||||||
static int blk; /* current block number for allocation */
|
static int blk; /* current block number for allocation */
|
||||||
|
|
||||||
int b_init(void)
|
int b_init(void) {
|
||||||
{
|
|
||||||
blk = 0;
|
blk = 0;
|
||||||
bi = 0;
|
bi = 0;
|
||||||
bt[bi] = blk;
|
bt[bi] = blk;
|
||||||
|
@ -788,30 +746,25 @@ int b_init(void)
|
||||||
return (E_OK);
|
return (E_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int b_new(void)
|
int b_new(void) {
|
||||||
{
|
|
||||||
return ++blk;
|
return ++blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
int b_depth(void)
|
int b_depth(void) {
|
||||||
{
|
|
||||||
return bi;
|
return bi;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ga_blk(void)
|
int ga_blk(void) {
|
||||||
{
|
|
||||||
return (blk);
|
return (blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open a new block scope
|
* open a new block scope
|
||||||
*/
|
*/
|
||||||
int b_open(void)
|
int b_open(void) {
|
||||||
{
|
|
||||||
int er = E_BLKOVR;
|
int er = E_BLKOVR;
|
||||||
|
|
||||||
if(bi<MAXBLK-1)
|
if (bi < MAXBLK - 1) {
|
||||||
{
|
|
||||||
bi++;
|
bi++;
|
||||||
bt[bi] = b_new();
|
bt[bi] = b_new();
|
||||||
|
|
||||||
|
@ -823,11 +776,9 @@ int b_open(void)
|
||||||
/**
|
/**
|
||||||
* close a block scope
|
* close a block scope
|
||||||
*/
|
*/
|
||||||
int b_close(void)
|
int b_close(void) {
|
||||||
{
|
|
||||||
|
|
||||||
if(bi)
|
if (bi) {
|
||||||
{
|
|
||||||
ll_exblk(bt[bi], bt[bi - 1]);
|
ll_exblk(bt[bi], bt[bi - 1]);
|
||||||
bi--;
|
bi--;
|
||||||
} else {
|
} else {
|
||||||
|
@ -841,8 +792,7 @@ int b_close(void)
|
||||||
/**
|
/**
|
||||||
* get the block number of the current innermost block
|
* get the block number of the current innermost block
|
||||||
*/
|
*/
|
||||||
static int b_get(int *n)
|
static int b_get(int *n) {
|
||||||
{
|
|
||||||
*n = bt[bi];
|
*n = bt[bi];
|
||||||
|
|
||||||
return (E_OK);
|
return (E_OK);
|
||||||
|
@ -851,8 +801,7 @@ static int b_get(int *n)
|
||||||
/**
|
/**
|
||||||
* returns the block number of the block "i" levels up in the current block stack
|
* returns the block number of the block "i" levels up in the current block stack
|
||||||
*/
|
*/
|
||||||
static int b_fget(int *n, int i)
|
static int b_fget(int *n, int i) {
|
||||||
{
|
|
||||||
if ((bi - i) >= 0)
|
if ((bi - i) >= 0)
|
||||||
*n = bt[bi - i];
|
*n = bt[bi - i];
|
||||||
else
|
else
|
||||||
|
@ -864,8 +813,7 @@ static int b_fget(int *n, int i)
|
||||||
* tests whether the given block number n is in the current stack of
|
* tests whether the given block number n is in the current stack of
|
||||||
* current block numbers bt[]
|
* current block numbers bt[]
|
||||||
*/
|
*/
|
||||||
static int b_test(int n)
|
static int b_test(int n) {
|
||||||
{
|
|
||||||
int i = bi;
|
int i = bi;
|
||||||
|
|
||||||
while (i >= 0 && n != bt[i])
|
while (i >= 0 && n != bt[i])
|
||||||
|
@ -881,14 +829,11 @@ static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(
|
||||||
{
|
{
|
||||||
int i = 0, er = E_OK;
|
int i = 0, er = E_OK;
|
||||||
|
|
||||||
if(a!=b)
|
if (a != b) {
|
||||||
{
|
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
|
|
||||||
while(i<=bi && b!=bt[i])
|
while (i <= bi && b != bt[i]) {
|
||||||
{
|
if (bt[i] == a) {
|
||||||
if(bt[i]==a)
|
|
||||||
{
|
|
||||||
er = E_NOBLK;
|
er = E_NOBLK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
*/
|
*/
|
||||||
extern char *lz;
|
extern char *lz;
|
||||||
|
|
||||||
|
|
||||||
int l_init(void);
|
int l_init(void);
|
||||||
int ga_lab(void);
|
int ga_lab(void);
|
||||||
int gm_lab(void);
|
int gm_lab(void);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
* maintained by Cameron Kaiser
|
* maintained by Cameron Kaiser
|
||||||
*
|
*
|
||||||
* Assembler listing
|
* Assembler listing
|
||||||
|
@ -31,7 +31,6 @@
|
||||||
#include "xal.h"
|
#include "xal.h"
|
||||||
#include "xat.h"
|
#include "xat.h"
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
/* this is the listing code
|
/* this is the listing code
|
||||||
*
|
*
|
||||||
|
@ -87,9 +86,7 @@ static char *def_escape_char(char toescape) {
|
||||||
|
|
||||||
static formatter_t def_format = {
|
static formatter_t def_format = {
|
||||||
NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL, def_escape, def_escape_char };
|
||||||
def_escape, def_escape_char
|
|
||||||
};
|
|
||||||
|
|
||||||
static void html_start_listing(char *name) {
|
static void html_start_listing(char *name) {
|
||||||
// really short version for now
|
// really short version for now
|
||||||
|
@ -127,13 +124,11 @@ static char *html_escape(char *toescape) {
|
||||||
strcpy(q, "<");
|
strcpy(q, "<");
|
||||||
q += 4;
|
q += 4;
|
||||||
p++;
|
p++;
|
||||||
} else
|
} else if (*p == '&') {
|
||||||
if (*p == '&') {
|
|
||||||
strcpy(q, "&");
|
strcpy(q, "&");
|
||||||
q += 5;
|
q += 5;
|
||||||
p++;
|
p++;
|
||||||
} else
|
} else if (*p == '>') {
|
||||||
if (*p == '>') {
|
|
||||||
strcpy(q, ">");
|
strcpy(q, ">");
|
||||||
q += 4;
|
q += 4;
|
||||||
p++;
|
p++;
|
||||||
|
@ -156,16 +151,9 @@ static char *html_escape_char(char toescape) {
|
||||||
return html_escape(buf);
|
return html_escape(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static formatter_t html_format = {
|
static formatter_t html_format = { html_start_listing,
|
||||||
html_start_listing,
|
NULL, html_set_anchor, html_start_label, html_end_label,
|
||||||
NULL,
|
NULL, html_end_listing, html_escape, html_escape_char };
|
||||||
html_set_anchor,
|
|
||||||
html_start_label,
|
|
||||||
html_end_label,
|
|
||||||
NULL,
|
|
||||||
html_end_listing,
|
|
||||||
html_escape, html_escape_char
|
|
||||||
};
|
|
||||||
|
|
||||||
static formatter_t *formatp = &def_format;
|
static formatter_t *formatp = &def_format;
|
||||||
|
|
||||||
|
@ -185,13 +173,15 @@ void list_start(const char *formatname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listfp != NULL) {
|
if (listfp != NULL) {
|
||||||
if (formatp->start_listing != NULL) formatp->start_listing(list_filenamep);
|
if (formatp->start_listing != NULL)
|
||||||
|
formatp->start_listing(list_filenamep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_end() {
|
void list_end() {
|
||||||
if (listfp != NULL) {
|
if (listfp != NULL) {
|
||||||
if (formatp->end_listing != NULL) formatp->end_listing();
|
if (formatp->end_listing != NULL)
|
||||||
|
formatp->end_listing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +197,8 @@ void list_line(int l) {
|
||||||
|
|
||||||
/* set file name for the coming listing output */
|
/* set file name for the coming listing output */
|
||||||
void list_filename(char *fname) {
|
void list_filename(char *fname) {
|
||||||
if (list_filenamep == NULL || (fname != NULL && strcmp(fname, list_filenamep) != 0)) {
|
if (list_filenamep == NULL
|
||||||
|
|| (fname != NULL && strcmp(fname, list_filenamep) != 0)) {
|
||||||
list_filenamep = fname;
|
list_filenamep = fname;
|
||||||
list_lineno = 1;
|
list_lineno = 1;
|
||||||
list_last_lineno = 0;
|
list_last_lineno = 0;
|
||||||
|
@ -239,12 +230,24 @@ char *list_preamble(char *buf, int lineno, int seg, int pc) {
|
||||||
c = '?';
|
c = '?';
|
||||||
/* preamble <segment>':'<address>' ' */
|
/* preamble <segment>':'<address>' ' */
|
||||||
switch (seg) {
|
switch (seg) {
|
||||||
case SEG_ABS: c='A'; break;
|
case SEG_ABS:
|
||||||
case SEG_TEXT: c='T'; break;
|
c = 'A';
|
||||||
case SEG_BSS: c='B'; break;
|
break;
|
||||||
case SEG_DATA: c='D'; break;
|
case SEG_TEXT:
|
||||||
case SEG_UNDEF: c='U'; break;
|
c = 'T';
|
||||||
case SEG_ZERO: c='Z'; break;
|
break;
|
||||||
|
case SEG_BSS:
|
||||||
|
c = 'B';
|
||||||
|
break;
|
||||||
|
case SEG_DATA:
|
||||||
|
c = 'D';
|
||||||
|
break;
|
||||||
|
case SEG_UNDEF:
|
||||||
|
c = 'U';
|
||||||
|
break;
|
||||||
|
case SEG_ZERO:
|
||||||
|
c = 'Z';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
buf = buf + list_char(buf, c);
|
buf = buf + list_char(buf, c);
|
||||||
buf = buf + list_char(buf, ':');
|
buf = buf + list_char(buf, ':');
|
||||||
|
@ -254,7 +257,6 @@ char *list_preamble(char *buf, int lineno, int seg, int pc) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* listing/listing_len give the buffer address and length respectively that contains
|
* listing/listing_len give the buffer address and length respectively that contains
|
||||||
* the token as they are produced by the tokenizer.
|
* the token as they are produced by the tokenizer.
|
||||||
|
@ -263,7 +265,8 @@ char *list_preamble(char *buf, int lineno, int seg, int pc) {
|
||||||
*
|
*
|
||||||
* Note that both lengths may be zero
|
* Note that both lengths may be zero
|
||||||
*/
|
*/
|
||||||
void do_listing(signed char *listing, int listing_len, signed char *bincode, int bincode_len) {
|
void do_listing(signed char *listing, int listing_len, signed char *bincode,
|
||||||
|
int bincode_len) {
|
||||||
int i, n_hexb, num_last_line, tmp, overflow;
|
int i, n_hexb, num_last_line, tmp, overflow;
|
||||||
|
|
||||||
char outline[MAXLINE];
|
char outline[MAXLINE];
|
||||||
|
@ -273,12 +276,13 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||||
int lst_pc = (listing[2] << 8) | (listing[1] & 255);
|
int lst_pc = (listing[2] << 8) | (listing[1] & 255);
|
||||||
|
|
||||||
/* no output file (not even stdout) */
|
/* no output file (not even stdout) */
|
||||||
if (listfp == NULL) return;
|
if (listfp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
/*printf("do_listing: listing=%p (%d), bincode=%p (%d)\n", listing, listing_len, bincode, bincode_len);*/
|
/*printf("do_listing: listing=%p (%d), bincode=%p (%d)\n", listing, listing_len, bincode, bincode_len);*/
|
||||||
|
|
||||||
if (bincode_len < 0) bincode_len = -bincode_len;
|
if (bincode_len < 0)
|
||||||
|
bincode_len = -bincode_len;
|
||||||
|
|
||||||
/* do we need a separation line? */
|
/* do we need a separation line? */
|
||||||
if (list_lineno > list_last_lineno + 1) {
|
if (list_lineno > list_last_lineno + 1) {
|
||||||
|
@ -289,7 +293,8 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||||
list_last_lineno = list_lineno;
|
list_last_lineno = list_lineno;
|
||||||
|
|
||||||
// could be extended to include the preamble...
|
// could be extended to include the preamble...
|
||||||
if (formatp->start_line != NULL) formatp->start_line();
|
if (formatp->start_line != NULL)
|
||||||
|
formatp->start_line();
|
||||||
|
|
||||||
buf = list_preamble(buf, list_lineno, lst_seg, lst_pc);
|
buf = list_preamble(buf, list_lineno, lst_seg, lst_pc);
|
||||||
|
|
||||||
|
@ -316,8 +321,10 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||||
// make a break
|
// make a break
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
fprintf(listfp, "%s\n", outline);
|
fprintf(listfp, "%s\n", outline);
|
||||||
if (formatp->end_line != NULL) formatp->end_line();
|
if (formatp->end_line != NULL)
|
||||||
if (formatp->start_line != NULL) formatp->start_line();
|
formatp->end_line();
|
||||||
|
if (formatp->start_line != NULL)
|
||||||
|
formatp->start_line();
|
||||||
buf = outline;
|
buf = outline;
|
||||||
buf = list_preamble(buf, list_lineno, lst_seg, lst_pc + i + 1);
|
buf = list_preamble(buf, list_lineno, lst_seg, lst_pc + i + 1);
|
||||||
}
|
}
|
||||||
|
@ -339,8 +346,10 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||||
// make a break (Note: with original PC, as now the assembler text follows
|
// make a break (Note: with original PC, as now the assembler text follows
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
fprintf(listfp, "%s\n", outline);
|
fprintf(listfp, "%s\n", outline);
|
||||||
if (formatp->end_line != NULL) formatp->end_line();
|
if (formatp->end_line != NULL)
|
||||||
if (formatp->start_line != NULL) formatp->start_line();
|
formatp->end_line();
|
||||||
|
if (formatp->start_line != NULL)
|
||||||
|
formatp->start_line();
|
||||||
buf = outline;
|
buf = outline;
|
||||||
buf = list_preamble(buf, list_lineno, lst_seg, lst_pc);
|
buf = list_preamble(buf, list_lineno, lst_seg, lst_pc);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -373,7 +382,8 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||||
|
|
||||||
fprintf(listfp, "%s\n", outline);
|
fprintf(listfp, "%s\n", outline);
|
||||||
|
|
||||||
if (formatp->end_line != NULL) formatp->end_line();
|
if (formatp->end_line != NULL)
|
||||||
|
formatp->end_line();
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_tokens(char *buf, signed char *input, int len) {
|
int list_tokens(char *buf, signed char *input, int len) {
|
||||||
|
@ -386,7 +396,8 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
int tabval, operator;
|
int tabval, operator;
|
||||||
signed char format;
|
signed char format;
|
||||||
|
|
||||||
if (inp >= len) return 0;
|
if (inp >= len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
tmp = input[inp] & 255;
|
tmp = input[inp] & 255;
|
||||||
|
|
||||||
|
@ -404,8 +415,7 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
|
|
||||||
if (is_cll == CHEAP) {
|
if (is_cll == CHEAP) {
|
||||||
outp += list_char(buf + outp, '@');
|
outp += list_char(buf + outp, '@');
|
||||||
} else
|
} else if (is_cll == UNNAMED_DEF || is_cll == UNNAMED) {
|
||||||
if (is_cll == UNNAMED_DEF || is_cll == UNNAMED) {
|
|
||||||
outp += list_char(buf + outp, ':');
|
outp += list_char(buf + outp, ':');
|
||||||
}
|
}
|
||||||
if (is_cll != UNNAMED) {
|
if (is_cll != UNNAMED) {
|
||||||
|
@ -455,13 +465,15 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
|
|
||||||
switch (input[inp]) {
|
switch (input[inp]) {
|
||||||
case T_CAST:
|
case T_CAST:
|
||||||
outp += list_string(buf+outp, formatp->escape_char(input[inp+1]));
|
outp += list_string(buf + outp,
|
||||||
|
formatp->escape_char(input[inp + 1]));
|
||||||
inp += 2;
|
inp += 2;
|
||||||
break;
|
break;
|
||||||
case T_VALUE:
|
case T_VALUE:
|
||||||
/*outp += list_char(buf+outp, 'V');*/
|
/*outp += list_char(buf+outp, 'V');*/
|
||||||
/* 24 bit value */
|
/* 24 bit value */
|
||||||
tmp = ((input[inp+3]&255)<<16) | ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
tmp = ((input[inp + 3] & 255) << 16) | ((input[inp + 2] & 255) << 8)
|
||||||
|
| (input[inp + 1] & 255);
|
||||||
format = input[inp + 4];
|
format = input[inp + 4];
|
||||||
outp += list_value(buf + outp, tmp, format);
|
outp += list_value(buf + outp, tmp, format);
|
||||||
inp += 5;
|
inp += 5;
|
||||||
|
@ -475,19 +487,20 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
|
|
||||||
// duplicate label name
|
// duplicate label name
|
||||||
if (formatp->start_label != NULL) {
|
if (formatp->start_label != NULL) {
|
||||||
outp += formatp->start_label(buf+outp, l_get_unique_name(tmp));
|
outp += formatp->start_label(buf + outp,
|
||||||
|
l_get_unique_name(tmp));
|
||||||
}
|
}
|
||||||
if (is_cll == CHEAP) {
|
if (is_cll == CHEAP) {
|
||||||
outp += list_char(buf + outp, '@');
|
outp += list_char(buf + outp, '@');
|
||||||
} else
|
} else if (is_cll == UNNAMED || is_cll == UNNAMED_DEF) {
|
||||||
if (is_cll == UNNAMED || is_cll == UNNAMED_DEF) {
|
|
||||||
outp += list_char(buf + outp, ':');
|
outp += list_char(buf + outp, ':');
|
||||||
}
|
}
|
||||||
if (is_cll != UNNAMED) {
|
if (is_cll != UNNAMED) {
|
||||||
outp += list_string(buf + outp, name == NULL ? "<null>" : name);
|
outp += list_string(buf + outp, name == NULL ? "<null>" : name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formatp->end_label != NULL) outp += formatp->end_label(buf+outp);
|
if (formatp->end_label != NULL)
|
||||||
|
outp += formatp->end_label(buf + outp);
|
||||||
|
|
||||||
inp += 3;
|
inp += 3;
|
||||||
operator = 1; /* check if arithmetic operator follows */
|
operator = 1; /* check if arithmetic operator follows */
|
||||||
|
@ -499,10 +512,12 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
if (input[inp + 3] == '=') {
|
if (input[inp + 3] == '=') {
|
||||||
// label definition
|
// label definition
|
||||||
if (formatp->set_anchor != NULL) {
|
if (formatp->set_anchor != NULL) {
|
||||||
outp += formatp->set_anchor(buf+outp, l_get_unique_name(tmp));
|
outp += formatp->set_anchor(buf + outp,
|
||||||
|
l_get_unique_name(tmp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_cll) outp += list_char(buf+outp, '@');
|
if (is_cll)
|
||||||
|
outp += list_char(buf + outp, '@');
|
||||||
outp += list_string(buf + outp, name);
|
outp += list_string(buf + outp, name);
|
||||||
outp += list_char(buf + outp, input[inp + 3]);
|
outp += list_char(buf + outp, input[inp + 3]);
|
||||||
inp += 4;
|
inp += 4;
|
||||||
|
@ -533,12 +548,15 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
tmp = ((input[inp + 5] & 255) << 8) | (input[inp + 4] & 255);
|
tmp = ((input[inp + 5] & 255) << 8) | (input[inp + 4] & 255);
|
||||||
name = l_get_name(tmp, &is_cll);
|
name = l_get_name(tmp, &is_cll);
|
||||||
if (formatp->start_label != NULL) {
|
if (formatp->start_label != NULL) {
|
||||||
outp += formatp->start_label(buf+outp, l_get_unique_name(tmp));
|
outp += formatp->start_label(buf + outp,
|
||||||
|
l_get_unique_name(tmp));
|
||||||
}
|
}
|
||||||
if (is_cll) outp += list_char(buf+outp, '@');
|
if (is_cll)
|
||||||
|
outp += list_char(buf + outp, '@');
|
||||||
outp += list_string(buf + outp, name);
|
outp += list_string(buf + outp, name);
|
||||||
|
|
||||||
if (formatp->end_label != NULL) outp += formatp->end_label(buf+outp);
|
if (formatp->end_label != NULL)
|
||||||
|
outp += formatp->end_label(buf + outp);
|
||||||
/*
|
/*
|
||||||
outp += list_byte(buf+outp, input[inp+1]);
|
outp += list_byte(buf+outp, input[inp+1]);
|
||||||
outp += list_char(buf+outp, '#');
|
outp += list_char(buf+outp, '#');
|
||||||
|
@ -573,7 +591,8 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
default:
|
default:
|
||||||
c = input[inp];
|
c = input[inp];
|
||||||
if (c > 31) {
|
if (c > 31) {
|
||||||
outp += list_string(buf+outp, formatp->escape_char(input[inp]));
|
outp += list_string(buf + outp,
|
||||||
|
formatp->escape_char(input[inp]));
|
||||||
} else {
|
} else {
|
||||||
outp += list_char(buf + outp, '\'');
|
outp += list_char(buf + outp, '\'');
|
||||||
outp += list_byte(buf + outp, input[inp]);
|
outp += list_byte(buf + outp, input[inp]);
|
||||||
|
@ -594,8 +613,7 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
// another operator is expected after the bracket
|
// another operator is expected after the bracket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
end: return outp;
|
||||||
return outp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_string(char *buf, char *string) {
|
int list_string(char *buf, char *string) {
|
||||||
|
@ -624,8 +642,7 @@ int list_value(char *buf, int val, signed char format) {
|
||||||
if (val & (255 << 16)) {
|
if (val & (255 << 16)) {
|
||||||
p += list_byte(buf + p, val >> 16);
|
p += list_byte(buf + p, val >> 16);
|
||||||
p += list_word(buf + p, val);
|
p += list_word(buf + p, val);
|
||||||
} else
|
} else if (val & (255 << 8)) {
|
||||||
if (val & (255<<8)) {
|
|
||||||
p += list_word(buf + p, val);
|
p += list_word(buf + p, val);
|
||||||
} else {
|
} else {
|
||||||
p += list_byte(buf + p, val);
|
p += list_byte(buf + p, val);
|
||||||
|
@ -636,8 +653,7 @@ int list_value(char *buf, int val, signed char format) {
|
||||||
if (val & (255 << 16)) {
|
if (val & (255 << 16)) {
|
||||||
p += list_byte_f(buf + p, val >> 16, '%');
|
p += list_byte_f(buf + p, val >> 16, '%');
|
||||||
p += list_word_f(buf + p, val, '%');
|
p += list_word_f(buf + p, val, '%');
|
||||||
} else
|
} else if (val & (255 << 8)) {
|
||||||
if (val & (255<<8)) {
|
|
||||||
p += list_word_f(buf + p, val, '%');
|
p += list_word_f(buf + p, val, '%');
|
||||||
} else {
|
} else {
|
||||||
p += list_byte_f(buf + p, val, '%');
|
p += list_byte_f(buf + p, val, '%');
|
||||||
|
@ -664,8 +680,7 @@ int list_value(char *buf, int val, signed char format) {
|
||||||
if (val & (255 << 16)) {
|
if (val & (255 << 16)) {
|
||||||
p += list_byte(buf + p, val >> 16);
|
p += list_byte(buf + p, val >> 16);
|
||||||
p += list_word(buf + p, val);
|
p += list_word(buf + p, val);
|
||||||
} else
|
} else if (val & (255 << 8)) {
|
||||||
if (val & (255<<8)) {
|
|
||||||
p += list_word(buf + p, val);
|
p += list_word(buf + p, val);
|
||||||
} else {
|
} else {
|
||||||
p += list_byte(buf + p, val);
|
p += list_byte(buf + p, val);
|
||||||
|
@ -746,5 +761,3 @@ int list_nibble_f(char *buf, int outnib, signed char format) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,6 +29,7 @@ void list_line(int l); /* set line number for the coming listing output
|
||||||
void list_filename(char *fname);/* set file name for the coming listing output */
|
void list_filename(char *fname);/* set file name for the coming listing output */
|
||||||
|
|
||||||
// list a single line/token set
|
// list a single line/token set
|
||||||
void do_listing(signed char *listing, int listing_len, signed char *bincode, int bincode_len);
|
void do_listing(signed char *listing, int listing_len, signed char *bincode,
|
||||||
|
int bincode_len);
|
||||||
|
|
||||||
#endif /* __XA65_XALISTING_H__ */
|
#endif /* __XA65_XALISTING_H__ */
|
||||||
|
|
38
xa/src/xam.c
38
xa/src/xam.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* Memory manager/malloc() stub module
|
* Memory manager/malloc() stub module
|
||||||
*
|
*
|
||||||
|
@ -41,8 +41,7 @@ void reg_include(char *path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *xfopen(const char *fn,const char *mode)
|
FILE* xfopen(const char *fn, const char *mode) {
|
||||||
{
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char c, *cp, n[MAXLINE], path[MAXLINE];
|
char c, *cp, n[MAXLINE], path[MAXLINE];
|
||||||
char xname[MAXLINE], n2[MAXLINE];
|
char xname[MAXLINE], n2[MAXLINE];
|
||||||
|
@ -60,28 +59,26 @@ FILE *xfopen(const char *fn,const char *mode)
|
||||||
|
|
||||||
//printf("name=%s, xname=%s, mode=%s\n",fn,xname, mode);
|
//printf("name=%s, xname=%s, mode=%s\n",fn,xname, mode);
|
||||||
|
|
||||||
if(mode[0]=='r')
|
if (mode[0] == 'r') {
|
||||||
{
|
|
||||||
if ((file = fopen(fn, mode)) == NULL
|
if ((file = fopen(fn, mode)) == NULL
|
||||||
&& (file = fopen(xname, mode)) == NULL) {
|
&& (file = fopen(xname, mode)) == NULL) {
|
||||||
for (i = 0; (!file) && (i < ninc); i++) {
|
for (i = 0; (!file) && (i < ninc); i++) {
|
||||||
strcpy(n, nip[i]);
|
strcpy(n, nip[i]);
|
||||||
c = n[(int) strlen(n) - 1];
|
c = n[(int) strlen(n) - 1];
|
||||||
if(c!=DIRCHAR) strcat(n,DIRCSTRING);
|
if (c != DIRCHAR)
|
||||||
|
strcat(n, DIRCSTRING);
|
||||||
strcpy(n2, n);
|
strcpy(n2, n);
|
||||||
strcat(n2, xname);
|
strcat(n2, xname);
|
||||||
strcat(n, fn);
|
strcat(n, fn);
|
||||||
file = fopen(n, mode);
|
file = fopen(n, mode);
|
||||||
if(!file) file=fopen(n2,mode);
|
if (!file)
|
||||||
|
file = fopen(n2, mode);
|
||||||
}
|
}
|
||||||
if((!file) && (cp=getenv("XAINPUT"))!=NULL)
|
if ((!file) && (cp = getenv("XAINPUT")) != NULL) {
|
||||||
{
|
|
||||||
strcpy(path, cp);
|
strcpy(path, cp);
|
||||||
cp = strtok(path, ",");
|
cp = strtok(path, ",");
|
||||||
while(cp && !file)
|
while (cp && !file) {
|
||||||
{
|
if (cp[0]) {
|
||||||
if(cp[0])
|
|
||||||
{
|
|
||||||
strcpy(n, cp);
|
strcpy(n, cp);
|
||||||
c = n[(int) strlen(n) - 1];
|
c = n[(int) strlen(n) - 1];
|
||||||
if (c != DIRCHAR && c != ':')
|
if (c != DIRCHAR && c != ':')
|
||||||
|
@ -90,26 +87,23 @@ FILE *xfopen(const char *fn,const char *mode)
|
||||||
strcat(n2, xname);
|
strcat(n2, xname);
|
||||||
strcat(n, fn);
|
strcat(n, fn);
|
||||||
file = fopen(n, mode);
|
file = fopen(n, mode);
|
||||||
if(!file) file=fopen(n2,mode);
|
if (!file)
|
||||||
|
file = fopen(n2, mode);
|
||||||
}
|
}
|
||||||
cp = strtok(NULL, ",");
|
cp = strtok(NULL, ",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
{
|
if ((cp = getenv("XAOUTPUT")) != NULL) {
|
||||||
if((cp=getenv("XAOUTPUT"))!=NULL)
|
|
||||||
{
|
|
||||||
strcpy(n, cp);
|
strcpy(n, cp);
|
||||||
if(n[0])
|
if (n[0]) {
|
||||||
{
|
|
||||||
c = n[(int) strlen(n) - 1];
|
c = n[(int) strlen(n) - 1];
|
||||||
if (c != DIRCHAR && c != ':')
|
if (c != DIRCHAR && c != ':')
|
||||||
strcat(n, DIRCSTRING);
|
strcat(n, DIRCSTRING);
|
||||||
}
|
}
|
||||||
cp = strrchr(fn, DIRCHAR);
|
cp = strrchr(fn, DIRCHAR);
|
||||||
if(!cp)
|
if (!cp) {
|
||||||
{
|
|
||||||
cp = strrchr(fn, ':');
|
cp = strrchr(fn, ':');
|
||||||
if (!cp)
|
if (!cp)
|
||||||
cp = (char*) fn;
|
cp = (char*) fn;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
14
xa/src/xao.c
14
xa/src/xao.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* Options module (handles pass options and writing them out to disk)
|
* Options module (handles pass options and writing them out to disk)
|
||||||
*
|
*
|
||||||
|
@ -40,17 +40,19 @@ void set_fopt(int l, signed char *buf, int reallen) {
|
||||||
/*printf("set_fopt(%s, l=%d\n",buf,l);*/
|
/*printf("set_fopt(%s, l=%d\n",buf,l);*/
|
||||||
while (afile->fo.mlist <= afile->fo.nlist) {
|
while (afile->fo.mlist <= afile->fo.nlist) {
|
||||||
afile->fo.mlist += 5;
|
afile->fo.mlist += 5;
|
||||||
afile->fo.olist = realloc(afile->fo.olist, afile->fo.mlist*sizeof(Fopt));
|
afile->fo.olist = realloc(afile->fo.olist,
|
||||||
|
afile->fo.mlist * sizeof(Fopt));
|
||||||
if (!afile->fo.olist) {
|
if (!afile->fo.olist) {
|
||||||
fprintf(stderr, "Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n",
|
fprintf(stderr,
|
||||||
(unsigned long)(
|
"Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n",
|
||||||
afile->fo.mlist*sizeof(Fopt)));
|
(unsigned long) (afile->fo.mlist * sizeof(Fopt)));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
afile->fo.olist[afile->fo.nlist].text = malloc(l);
|
afile->fo.olist[afile->fo.nlist].text = malloc(l);
|
||||||
if (!afile->fo.olist[afile->fo.nlist].text) {
|
if (!afile->fo.olist[afile->fo.nlist].text) {
|
||||||
fprintf(stderr, "Fatal: Couldn't alloc memory (%d bytes) for fopt!\n",l);
|
fprintf(stderr, "Fatal: Couldn't alloc memory (%d bytes) for fopt!\n",
|
||||||
|
l);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memcpy(afile->fo.olist[afile->fo.nlist].text, buf, l);
|
memcpy(afile->fo.olist[afile->fo.nlist].text, buf, l);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
318
xa/src/xap.c
318
xa/src/xap.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
* Maintained by Cameron Kaiser
|
* Maintained by Cameron Kaiser
|
||||||
*
|
*
|
||||||
* File handling and preprocessor (also see xaa.c) module
|
* File handling and preprocessor (also see xaa.c) module
|
||||||
|
@ -65,10 +65,9 @@ static int pp_error(char*);
|
||||||
static int quotebs = 0;
|
static int quotebs = 0;
|
||||||
static int inquote = 0;
|
static int inquote = 0;
|
||||||
|
|
||||||
static char *cmd[]={
|
static char *cmd[] = { "echo", "include", "define", "undef", "printdef",
|
||||||
"echo","include","define","undef","printdef","print","error", /* VALBEF */
|
"print", "error", /* VALBEF */
|
||||||
"ifdef","ifndef","else","endif",
|
"ifdef", "ifndef", "else", "endif", "ifldef", "iflused", "if" }; /* ANZBEF */
|
||||||
"ifldef","iflused","if" }; /* ANZBEF */
|
|
||||||
|
|
||||||
static int (*func[])(char*) = {pp_echo,icl_open,pp_define,pp_undef,
|
static int (*func[])(char*) = {pp_echo,icl_open,pp_define,pp_undef,
|
||||||
pp_prdef,pp_print,pp_error,pp_ifdef,pp_ifndef,
|
pp_prdef,pp_print,pp_error,pp_ifdef,pp_ifndef,
|
||||||
|
@ -88,20 +87,18 @@ static int loopfl;
|
||||||
static Datei flist[MAXFILE + 1];
|
static Datei flist[MAXFILE + 1];
|
||||||
static char in_line[MAXLINE];
|
static char in_line[MAXLINE];
|
||||||
|
|
||||||
int pp_comand(char *t)
|
int pp_comand(char *t) {
|
||||||
{
|
|
||||||
int i, l, er = 1;
|
int i, l, er = 1;
|
||||||
|
|
||||||
i = tcompare(t, cmd, ANZBEF);
|
i = tcompare(t, cmd, ANZBEF);
|
||||||
|
|
||||||
if(i>=0)
|
if (i >= 0) {
|
||||||
{
|
|
||||||
if (loopfl && (i < VALBEF))
|
if (loopfl && (i < VALBEF))
|
||||||
er = 0;
|
er = 0;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
l = (int) strlen(cmd[i]);
|
l = (int) strlen(cmd[i]);
|
||||||
while(isspace(t[l])) l++;
|
while (isspace(t[l]))
|
||||||
|
l++;
|
||||||
|
|
||||||
er = (*func[i])(t + l);
|
er = (*func[i])(t + l);
|
||||||
}
|
}
|
||||||
|
@ -109,8 +106,7 @@ int pp_comand(char *t)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_ifdef(char *t)
|
int pp_ifdef(char *t) {
|
||||||
{
|
|
||||||
/* int x;
|
/* int x;
|
||||||
printf("t=%s\n",t);
|
printf("t=%s\n",t);
|
||||||
x=searchdef(t);
|
x=searchdef(t);
|
||||||
|
@ -120,83 +116,71 @@ int pp_ifdef(char *t)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_ifndef(char *t)
|
int pp_ifndef(char *t) {
|
||||||
{
|
|
||||||
loopfl = (loopfl << 1) + (searchdef(t) ? 1 : 0);
|
loopfl = (loopfl << 1) + (searchdef(t) ? 1 : 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_ifldef(char *t)
|
int pp_ifldef(char *t) {
|
||||||
{
|
|
||||||
loopfl = (loopfl << 1) + (ll_pdef(t) ? 1 : 0);
|
loopfl = (loopfl << 1) + (ll_pdef(t) ? 1 : 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_iflused(char *t)
|
int pp_iflused(char *t) {
|
||||||
{
|
|
||||||
int n;
|
int n;
|
||||||
loopfl = (loopfl << 1) + (ll_search(t, &n, STD) ? 1 : 0);
|
loopfl = (loopfl << 1) + (ll_search(t, &n, STD) ? 1 : 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_echo(char *t)
|
int pp_echo(char *t) {
|
||||||
{
|
|
||||||
int er;
|
int er;
|
||||||
|
|
||||||
if ((er = pp_replace(s, t, -1, rlist)))
|
if ((er = pp_replace(s, t, -1, rlist)))
|
||||||
errout(er);
|
errout(er);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
logout(s);
|
logout(s);
|
||||||
logout("\n");
|
logout("\n");
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_print(char *t)
|
int pp_print(char *t) {
|
||||||
{
|
|
||||||
int f, a, er;
|
int f, a, er;
|
||||||
|
|
||||||
logout(t);
|
logout(t);
|
||||||
if((er=pp_replace(s,t,-1,rlist)))
|
if ((er = pp_replace(s, t, -1, rlist))) {
|
||||||
{
|
|
||||||
logout("\n");
|
logout("\n");
|
||||||
errout(er);
|
errout(er);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
logout("=");
|
logout("=");
|
||||||
logout(s);
|
logout(s);
|
||||||
logout("=");
|
logout("=");
|
||||||
er = b_term(s, &a, &f, pc[segment]);
|
er = b_term(s, &a, &f, pc[segment]);
|
||||||
if(er)
|
if (er) {
|
||||||
{
|
|
||||||
logout("\n");
|
logout("\n");
|
||||||
errout(er);
|
errout(er);
|
||||||
|
} else {
|
||||||
|
sprintf(s, "%d\n", a);
|
||||||
|
logout(s);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ sprintf(s,"%d\n",a); logout(s); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_error(char *t)
|
int pp_error(char *t) {
|
||||||
{
|
|
||||||
/* the offending line is printed for us */
|
/* the offending line is printed for us */
|
||||||
return E_UERROR;
|
return E_UERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_if(char *t)
|
int pp_if(char *t) {
|
||||||
{
|
|
||||||
int a, f, l, er;
|
int a, f, l, er;
|
||||||
|
|
||||||
/* XXX: #if XYZ, if XYZ is not defined, XYZ gets treated as a label. */
|
/* XXX: #if XYZ, if XYZ is not defined, XYZ gets treated as a label. */
|
||||||
|
|
||||||
if ((er = pp_replace(s, t, -1, rlist))) {
|
if ((er = pp_replace(s, t, -1, rlist))) {
|
||||||
errout(er);
|
errout(er);
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
dsb_len = 1;
|
dsb_len = 1;
|
||||||
f = b_term(s, &a, &l, pc[segment]);
|
f = b_term(s, &a, &l, pc[segment]);
|
||||||
dsb_len = 0;
|
dsb_len = 0;
|
||||||
|
@ -209,21 +193,18 @@ int pp_if(char *t)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_else(char *t)
|
int pp_else(char *t) {
|
||||||
{
|
|
||||||
(void) t; /* quench warning */
|
(void) t; /* quench warning */
|
||||||
loopfl ^= 1;
|
loopfl ^= 1;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_endif(char *t)
|
int pp_endif(char *t) {
|
||||||
{
|
|
||||||
(void) t; /* quench warning */
|
(void) t; /* quench warning */
|
||||||
loopfl = loopfl >> 1;
|
loopfl = loopfl >> 1;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* stub for handling CPP directives */
|
/* stub for handling CPP directives */
|
||||||
int pp_cpp(char *t) {
|
int pp_cpp(char *t) {
|
||||||
char name[MAXLINE];
|
char name[MAXLINE];
|
||||||
|
@ -258,23 +239,20 @@ int pp_undef(char *t) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_prdef(char *t)
|
int pp_prdef(char *t) {
|
||||||
{
|
|
||||||
char *x;
|
char *x;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if((i=searchdef(t)))
|
if ((i = searchdef(t))) {
|
||||||
{
|
|
||||||
i += rlist;
|
i += rlist;
|
||||||
x = liste[i].search;
|
x = liste[i].search;
|
||||||
sprintf(s, "\n%s", x);
|
sprintf(s, "\n%s", x);
|
||||||
if(liste[i].p_anz)
|
if (liste[i].p_anz) {
|
||||||
{
|
|
||||||
sprintf(s + strlen(s), "(");
|
sprintf(s + strlen(s), "(");
|
||||||
for(j=0;j<liste[i].p_anz;j++)
|
for (j = 0; j < liste[i].p_anz; j++) {
|
||||||
{
|
|
||||||
x += strlen(x) + 1;
|
x += strlen(x) + 1;
|
||||||
sprintf(s+strlen(s),"%s%c",x,(liste[i].p_anz-j-1) ? ',' : ')');
|
sprintf(s + strlen(s), "%s%c", x,
|
||||||
|
(liste[i].p_anz - j - 1) ? ',' : ')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sprintf(s + strlen(s), "=%s\n", liste[i].replace);
|
sprintf(s + strlen(s), "=%s\n", liste[i].replace);
|
||||||
|
@ -283,14 +261,13 @@ int pp_prdef(char *t)
|
||||||
return (E_OK);
|
return (E_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int searchdef(char *t)
|
int searchdef(char *t) {
|
||||||
{
|
|
||||||
int i = 0, j, k, l = 0;
|
int i = 0, j, k, l = 0;
|
||||||
|
|
||||||
while(t[l]!=' ' && t[l]!='\0') l++;
|
while (t[l] != ' ' && t[l] != '\0')
|
||||||
|
l++;
|
||||||
|
|
||||||
if(rlist)
|
if (rlist) {
|
||||||
{
|
|
||||||
i = hashindex[hashcode(t, l)];
|
i = hashindex[hashcode(t, l)];
|
||||||
|
|
||||||
do /*for(i=0;i<rlist;i++)*/
|
do /*for(i=0;i<rlist;i++)*/
|
||||||
|
@ -298,15 +275,14 @@ int searchdef(char *t)
|
||||||
k = liste[i].s_len;
|
k = liste[i].s_len;
|
||||||
j = 0;
|
j = 0;
|
||||||
|
|
||||||
if(k && (k==l))
|
if (k && (k == l)) {
|
||||||
{
|
while ((t[j] == liste[i].search[j]) && j < k)
|
||||||
while((t[j]==liste[i].search[j])&&j<k) j++;
|
j++;
|
||||||
if (j == k)
|
if (j == k)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!i)
|
if (!i) {
|
||||||
{
|
|
||||||
i = rlist;
|
i = rlist;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -319,28 +295,23 @@ int searchdef(char *t)
|
||||||
return (i - rlist);
|
return (i - rlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ga_pp(void)
|
int ga_pp(void) {
|
||||||
{
|
|
||||||
return (rlist);
|
return (rlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gm_pp(void)
|
int gm_pp(void) {
|
||||||
{
|
|
||||||
return (ANZDEF);
|
return (ANZDEF);
|
||||||
}
|
}
|
||||||
|
|
||||||
long gm_ppm(void)
|
long gm_ppm(void) {
|
||||||
{
|
|
||||||
return (MAXPP);
|
return (MAXPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
long ga_ppm(void)
|
long ga_ppm(void) {
|
||||||
{
|
|
||||||
return (MAXPP - memfre);
|
return (MAXPP - memfre);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_define(char *k)
|
int pp_define(char *k) {
|
||||||
{
|
|
||||||
int i, er = E_OK, hash, rl;
|
int i, er = E_OK, hash, rl;
|
||||||
char h[MAXLINE * 2], *t;
|
char h[MAXLINE * 2], *t;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
@ -363,23 +334,23 @@ int pp_define(char *k)
|
||||||
liste[rl].s_len = i;
|
liste[rl].s_len = i;
|
||||||
liste[rl].p_anz = 0;
|
liste[rl].p_anz = 0;
|
||||||
|
|
||||||
|
|
||||||
/* printf("define:%s\nlen1=%d\n",liste[rl].search,liste[rl].s_len);
|
/* printf("define:%s\nlen1=%d\n",liste[rl].search,liste[rl].s_len);
|
||||||
getchar();
|
getchar();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(t[i]=='(')
|
if (t[i] == '(') {
|
||||||
{
|
while (t[i] != ')' && t[i] != '\0') {
|
||||||
while(t[i]!=')' && t[i]!='\0')
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
liste[rl].p_anz++;
|
liste[rl].p_anz++;
|
||||||
// skip whitespace before parameter name
|
// skip whitespace before parameter name
|
||||||
while(isspace(t[i])) i++;
|
while (isspace(t[i]))
|
||||||
|
i++;
|
||||||
// find length
|
// find length
|
||||||
for(j=0; (!isspace(t[i+j])) && t[i+j]!=')' && t[i+j]!=',' && t[i+j]!='\0';j++);
|
for (j = 0;
|
||||||
if(j<memfre)
|
(!isspace(t[i + j])) && t[i + j] != ')' && t[i + j] != ','
|
||||||
{
|
&& t[i + j] != '\0'; j++)
|
||||||
|
;
|
||||||
|
if (j < memfre) {
|
||||||
strncpy(mem, t + i, j);
|
strncpy(mem, t + i, j);
|
||||||
mem += j;
|
mem += j;
|
||||||
*mem++ = '\0';
|
*mem++ = '\0';
|
||||||
|
@ -387,7 +358,8 @@ int pp_define(char *k)
|
||||||
}
|
}
|
||||||
i += j;
|
i += j;
|
||||||
// skip trailing whitespace after parameter name
|
// skip trailing whitespace after parameter name
|
||||||
while(isspace(t[i])) i++;
|
while (isspace(t[i]))
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
if (t[i] == ')')
|
if (t[i] == ')')
|
||||||
i++;
|
i++;
|
||||||
|
@ -424,8 +396,7 @@ int pp_define(char *k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!er)
|
if (!er) {
|
||||||
{
|
|
||||||
hash = hashcode(liste[rl].search, liste[rl].s_len);
|
hash = hashcode(liste[rl].search, liste[rl].s_len);
|
||||||
liste[rl].nextindex = hashindex[hash];
|
liste[rl].nextindex = hashindex[hash];
|
||||||
hashindex[hash] = rl;
|
hashindex[hash] = rl;
|
||||||
|
@ -435,8 +406,7 @@ int pp_define(char *k)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcompare(char s[],char *v[], int n)
|
int tcompare(char s[], char *v[], int n) {
|
||||||
{
|
|
||||||
int i, j, l;
|
int i, j, l;
|
||||||
static char t[MAXLINE];
|
static char t[MAXLINE];
|
||||||
|
|
||||||
|
@ -444,12 +414,10 @@ int tcompare(char s[],char *v[], int n)
|
||||||
t[i] = tolower(s[i]);
|
t[i] = tolower(s[i]);
|
||||||
t[i] = '\0';
|
t[i] = '\0';
|
||||||
|
|
||||||
for(i=0;i<n;i++)
|
for (i = 0; i < n; i++) {
|
||||||
{
|
|
||||||
l = (int) strlen(v[i]);
|
l = (int) strlen(v[i]);
|
||||||
|
|
||||||
for(j=0;j<l;j++)
|
for (j = 0; j < l; j++) {
|
||||||
{
|
|
||||||
if (t[j] != v[i][j])
|
if (t[j] != v[i][j])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -487,8 +455,8 @@ static int check_name(char *t, int n) {
|
||||||
* blist ->
|
* blist ->
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int *l, int blist)
|
static int pp_replace_part(char *to, char *t, int n, int sl, int recursive,
|
||||||
{
|
int *l, int blist) {
|
||||||
int er = E_OK;
|
int er = E_OK;
|
||||||
int i, d;
|
int i, d;
|
||||||
char c;
|
char c;
|
||||||
|
@ -507,9 +475,7 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
|
|
||||||
// does it have parameters?
|
// does it have parameters?
|
||||||
|
|
||||||
|
if (liste[n].p_anz) {
|
||||||
if(liste[n].p_anz)
|
|
||||||
{
|
|
||||||
// yes, we have parameters, so we need to pp_replace them
|
// yes, we have parameters, so we need to pp_replace them
|
||||||
// as well.
|
// as well.
|
||||||
char fti[MAXLINE], fto[MAXLINE];
|
char fti[MAXLINE], fto[MAXLINE];
|
||||||
|
@ -520,8 +486,7 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
// boundary checks ...
|
// boundary checks ...
|
||||||
if (blist + liste[n].p_anz >= ANZDEF || memfre < MAXLINE * 2)
|
if (blist + liste[n].p_anz >= ANZDEF || memfre < MAXLINE * 2)
|
||||||
er = E_NOMEM;
|
er = E_NOMEM;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// ... passed
|
// ... passed
|
||||||
// y points to the char behind the input name (i.e. the '(')
|
// y points to the char behind the input name (i.e. the '(')
|
||||||
char *y = t + sl;
|
char *y = t + sl;
|
||||||
|
@ -533,17 +498,14 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
if (*y != '(') {
|
if (*y != '(') {
|
||||||
// no. Should probably get an own error (E_PARAMETER_EXPECTED)
|
// no. Should probably get an own error (E_PARAMETER_EXPECTED)
|
||||||
er = E_SYNTAX;
|
er = E_SYNTAX;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// mx now points to next free memory (mem current pointer in text table)
|
// mx now points to next free memory (mem current pointer in text table)
|
||||||
char *mx = mem - 1;
|
char *mx = mem - 1;
|
||||||
// walk through the pp parameters
|
// walk through the pp parameters
|
||||||
// by creating "fake" preprocessor definitions at the end
|
// by creating "fake" preprocessor definitions at the end
|
||||||
// of the current definition list, i.e. in liste[] after index
|
// of the current definition list, i.e. in liste[] after index
|
||||||
// rlist.
|
// rlist.
|
||||||
for(i=0;i<liste[n].p_anz;i++)
|
for (i = 0; i < liste[n].p_anz; i++) {
|
||||||
{
|
|
||||||
char c;
|
char c;
|
||||||
int hkfl = 0; // quote flag
|
int hkfl = 0; // quote flag
|
||||||
int klfl = 0; // brackets counter
|
int klfl = 0; // brackets counter
|
||||||
|
@ -561,17 +523,11 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
c = *(++mx) = *(++y);
|
c = *(++mx) = *(++y);
|
||||||
// copy over the other characters
|
// copy over the other characters
|
||||||
while (c != '\0'
|
while (c != '\0'
|
||||||
&& ((hkfl!=0
|
&& ((hkfl != 0 || klfl != 0)
|
||||||
|| klfl!=0)
|
|| (c != ',' && c != ')'))) {
|
||||||
|| (c!=','
|
|
||||||
&& c!=')')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (c == '\"')
|
if (c == '\"')
|
||||||
hkfl = hkfl ^ 1;
|
hkfl = hkfl ^ 1;
|
||||||
if(!hkfl)
|
if (!hkfl) {
|
||||||
{
|
|
||||||
if (c == '(')
|
if (c == '(')
|
||||||
klfl++;
|
klfl++;
|
||||||
if (c == ')')
|
if (c == ')')
|
||||||
|
@ -584,8 +540,7 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
// if i is for the last parameter, then check if the
|
// if i is for the last parameter, then check if the
|
||||||
// last copied char was ')', otherwise it should be ','
|
// last copied char was ')', otherwise it should be ','
|
||||||
// as separator for the next parameter
|
// as separator for the next parameter
|
||||||
if(c!=((i==liste[n].p_anz-1) ? ')' : ','))
|
if (c != ((i == liste[n].p_anz - 1) ? ')' : ',')) {
|
||||||
{
|
|
||||||
er = E_ANZPAR;
|
er = E_ANZPAR;
|
||||||
// note: this break only exits the innermost loop!
|
// note: this break only exits the innermost loop!
|
||||||
break;
|
break;
|
||||||
|
@ -624,7 +579,8 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
if (!er) {
|
if (!er) {
|
||||||
// replace the tokens in the parameter, adding possible pseudo params
|
// replace the tokens in the parameter, adding possible pseudo params
|
||||||
// on top of the liste[] into nfto
|
// on top of the liste[] into nfto
|
||||||
er=pp_replace(nfto,nfwas,-1,blist+liste[n].p_anz);
|
er = pp_replace(nfto, nfwas, -1,
|
||||||
|
blist + liste[n].p_anz);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_RECMAC
|
#ifdef DEBUG_RECMAC
|
||||||
printf("-%s=%s\n",liste[rlist+i].search,liste[rlist+i].replace);
|
printf("-%s=%s\n",liste[rlist+i].search,liste[rlist+i].replace);
|
||||||
|
@ -681,7 +637,8 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
printf("replace macro: recursive=%d, blist=%d, -> b=%d\n", recursive, blist, blist+liste[n].p_anz);
|
printf("replace macro: recursive=%d, blist=%d, -> b=%d\n", recursive, blist, blist+liste[n].p_anz);
|
||||||
printf(" from: %s\n", fti);
|
printf(" from: %s\n", fti);
|
||||||
#endif
|
#endif
|
||||||
er=pp_replace(fto,fti,recursive ? 0 : blist,blist+liste[n].p_anz);
|
er = pp_replace(fto, fti, recursive ? 0 : blist,
|
||||||
|
blist + liste[n].p_anz);
|
||||||
#ifdef DEBUG_RECMAC
|
#ifdef DEBUG_RECMAC
|
||||||
printf(" to: %s\n", fto);
|
printf(" to: %s\n", fto);
|
||||||
#endif
|
#endif
|
||||||
|
@ -753,8 +710,7 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
|
||||||
* parameters
|
* parameters
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int pp_replace(char *to, char *ti, int a,int b)
|
int pp_replace(char *to, char *ti, int a, int b) {
|
||||||
{
|
|
||||||
char *t = to;
|
char *t = to;
|
||||||
int l, n, sl, er = E_OK;
|
int l, n, sl, er = E_OK;
|
||||||
int ld; // length of name/token to analyse
|
int ld; // length of name/token to analyse
|
||||||
|
@ -767,22 +723,21 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
(void) strcpy(t, ti);
|
(void) strcpy(t, ti);
|
||||||
|
|
||||||
// if there are replacements in the list of replacements
|
// if there are replacements in the list of replacements
|
||||||
if(rlist)
|
if (rlist) {
|
||||||
{
|
|
||||||
// loop over the whole input
|
// loop over the whole input
|
||||||
while(t[0]!='\0' && t[0] != ';')
|
while (t[0] != '\0' && t[0] != ';') {
|
||||||
{
|
|
||||||
// skip over the whitespace
|
// skip over the whitespace
|
||||||
// comment handling is NASTY NASTY NASTY
|
// comment handling is NASTY NASTY NASTY
|
||||||
// but I currently don't see another way, as comments and colons
|
// but I currently don't see another way, as comments and colons
|
||||||
// can (and do) appear in preprocessor replacements
|
// can (and do) appear in preprocessor replacements
|
||||||
char quotefl = 0;
|
char quotefl = 0;
|
||||||
char commentfl = 0;
|
char commentfl = 0;
|
||||||
while((t[0] != 0) && (quotefl || commentfl || ((!isalpha(t[0]) && t[0]!='_')))) {
|
while ((t[0] != 0)
|
||||||
|
&& (quotefl || commentfl
|
||||||
|
|| ((!isalpha(t[0]) && t[0] != '_')))) {
|
||||||
if (t[0] == '\0') {
|
if (t[0] == '\0') {
|
||||||
break; /*return(E_OK);*/
|
break; /*return(E_OK);*/
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
if (t[0] == ';' && !quotefl) {
|
if (t[0] == ';' && !quotefl) {
|
||||||
commentfl = 1;
|
commentfl = 1;
|
||||||
}
|
}
|
||||||
|
@ -796,8 +751,7 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
if (t[0] == quotefl) {
|
if (t[0] == quotefl) {
|
||||||
quotefl = 0;
|
quotefl = 0;
|
||||||
}
|
}
|
||||||
} else
|
} else if (t[0] == '"' || t[0] == '\'') {
|
||||||
if (t[0] == '"' || t[0] == '\'') {
|
|
||||||
quotefl = t[0];
|
quotefl = t[0];
|
||||||
}
|
}
|
||||||
t++;
|
t++;
|
||||||
|
@ -806,7 +760,8 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine the length of the name
|
// determine the length of the name
|
||||||
for(l=0;isalnum(t[l])||t[l]=='_';l++);
|
for (l = 0; isalnum(t[l]) || t[l] == '_'; l++)
|
||||||
|
;
|
||||||
// store in ld
|
// store in ld
|
||||||
ld = l;
|
ld = l;
|
||||||
#ifdef DEBUG_RECMAC
|
#ifdef DEBUG_RECMAC
|
||||||
|
@ -815,8 +770,7 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
|
|
||||||
// the following if() is executed when being called from an
|
// the following if() is executed when being called from an
|
||||||
// 'external' context, i.e. not from a recursion
|
// 'external' context, i.e. not from a recursion
|
||||||
if(a<0)
|
if (a < 0) {
|
||||||
{
|
|
||||||
// when called from an external context, not by recursion
|
// when called from an external context, not by recursion
|
||||||
|
|
||||||
// compute hashcode for the name for the search index entry (liste[n])
|
// compute hashcode for the name for the search index entry (liste[n])
|
||||||
|
@ -832,8 +786,7 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
printf("macro entry: name=%s, sl=%d, p_anz=%d\n", liste[n].search, sl, liste[n].p_anz);
|
printf("macro entry: name=%s, sl=%d, p_anz=%d\n", liste[n].search, sl, liste[n].p_anz);
|
||||||
#endif
|
#endif
|
||||||
// does pp definition match what we have found?
|
// does pp definition match what we have found?
|
||||||
if(sl && (sl==l) && check_name(t, n))
|
if (sl && (sl == l) && check_name(t, n)) {
|
||||||
{
|
|
||||||
er = pp_replace_part(to, t, n, sl, 0, &l, b);
|
er = pp_replace_part(to, t, n, sl, 0, &l, b);
|
||||||
if (er != E_OK) {
|
if (er != E_OK) {
|
||||||
return er;
|
return er;
|
||||||
|
@ -847,18 +800,15 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
n = liste[n].nextindex;
|
n = liste[n].nextindex;
|
||||||
|
|
||||||
} while (1);
|
} while (1);
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
// called when in recursive call
|
// called when in recursive call
|
||||||
// loop over all the replacement entries from the given b down to 0
|
// loop over all the replacement entries from the given b down to 0
|
||||||
// that allows to replace the parameters first (as they were added at
|
// that allows to replace the parameters first (as they were added at
|
||||||
// the end of the list)
|
// the end of the list)
|
||||||
for(n=b-1;n>=a;n--)
|
for (n = b - 1; n >= a; n--) {
|
||||||
{
|
|
||||||
sl = liste[n].s_len;
|
sl = liste[n].s_len;
|
||||||
|
|
||||||
if(sl && (sl==l) && check_name(t, n))
|
if (sl && (sl == l) && check_name(t, n)) {
|
||||||
{
|
|
||||||
er = pp_replace_part(to, t, n, sl, 1, &l, b);
|
er = pp_replace_part(to, t, n, sl, 1, &l, b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -873,8 +823,7 @@ int pp_replace(char *to, char *ti, int a,int b)
|
||||||
return (E_OK);
|
return (E_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_init(void)
|
int pp_init(void) {
|
||||||
{
|
|
||||||
int er;
|
int er;
|
||||||
|
|
||||||
for (er = 0; er < 256; er++)
|
for (er = 0; er < 256; er++)
|
||||||
|
@ -884,7 +833,8 @@ int pp_init(void)
|
||||||
|
|
||||||
er = 0;
|
er = 0;
|
||||||
mem = malloc(MAXPP);
|
mem = malloc(MAXPP);
|
||||||
if(!mem) er=E_NOMEM;
|
if (!mem)
|
||||||
|
er = E_NOMEM;
|
||||||
|
|
||||||
memfre = MAXPP;
|
memfre = MAXPP;
|
||||||
rlist = 0;
|
rlist = 0;
|
||||||
|
@ -892,18 +842,20 @@ int pp_init(void)
|
||||||
nff = 1;
|
nff = 1;
|
||||||
if (!er) {
|
if (!er) {
|
||||||
liste = malloc((long) ANZDEF * sizeof(List));
|
liste = malloc((long) ANZDEF * sizeof(List));
|
||||||
if(!liste) er=E_NOMEM;
|
if (!liste)
|
||||||
|
er = E_NOMEM;
|
||||||
if (!er && !xa23) {
|
if (!er && !xa23) {
|
||||||
er = pp_define("XA_MAJOR " progmajor);
|
er = pp_define("XA_MAJOR " progmajor);
|
||||||
if (!er) er = pp_define("XA_MINOR " progminor);
|
if (!er)
|
||||||
if (!er) er = pp_define("XA_PATCH " progpatch);
|
er = pp_define("XA_MINOR " progminor);
|
||||||
|
if (!er)
|
||||||
|
er = pp_define("XA_PATCH " progpatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pp_open(char *name)
|
int pp_open(char *name) {
|
||||||
{
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
|
@ -927,29 +879,30 @@ int pp_open(char *name)
|
||||||
return (fp == NULL);
|
return (fp == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_close(void)
|
void pp_close(void) {
|
||||||
{
|
|
||||||
if (flist[fsp].bdepth != b_depth()) {
|
if (flist[fsp].bdepth != b_depth()) {
|
||||||
fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
|
fprintf(stderr,
|
||||||
|
"Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
|
||||||
flist[fsp].fname, flist[fsp].bdepth, b_depth());
|
flist[fsp].fname, flist[fsp].bdepth, b_depth());
|
||||||
}
|
}
|
||||||
fclose(flist[fsp].filep);
|
fclose(flist[fsp].filep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_end(void) { }
|
void pp_end(void) {
|
||||||
|
}
|
||||||
|
|
||||||
Datei* pp_getidat(void) {
|
Datei* pp_getidat(void) {
|
||||||
return &flist[fsp];
|
return &flist[fsp];
|
||||||
}
|
}
|
||||||
|
|
||||||
int icl_close(int *c)
|
int icl_close(int *c) {
|
||||||
{
|
|
||||||
*c = '\n';
|
*c = '\n';
|
||||||
if (!fsp)
|
if (!fsp)
|
||||||
return (E_EOF);
|
return (E_EOF);
|
||||||
|
|
||||||
if (flist[fsp].bdepth != b_depth()) {
|
if (flist[fsp].bdepth != b_depth()) {
|
||||||
fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
|
fprintf(stderr,
|
||||||
|
"Blocks not consistent in file %s: start depth=%d, end depth=%d\n",
|
||||||
flist[fsp].fname, flist[fsp].bdepth, b_depth());
|
flist[fsp].fname, flist[fsp].bdepth, b_depth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,8 +912,7 @@ int icl_close(int *c)
|
||||||
return (E_OK);
|
return (E_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icl_open(char *tt)
|
int icl_open(char *tt) {
|
||||||
{
|
|
||||||
FILE *fp2;
|
FILE *fp2;
|
||||||
char *namep;
|
char *namep;
|
||||||
int len, j, i = 0;
|
int len, j, i = 0;
|
||||||
|
@ -1006,9 +958,7 @@ int icl_open(char *tt)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pgetline(char *t) {
|
||||||
int pgetline(char *t)
|
|
||||||
{
|
|
||||||
int c, er = E_OK;
|
int c, er = E_OK;
|
||||||
int rlen, tlen;
|
int rlen, tlen;
|
||||||
char *p = 0;
|
char *p = 0;
|
||||||
|
@ -1022,11 +972,13 @@ int pgetline(char *t)
|
||||||
int is_continuation = 0;
|
int is_continuation = 0;
|
||||||
tlen = 0; // start of current line in in_line[]
|
tlen = 0; // start of current line in in_line[]
|
||||||
do {
|
do {
|
||||||
c=fgetline(in_line + tlen, MAXLINE - tlen, &rlen, flist[fsp].filep);
|
c = fgetline(in_line + tlen, MAXLINE - tlen, &rlen,
|
||||||
|
flist[fsp].filep);
|
||||||
//fprintf(stderr, "fgetline -> c=%02x, rlen->%d, t->%s\n", c, rlen, in_line+tlen);
|
//fprintf(stderr, "fgetline -> c=%02x, rlen->%d, t->%s\n", c, rlen, in_line+tlen);
|
||||||
|
|
||||||
/* check for continuation lines */
|
/* check for continuation lines */
|
||||||
is_continuation = ((c == '\n') && (rlen > 0) && (in_line[tlen + rlen - 1]=='\\'));
|
is_continuation = ((c == '\n') && (rlen > 0)
|
||||||
|
&& (in_line[tlen + rlen - 1] == '\\'));
|
||||||
if (is_continuation) {
|
if (is_continuation) {
|
||||||
// cut off the continuation character
|
// cut off the continuation character
|
||||||
rlen--;
|
rlen--;
|
||||||
|
@ -1036,16 +988,13 @@ int pgetline(char *t)
|
||||||
tlen += rlen;
|
tlen += rlen;
|
||||||
} while (is_continuation);
|
} while (is_continuation);
|
||||||
|
|
||||||
if(in_line[0]=='#' || in_line[0] == altppchar)
|
if (in_line[0] == '#' || in_line[0] == altppchar) {
|
||||||
{
|
|
||||||
if (in_line[1] == ' ') { /* cpp comment -- pp_comand doesn't
|
if (in_line[1] == ' ') { /* cpp comment -- pp_comand doesn't
|
||||||
handle this right */
|
handle this right */
|
||||||
er = pp_cpp(in_line + 1);
|
er = pp_cpp(in_line + 1);
|
||||||
} else {
|
} else {
|
||||||
if((er=pp_comand(in_line+1)))
|
if ((er = pp_comand(in_line + 1))) {
|
||||||
{
|
if (er != 1) {
|
||||||
if(er!=1)
|
|
||||||
{
|
|
||||||
logout(in_line);
|
logout(in_line);
|
||||||
logout("\n");
|
logout("\n");
|
||||||
}
|
}
|
||||||
|
@ -1058,8 +1007,8 @@ int pgetline(char *t)
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
if (loopfl && fsp) {
|
if (loopfl && fsp) {
|
||||||
char bletch[MAXLINE];
|
char bletch[MAXLINE];
|
||||||
sprintf(bletch,
|
sprintf(bletch, "at end of included file %s:\n",
|
||||||
"at end of included file %s:\n", flist[fsp].fname);
|
flist[fsp].fname);
|
||||||
logout(bletch);
|
logout(bletch);
|
||||||
errout(W_OPENPP);
|
errout(W_OPENPP);
|
||||||
}
|
}
|
||||||
|
@ -1072,7 +1021,6 @@ int pgetline(char *t)
|
||||||
errout(E_OPENPP);
|
errout(E_OPENPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!er || loopfl) {
|
if (!er || loopfl) {
|
||||||
in_line[0] = '\0';
|
in_line[0] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -1102,12 +1050,10 @@ int pgetline(char *t)
|
||||||
return (er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
/* smart getc that can skip C comment blocks */
|
/* smart getc that can skip C comment blocks */
|
||||||
int rgetc(FILE *fp)
|
int rgetc(FILE *fp) {
|
||||||
{
|
|
||||||
int incomment;
|
int incomment;
|
||||||
int c;
|
int c;
|
||||||
static int d;
|
static int d;
|
||||||
|
@ -1116,8 +1062,7 @@ int rgetc(FILE *fp)
|
||||||
|
|
||||||
incomment = 0;
|
incomment = 0;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
restart:
|
restart:
|
||||||
|
|
||||||
/* we had a look-ahead to see if two-char sequence was received? */
|
/* we had a look-ahead to see if two-char sequence was received? */
|
||||||
|
@ -1141,8 +1086,7 @@ int rgetc(FILE *fp)
|
||||||
|
|
||||||
/* check for start of comment anyway, to allow for nested comments */
|
/* check for start of comment anyway, to allow for nested comments */
|
||||||
/* only allow this with 2.3 compatibility */
|
/* only allow this with 2.3 compatibility */
|
||||||
if(!inquote && c=='/' && (xa23 || !incomment))
|
if (!inquote && c == '/' && (xa23 || !incomment)) {
|
||||||
{
|
|
||||||
d = getc(fp);
|
d = getc(fp);
|
||||||
|
|
||||||
// C++ double slash comment
|
// C++ double slash comment
|
||||||
|
@ -1154,8 +1098,7 @@ int rgetc(FILE *fp)
|
||||||
flist[fsp].fline++;
|
flist[fsp].fline++;
|
||||||
nlf = 1;
|
nlf = 1;
|
||||||
}
|
}
|
||||||
} else
|
} else if (d == '*') {
|
||||||
if (d == '*') {
|
|
||||||
/* start block comment */
|
/* start block comment */
|
||||||
incomment++;
|
incomment++;
|
||||||
/* convene normal processing */
|
/* convene normal processing */
|
||||||
|
@ -1165,7 +1108,6 @@ int rgetc(FILE *fp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* here we are in a dilemma. If we interpret quotes in comments,
|
/* here we are in a dilemma. If we interpret quotes in comments,
|
||||||
* this may break end-of-block comment when singular quotes are
|
* this may break end-of-block comment when singular quotes are
|
||||||
* in a comment. If we don't interpret quotes in a comment,
|
* in a comment. If we don't interpret quotes in a comment,
|
||||||
|
@ -1194,15 +1136,17 @@ int rgetc(FILE *fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* implement backslashed quotes for 2.4 */
|
/* implement backslashed quotes for 2.4 */
|
||||||
if(!xa23 && c=='\\') quotebs=1; else quotebs=0;
|
if (!xa23 && c == '\\')
|
||||||
|
quotebs = 1;
|
||||||
|
else
|
||||||
|
quotebs = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* in comment */
|
/* in comment */
|
||||||
|
|
||||||
/* check for end of comment */
|
/* check for end of comment */
|
||||||
/* note: for xa2.3, incomment only set true if not quoted, and quote not changed in comment */
|
/* note: for xa2.3, incomment only set true if not quoted, and quote not changed in comment */
|
||||||
if((!inquote || !xa23) && (c=='*'))
|
if ((!inquote || !xa23) && (c == '*')) {
|
||||||
{
|
|
||||||
if ((d = getc(fp)) != '/') {
|
if ((d = getc(fp)) != '/') {
|
||||||
d_isvalid = 1;
|
d_isvalid = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1232,8 +1176,7 @@ int rgetc(FILE *fp)
|
||||||
* the rlen out parameter is just convenience, so that
|
* the rlen out parameter is just convenience, so that
|
||||||
* a further strlen() can be saved
|
* a further strlen() can be saved
|
||||||
*/
|
*/
|
||||||
int fgetline(char *t, int len, int *rlen, FILE *fp)
|
int fgetline(char *t, int len, int *rlen, FILE *fp) {
|
||||||
{
|
|
||||||
static int c, i;
|
static int c, i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -1241,8 +1184,7 @@ int fgetline(char *t, int len, int *rlen, FILE *fp)
|
||||||
do {
|
do {
|
||||||
c = rgetc(fp);
|
c = rgetc(fp);
|
||||||
|
|
||||||
if(c==EOF || c=='\n')
|
if (c == EOF || c == '\n') {
|
||||||
{
|
|
||||||
t[i] = '\0';
|
t[i] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
50
xa/src/xar.c
50
xa/src/xar.c
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* Relocation module (for relocatable objects)
|
* Relocation module (for relocatable objects)
|
||||||
*
|
*
|
||||||
|
@ -50,12 +50,13 @@ printf("set relocation @$%04x, l=%d, afl=%04x, segment=%d, label=%d\n",
|
||||||
pc, l, afl,segment, label);
|
pc, l, afl,segment, label);
|
||||||
#endif
|
#endif
|
||||||
if (((afl & A_FMASK) == (SEG_UNDEF << 8))
|
if (((afl & A_FMASK) == (SEG_UNDEF << 8))
|
||||||
|| ((afl & A_FMASK) == (SEG_UNDEFZP<<8))
|
|| ((afl & A_FMASK) == (SEG_UNDEFZP << 8))) {
|
||||||
) {
|
|
||||||
label = u_label(label); /* set label as undefined */
|
label = u_label(label); /* set label as undefined */
|
||||||
}
|
}
|
||||||
if(segment==SEG_TEXT) return rt_set(pc,afl,l,label);
|
if (segment == SEG_TEXT)
|
||||||
if(segment==SEG_DATA) return rd_set(pc,afl,l,label);
|
return rt_set(pc, afl, l, label);
|
||||||
|
if (segment == SEG_DATA)
|
||||||
|
return rd_set(pc, afl, l, label);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +77,8 @@ void r_mode(int m) {
|
||||||
int rt_set(int pc, int afl, int l, int lab) {
|
int rt_set(int pc, int afl, int l, int lab) {
|
||||||
int p, pp;
|
int p, pp;
|
||||||
|
|
||||||
if(!rmode) return 0;
|
if (!rmode)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*printf("set relocation @$%04x, l=%d, afl=%04x\n",pc, l, afl);*/
|
/*printf("set relocation @$%04x, l=%d, afl=%04x\n",pc, l, afl);*/
|
||||||
|
|
||||||
|
@ -86,8 +88,7 @@ int rt_set(int pc, int afl, int l, int lab) {
|
||||||
}
|
}
|
||||||
if (l == 1 && ((afl & A_MASK) == A_ADR)) {
|
if (l == 1 && ((afl & A_MASK) == A_ADR)) {
|
||||||
if (((afl & A_FMASK) != (SEG_ZERO << 8))
|
if (((afl & A_FMASK) != (SEG_ZERO << 8))
|
||||||
&& ((afl & A_FMASK) != (SEG_UNDEFZP<<8))
|
&& ((afl & A_FMASK) != (SEG_UNDEFZP << 8))) {
|
||||||
) {
|
|
||||||
/*printf("afl=%04x\n",afl);*/
|
/*printf("afl=%04x\n",afl);*/
|
||||||
errout(W_ADRRELOC);
|
errout(W_ADRRELOC);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +98,8 @@ int rt_set(int pc, int afl, int l, int lab) {
|
||||||
|
|
||||||
if (afile->rt.nlist >= afile->rt.mlist) {
|
if (afile->rt.nlist >= afile->rt.mlist) {
|
||||||
afile->rt.mlist += 500;
|
afile->rt.mlist += 500;
|
||||||
afile->rt.rlist=realloc(afile->rt.rlist, afile->rt.mlist*sizeof(relocateInfo));
|
afile->rt.rlist = realloc(afile->rt.rlist,
|
||||||
|
afile->rt.mlist * sizeof(relocateInfo));
|
||||||
}
|
}
|
||||||
if (!afile->rt.rlist) {
|
if (!afile->rt.rlist) {
|
||||||
fprintf(stderr, "Oops: no memory for relocation table!\n");
|
fprintf(stderr, "Oops: no memory for relocation table!\n");
|
||||||
|
@ -113,7 +115,8 @@ int rt_set(int pc, int afl, int l, int lab) {
|
||||||
if (afile->rt.first < 0) {
|
if (afile->rt.first < 0) {
|
||||||
afile->rt.first = afile->rt.nlist;
|
afile->rt.first = afile->rt.nlist;
|
||||||
} else {
|
} else {
|
||||||
p=afile->rt.first; pp=-1;
|
p = afile->rt.first;
|
||||||
|
pp = -1;
|
||||||
while (afile->rt.rlist[p].adr < pc && afile->rt.rlist[p].next >= 0) {
|
while (afile->rt.rlist[p].adr < pc && afile->rt.rlist[p].next >= 0) {
|
||||||
pp = p;
|
pp = p;
|
||||||
p = afile->rt.rlist[p].next;
|
p = afile->rt.rlist[p].next;
|
||||||
|
@ -124,8 +127,7 @@ printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
||||||
*/
|
*/
|
||||||
if (afile->rt.rlist[p].next < 0 && afile->rt.rlist[p].adr < pc) {
|
if (afile->rt.rlist[p].next < 0 && afile->rt.rlist[p].adr < pc) {
|
||||||
afile->rt.rlist[p].next = afile->rt.nlist;
|
afile->rt.rlist[p].next = afile->rt.nlist;
|
||||||
} else
|
} else if (pp == -1) {
|
||||||
if(pp==-1) {
|
|
||||||
afile->rt.rlist[afile->rt.nlist].next = afile->rt.first;
|
afile->rt.rlist[afile->rt.nlist].next = afile->rt.first;
|
||||||
afile->rt.first = afile->rt.nlist;
|
afile->rt.first = afile->rt.nlist;
|
||||||
} else {
|
} else {
|
||||||
|
@ -146,7 +148,8 @@ int rt_write(FILE *fp, int pc) {
|
||||||
pc2 = afile->rt.rlist[p].adr;
|
pc2 = afile->rt.rlist[p].adr;
|
||||||
afl = afile->rt.rlist[p].afl;
|
afl = afile->rt.rlist[p].afl;
|
||||||
/* hack to switch undef and abs flag from internal to file format */
|
/* hack to switch undef and abs flag from internal to file format */
|
||||||
if( ((afl & A_FMASK)>>8) < SEG_TEXT) afl^=0x100;
|
if (((afl & A_FMASK) >> 8) < SEG_TEXT)
|
||||||
|
afl ^= 0x100;
|
||||||
/*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/
|
/*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/
|
||||||
if ((pc2 - pc) < 0) {
|
if ((pc2 - pc) < 0) {
|
||||||
fprintf(stderr, "Oops, negative offset!\n");
|
fprintf(stderr, "Oops, negative offset!\n");
|
||||||
|
@ -168,7 +171,8 @@ int rt_write(FILE *fp, int pc) {
|
||||||
fputc((afile->rt.rlist[p].lab >> 8) & 255, fp);
|
fputc((afile->rt.rlist[p].lab >> 8) & 255, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((afl&A_MASK)==A_HIGH) fputc(afl&255,fp);
|
if ((afl & A_MASK) == A_HIGH)
|
||||||
|
fputc(afl & 255, fp);
|
||||||
}
|
}
|
||||||
p = afile->rt.rlist[p].next;
|
p = afile->rt.rlist[p].next;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +186,6 @@ int rt_write(FILE *fp, int pc) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void seg_start(int fmode, int t_base, int d_base, int b_base, int z_base,
|
void seg_start(int fmode, int t_base, int d_base, int b_base, int z_base,
|
||||||
int slen, int relmode) {
|
int slen, int relmode) {
|
||||||
afile->fmode = fmode;
|
afile->fmode = fmode;
|
||||||
|
@ -198,7 +201,6 @@ void seg_start(int fmode, int t_base, int d_base, int b_base, int z_base,
|
||||||
pc[SEG_ABS] = pc[SEG_TEXT];
|
pc[SEG_ABS] = pc[SEG_TEXT];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
File* alloc_file(void) {
|
File* alloc_file(void) {
|
||||||
File *afile;
|
File *afile;
|
||||||
int i;
|
int i;
|
||||||
|
@ -217,21 +219,25 @@ File *alloc_file(void) {
|
||||||
afile->mn.tmpz = 0;
|
afile->mn.tmpz = 0;
|
||||||
afile->mn.tmpe = 0;
|
afile->mn.tmpe = 0;
|
||||||
|
|
||||||
afile->ud.ulist = NULL; afile->ud.un = afile->ud.um = 0;
|
afile->ud.ulist = NULL;
|
||||||
afile->rt.rlist = NULL; afile->rt.first = -1;
|
afile->ud.un = afile->ud.um = 0;
|
||||||
|
afile->rt.rlist = NULL;
|
||||||
|
afile->rt.first = -1;
|
||||||
afile->rt.mlist = afile->rt.nlist = 0;
|
afile->rt.mlist = afile->rt.nlist = 0;
|
||||||
afile->rd.rlist = NULL; afile->rd.first = -1;
|
afile->rd.rlist = NULL;
|
||||||
|
afile->rd.first = -1;
|
||||||
afile->rd.mlist = afile->rd.nlist = 0;
|
afile->rd.mlist = afile->rd.nlist = 0;
|
||||||
afile->fo.olist = NULL;
|
afile->fo.olist = NULL;
|
||||||
afile->fo.mlist = afile->fo.nlist = 0;
|
afile->fo.mlist = afile->fo.nlist = 0;
|
||||||
|
|
||||||
for(i=0;i<256;i++) afile->la.hashindex[i]=0;
|
for (i = 0; i < 256; i++)
|
||||||
|
afile->la.hashindex[i] = 0;
|
||||||
afile->la.lt = NULL;
|
afile->la.lt = NULL;
|
||||||
afile->la.lti = 0;
|
afile->la.lti = 0;
|
||||||
afile->la.ltm = 0;
|
afile->la.ltm = 0;
|
||||||
|
|
||||||
afile->len[SEG_TEXT] = afile->len[SEG_DATA] =
|
afile->len[SEG_TEXT] = afile->len[SEG_DATA] = afile->len[SEG_BSS] =
|
||||||
afile->len[SEG_BSS] = afile->len[SEG_ZERO] = 0;
|
afile->len[SEG_ZERO] = 0;
|
||||||
|
|
||||||
return afile;
|
return afile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -44,14 +44,16 @@ int rd_set(int pc, int afl, int l, int lab) {
|
||||||
/*printf("Warning: byte relocation in word value at PC=$%04x!\n",pc);*/
|
/*printf("Warning: byte relocation in word value at PC=$%04x!\n",pc);*/
|
||||||
}
|
}
|
||||||
if (l == 1 && ((afl & A_MASK) == A_ADR)) {
|
if (l == 1 && ((afl & A_MASK) == A_ADR)) {
|
||||||
if((afl & A_FMASK) != (SEG_ZERO<<8)) errout(W_ADRRELOC);
|
if ((afl & A_FMASK) != (SEG_ZERO << 8))
|
||||||
|
errout(W_ADRRELOC);
|
||||||
/*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/
|
/*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/
|
||||||
afl = (afl & (~A_MASK)) | A_LOW;
|
afl = (afl & (~A_MASK)) | A_LOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afile->rd.nlist >= afile->rd.mlist) {
|
if (afile->rd.nlist >= afile->rd.mlist) {
|
||||||
afile->rd.mlist += 500;
|
afile->rd.mlist += 500;
|
||||||
afile->rd.rlist=realloc(afile->rd.rlist, afile->rd.mlist*sizeof(relocateInfo));
|
afile->rd.rlist = realloc(afile->rd.rlist,
|
||||||
|
afile->rd.mlist * sizeof(relocateInfo));
|
||||||
}
|
}
|
||||||
if (!afile->rd.rlist) {
|
if (!afile->rd.rlist) {
|
||||||
fprintf(stderr, "Oops: no memory for relocation table!\n");
|
fprintf(stderr, "Oops: no memory for relocation table!\n");
|
||||||
|
@ -67,7 +69,8 @@ int rd_set(int pc, int afl, int l, int lab) {
|
||||||
if (afile->rd.first < 0) {
|
if (afile->rd.first < 0) {
|
||||||
afile->rd.first = afile->rd.nlist;
|
afile->rd.first = afile->rd.nlist;
|
||||||
} else {
|
} else {
|
||||||
p=afile->rd.first; pp=-1;
|
p = afile->rd.first;
|
||||||
|
pp = -1;
|
||||||
while (afile->rd.rlist[p].adr < pc && afile->rd.rlist[p].next >= 0) {
|
while (afile->rd.rlist[p].adr < pc && afile->rd.rlist[p].next >= 0) {
|
||||||
pp = p;
|
pp = p;
|
||||||
p = afile->rd.rlist[p].next;
|
p = afile->rd.rlist[p].next;
|
||||||
|
@ -78,8 +81,7 @@ printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
||||||
*/
|
*/
|
||||||
if (afile->rd.rlist[p].next < 0 && afile->rd.rlist[p].adr < pc) {
|
if (afile->rd.rlist[p].next < 0 && afile->rd.rlist[p].adr < pc) {
|
||||||
afile->rd.rlist[p].next = afile->rd.nlist;
|
afile->rd.rlist[p].next = afile->rd.nlist;
|
||||||
} else
|
} else if (pp == -1) {
|
||||||
if(pp==-1) {
|
|
||||||
afile->rd.rlist[afile->rd.nlist].next = afile->rd.first;
|
afile->rd.rlist[afile->rd.nlist].next = afile->rd.first;
|
||||||
afile->rd.first = afile->rd.nlist;
|
afile->rd.first = afile->rd.nlist;
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,7 +103,8 @@ int rd_write(FILE *fp, int pc) {
|
||||||
afl = afile->rd.rlist[p].afl;
|
afl = afile->rd.rlist[p].afl;
|
||||||
/*printf("rd_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/
|
/*printf("rd_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/
|
||||||
/* hack to switch undef and abs flag from internal to file format */
|
/* hack to switch undef and abs flag from internal to file format */
|
||||||
if( ((afl & A_FMASK)>>8) < SEG_TEXT) afl^=0x100;
|
if (((afl & A_FMASK) >> 8) < SEG_TEXT)
|
||||||
|
afl ^= 0x100;
|
||||||
if ((pc2 - pc) < 0) {
|
if ((pc2 - pc) < 0) {
|
||||||
fprintf(stderr, "Oops, negative offset!\n");
|
fprintf(stderr, "Oops, negative offset!\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,7 +125,8 @@ int rd_write(FILE *fp, int pc) {
|
||||||
fputc((afile->rd.rlist[p].lab >> 8) & 255, fp);
|
fputc((afile->rd.rlist[p].lab >> 8) & 255, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((afl&A_MASK)==A_HIGH) fputc(afl&255,fp);
|
if ((afl & A_MASK) == A_HIGH)
|
||||||
|
fputc(afl & 255, fp);
|
||||||
}
|
}
|
||||||
p = afile->rd.rlist[p].next;
|
p = afile->rd.rlist[p].next;
|
||||||
}
|
}
|
||||||
|
|
866
xa/src/xat.c
866
xa/src/xat.c
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
* Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
/* xa65 - 65xx/65816 cross-assembler and utility suite
|
||||||
*
|
*
|
||||||
* Copyright (C) 1989-1997 André Fachat (fachat@web.de)
|
* Copyright (C) 1989-1997 Andr<EFBFBD> Fachat (fachat@web.de)
|
||||||
*
|
*
|
||||||
* Undefined label tracking module (also see xal.c)
|
* Undefined label tracking module (also see xal.c)
|
||||||
*
|
*
|
||||||
|
@ -36,11 +36,13 @@ printf("u_label: %d\n",labnr);
|
||||||
#endif
|
#endif
|
||||||
if (!afile->ud.ulist) {
|
if (!afile->ud.ulist) {
|
||||||
afile->ud.ulist = malloc(200 * sizeof(int));
|
afile->ud.ulist = malloc(200 * sizeof(int));
|
||||||
if(afile->ud.ulist) afile->ud.um=200;
|
if (afile->ud.ulist)
|
||||||
|
afile->ud.um = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < afile->ud.un; i++) {
|
for (i = 0; i < afile->ud.un; i++) {
|
||||||
if(afile->ud.ulist[i] == labnr) return i;
|
if (afile->ud.ulist[i] == labnr)
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
if (afile->ud.un >= afile->ud.um) {
|
if (afile->ud.un >= afile->ud.um) {
|
||||||
afile->ud.um *= 1.5;
|
afile->ud.um *= 1.5;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
xa65 - 6502 cross assembler and utility suite
|
xa65 - 6502 cross assembler and utility suite
|
||||||
Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de)
|
Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,7 +17,6 @@
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
extern int u_label(int labnr);
|
extern int u_label(int labnr);
|
||||||
extern void u_write(FILE *fp);
|
extern void u_write(FILE *fp);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user