mirror of
https://github.com/fachat/xa65.git
synced 2024-06-26 08:29:29 +00:00
Compare commits
2 Commits
59a635ce37
...
f2dac69090
Author | SHA1 | Date | |
---|---|---|---|
|
f2dac69090 | ||
|
4eb72b1896 |
326
xa/misc/file65.c
326
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);
|
||||||
|
@ -103,15 +94,16 @@ void usage(FILE *fp)
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int i, j, n, mode, hlen;
|
int i, j, n, mode, hlen;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *aligntxt[4]= {"[align 1]","[align 2]","[align 4]","[align 256]"};
|
char *aligntxt[4] = { "[align 1]", "[align 2]", "[align 4]", "[align 256]" };
|
||||||
if(argc<=1) {
|
if (argc <= 1) {
|
||||||
usage(stderr);
|
usage(stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -121,105 +113,148 @@ int main(int argc, char *argv[]) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(i<argc) {
|
while (i < argc) {
|
||||||
if(argv[i][0]=='-') {
|
if (argv[i][0] == '-') {
|
||||||
/* process options */
|
/* process options */
|
||||||
switch(argv[i][1]) {
|
switch (argv[i][1]) {
|
||||||
case 'v':
|
case 'v':
|
||||||
j = 1;
|
j = 1;
|
||||||
while (argv[i][j] == 'v') {
|
while (argv[i][j] == 'v') {
|
||||||
verbose ++;
|
verbose++;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
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 {
|
||||||
fp = fopen(argv[i],"rb");
|
fp = fopen(argv[i], "rb");
|
||||||
if(fp) {
|
if (fp) {
|
||||||
n = fread(hdr, 1, 8, fp);
|
n = fread(hdr, 1, 8, fp);
|
||||||
if((n>=8) && (!memcmp(hdr, cmp, 5))) {
|
if ((n >= 8) && (!memcmp(hdr, cmp, 5))) {
|
||||||
mode=hdr[7]*256+hdr[6];
|
mode = hdr[7] * 256 + hdr[6];
|
||||||
if(!xapar && !rompar) {
|
if (!xapar && !rompar) {
|
||||||
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(
|
||||||
(mode & 0x1000)?"object":"executable",
|
"[%s][%sbit][%s relocation][CPU %s][CPU2 %s]%s\n",
|
||||||
(mode & 0x2000)?"32":"16",
|
(mode & 0x1000) ? "object" : "executable",
|
||||||
(mode & 0x4000)?"page":"byte",
|
(mode & 0x2000) ? "32" : "16",
|
||||||
(mode & 0x8000)?"65816":"6502",
|
(mode & 0x4000) ? "page" : "byte",
|
||||||
|
(mode & 0x8000) ? "65816" : "6502",
|
||||||
cpunames[(mode & FM_CPU2) >> 4],
|
cpunames[(mode & FM_CPU2) >> 4],
|
||||||
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]);
|
||||||
if(verbose) {
|
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) {
|
||||||
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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 {
|
||||||
fprintf(stderr,"file65: %s: %s\n", argv[i], strerror(errno));
|
fprintf(stderr, "file65: %s: %s\n", argv[i], strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -227,40 +262,32 @@ 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(otab[i].opt>=0) {
|
if (*buf == otab[i].opt)
|
||||||
|
break;
|
||||||
|
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;
|
||||||
} else {
|
} else {
|
||||||
printf("fopt: Unknown Type $%02x : ", (*buf & 0xff));
|
printf("fopt: Unknown Type $%02x : ", (*buf & 0xff));
|
||||||
}
|
}
|
||||||
if(strfl) {
|
if (strfl) {
|
||||||
buf[len]=0;
|
buf[len] = 0;
|
||||||
printf("%s\n", buf+1);
|
printf("%s\n", buf + 1);
|
||||||
} else {
|
} else {
|
||||||
for (i=1; i<len-1; i++) {
|
for (i = 1; i < len - 1; i++) {
|
||||||
printf("%02x ", buf[i] & 0xff);
|
printf("%02x ", buf[i] & 0xff);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -268,16 +295,18 @@ void print_option(unsigned char *buf, int len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_options(FILE *fp) {
|
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);
|
||||||
while(c && c!=EOF) {
|
l++;
|
||||||
c&=255;
|
while (c && c != EOF) {
|
||||||
d = fread(tb, 1, c-1, fp);
|
c &= 255;
|
||||||
if(labels) print_option(tb, c);
|
d = fread(tb, 1, c - 1, fp);
|
||||||
l+=c;
|
if (labels)
|
||||||
c=fgetc(fp);
|
print_option(tb, c);
|
||||||
|
l += c;
|
||||||
|
c = fgetc(fp);
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
@ -285,11 +314,12 @@ 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);
|
||||||
*/
|
*/
|
||||||
fseek(fp, offset, SEEK_CUR);
|
fseek(fp, offset, SEEK_CUR);
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
|
@ -300,15 +330,15 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
|
|
||||||
printf("Undefined Labels: %d\n", nud);
|
printf("Undefined Labels: %d\n", nud);
|
||||||
|
|
||||||
if(nud) {
|
if (nud) {
|
||||||
do {
|
do {
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
while(c && c!=EOF) {
|
while (c && c != EOF) {
|
||||||
fputc(c, stdout);
|
fputc(c, stdout);
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
}
|
}
|
||||||
printf("\t");
|
printf("\t");
|
||||||
} while(--nud);
|
} while (--nud);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,76 +346,78 @@ printf("print_labels:offset=%d\n",offset);
|
||||||
// skip relocation tables
|
// skip relocation tables
|
||||||
|
|
||||||
// two tables, one for text one for data
|
// two tables, one for text one for data
|
||||||
for(i=0;i<2;i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
unsigned char lowbyte;
|
unsigned char lowbyte;
|
||||||
unsigned short index;
|
unsigned short index;
|
||||||
unsigned short offset = 0;
|
unsigned short offset = 0;
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("Relocation table for %s:\n", i ? "text":"data");
|
printf("Relocation table for %s:\n", i ? "text" : "data");
|
||||||
}
|
}
|
||||||
|
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
while(c && c!=EOF) {
|
while (c && c != EOF) {
|
||||||
c&= 0xff;
|
c &= 0xff;
|
||||||
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)
|
||||||
c&= 0xff;
|
break;
|
||||||
|
c &= 0xff;
|
||||||
}
|
}
|
||||||
if(c==EOF) break;
|
if (c == EOF)
|
||||||
|
break;
|
||||||
offset += c;
|
offset += c;
|
||||||
|
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
if( (c & 0xe0) == 0x40 ) {
|
if ((c & 0xe0) == 0x40) {
|
||||||
lowbyte = fgetc(fp);
|
lowbyte = fgetc(fp);
|
||||||
}
|
}
|
||||||
if( (c & 0x07) == 0 ) {
|
if ((c & 0x07) == 0) {
|
||||||
index = fgetc(fp) & 0xff;
|
index = fgetc(fp) & 0xff;
|
||||||
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],
|
||||||
if ( (c & 0xe0) == 0x40) {
|
segments[c & 0x07], (c & 0x07));
|
||||||
|
if ((c & 0xe0) == 0x40) {
|
||||||
printf(", %02x", lowbyte);
|
printf(", %02x", lowbyte);
|
||||||
}
|
}
|
||||||
if ( (c & 0x07) == 0) {
|
if ((c & 0x07) == 0) {
|
||||||
printf(", %04x", index);
|
printf(", %04x", index);
|
||||||
}
|
}
|
||||||
printf(")");
|
printf(")");
|
||||||
}
|
}
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
}
|
}
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// print global labels
|
// print global labels
|
||||||
nud = (fgetc(fp) & 0xff);
|
nud = (fgetc(fp) & 0xff);
|
||||||
nud += ((fgetc(fp) << 8) & 0xff00);
|
nud += ((fgetc(fp) << 8) & 0xff00);
|
||||||
printf("Global Labels: %d\n", nud);
|
printf("Global Labels: %d\n", nud);
|
||||||
|
|
||||||
if(nud) {
|
if (nud) {
|
||||||
do {
|
do {
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
while(c && c!=EOF) {
|
while (c && c != EOF) {
|
||||||
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);
|
||||||
off+= ((fgetc(fp) << 8) & 0xff00);
|
off += ((fgetc(fp) << 8) & 0xff00);
|
||||||
printf(" (segID=%d (%s), offset=%04x)\n", seg, stab[seg&7], off);
|
printf(" (segID=%d (%s), offset=%04x)\n", seg, stab[seg & 7], off);
|
||||||
|
|
||||||
} while(--nud);
|
} while (--nud);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
617
xa/misc/ldo65.c
617
xa/misc/ldo65.c
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||||
unsigned char *reloc_globals(unsigned char *, file65 *fp);
|
file65 *fp, int undefwarn);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -141,53 +134,60 @@ int main(int argc, char *argv[]) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(i<argc) {
|
while (i < argc) {
|
||||||
arg = NULL;
|
arg = NULL;
|
||||||
if(argv[i][0]=='-') {
|
if (argv[i][0] == '-') {
|
||||||
/* process options */
|
/* process options */
|
||||||
switch(argv[i][1]) {
|
switch (argv[i][1]) {
|
||||||
case 'v':
|
case 'v':
|
||||||
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;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
base=NULL;
|
base = NULL;
|
||||||
switch(argv[i][2]) {
|
switch (argv[i][2]) {
|
||||||
case 't':
|
case 't':
|
||||||
tflag= 1;
|
tflag = 1;
|
||||||
base=&tbase;
|
base = &tbase;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
dflag= 1;
|
dflag = 1;
|
||||||
base=&dbase;
|
base = &dbase;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
bflag= 1;
|
bflag = 1;
|
||||||
base=&bbase;
|
base = &bbase;
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
zflag= 1;
|
zflag = 1;
|
||||||
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 */
|
||||||
switch(argv[i][2]) {
|
switch (argv[i][2]) {
|
||||||
case 't':
|
case 't':
|
||||||
extract = 1;
|
extract = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -196,21 +196,25 @@ 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;
|
||||||
}
|
}
|
||||||
for(j = 0; j < 16; j++) {
|
for (j = 0; j < 16; j++) {
|
||||||
if (cpunames[j] != NULL && !strcmp(arg, cpunames[j])) {
|
if (cpunames[j] != NULL && !strcmp(arg, cpunames[j])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -223,31 +227,35 @@ 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 {
|
||||||
struct stat fs;
|
struct stat fs;
|
||||||
file.fname=argv[i];
|
file.fname = argv[i];
|
||||||
stat(argv[i], &fs);
|
stat(argv[i], &fs);
|
||||||
file.fsize=fs.st_size;
|
file.fsize = fs.st_size;
|
||||||
file.buf=malloc(file.fsize);
|
file.buf = malloc(file.fsize);
|
||||||
if(!file.buf) {
|
if (!file.buf) {
|
||||||
fprintf(stderr,"Oops, no more memory!\n");
|
fprintf(stderr, "Oops, no more memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("reloc65: read file %s -> %s\n",argv[i],outfile);
|
printf("reloc65: read file %s -> %s\n", argv[i], outfile);
|
||||||
fp = fopen(argv[i],"rb");
|
fp = fopen(argv[i], "rb");
|
||||||
if(fp) {
|
if (fp) {
|
||||||
n = fread(file.buf, 1, file.fsize, fp);
|
n = fread(file.buf, 1, file.fsize, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
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
|
||||||
|
@ -263,54 +271,70 @@ int main(int argc, char *argv[]) {
|
||||||
file.buf[6] = mode & 0xff;
|
file.buf[6] = mode & 0xff;
|
||||||
file.buf[7] = (mode >> 8) & 0xff;
|
file.buf[7] = (mode >> 8) & 0xff;
|
||||||
|
|
||||||
hlen = BUF+read_options(file.buf+BUF);
|
hlen = BUF + read_options(file.buf + BUF);
|
||||||
|
|
||||||
file.tbase = file.buf[ 9]*256+file.buf[ 8];
|
file.tbase = file.buf[9] * 256 + file.buf[8];
|
||||||
file.tlen = file.buf[11]*256+file.buf[10];
|
file.tlen = file.buf[11] * 256 + file.buf[10];
|
||||||
file.tdiff = tflag ? tbase - file.tbase : 0;
|
file.tdiff = tflag ? tbase - file.tbase : 0;
|
||||||
|
|
||||||
file.dbase = file.buf[13]*256+file.buf[12];
|
file.dbase = file.buf[13] * 256 + file.buf[12];
|
||||||
file.dlen = file.buf[15]*256+file.buf[14];
|
file.dlen = file.buf[15] * 256 + file.buf[14];
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.bbase = file.buf[17]*256+file.buf[16];
|
file.bbase = file.buf[17] * 256 + file.buf[16];
|
||||||
file.blen = file.buf[19]*256+file.buf[18];
|
file.blen = file.buf[19] * 256 + file.buf[18];
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.zbase = file.buf[21]*256+file.buf[20];
|
file.zbase = file.buf[21] * 256 + file.buf[20];
|
||||||
file.zlen = file.buf[23]*256+file.buf[22];
|
file.zlen = file.buf[23] * 256 + file.buf[22];
|
||||||
file.zdiff = zflag ? zbase - file.zbase : 0;
|
file.zdiff = zflag ? zbase - file.zbase : 0;
|
||||||
|
|
||||||
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 */
|
||||||
|
@ -326,26 +350,26 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
reloc_globals(file.extab, &file);
|
reloc_globals(file.extab, &file);
|
||||||
|
|
||||||
if(tflag) {
|
if (tflag) {
|
||||||
file.buf[ 9]= (tbase>>8)&255;
|
file.buf[9] = (tbase >> 8) & 255;
|
||||||
file.buf[ 8]= tbase & 255;
|
file.buf[8] = tbase & 255;
|
||||||
}
|
}
|
||||||
if(dflag) {
|
if (dflag) {
|
||||||
file.buf[13]= (dbase>>8)&255;
|
file.buf[13] = (dbase >> 8) & 255;
|
||||||
file.buf[12]= dbase & 255;
|
file.buf[12] = dbase & 255;
|
||||||
}
|
}
|
||||||
if(bflag) {
|
if (bflag) {
|
||||||
file.buf[17]= (bbase>>8)&255;
|
file.buf[17] = (bbase >> 8) & 255;
|
||||||
file.buf[16]= bbase & 255;
|
file.buf[16] = bbase & 255;
|
||||||
}
|
}
|
||||||
if(zflag) {
|
if (zflag) {
|
||||||
file.buf[21]= (zbase>>8)&255;
|
file.buf[21] = (zbase >> 8) & 255;
|
||||||
file.buf[20]= zbase & 255;
|
file.buf[20] = zbase & 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(outfile, "wb");
|
fp = fopen(outfile, "wb");
|
||||||
if(fp) {
|
if (fp) {
|
||||||
switch(extract) {
|
switch (extract) {
|
||||||
case 0: /* whole file */
|
case 0: /* whole file */
|
||||||
fwrite(file.buf, 1, file.fsize, fp);
|
fwrite(file.buf, 1, file.fsize, fp);
|
||||||
break;
|
break;
|
||||||
|
@ -362,22 +386,27 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"reloc65: write '%s': %s\n",
|
fprintf(stderr, "reloc65: write '%s': %s\n",
|
||||||
outfile, strerror(errno));
|
outfile, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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,15 +414,14 @@ 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;
|
||||||
|
|
||||||
c=buf[0];
|
c = buf[0];
|
||||||
while(c && c!=EOF) {
|
while (c && c != EOF) {
|
||||||
c&=255;
|
c &= 255;
|
||||||
l+=c;
|
l += c;
|
||||||
c=buf[l];
|
c = buf[l];
|
||||||
}
|
}
|
||||||
return ++l;
|
return ++l;
|
||||||
}
|
}
|
||||||
|
@ -401,10 +429,10 @@ int read_options(unsigned char *buf) {
|
||||||
int read_undef(unsigned char *buf) {
|
int read_undef(unsigned char *buf) {
|
||||||
int n, l = 2;
|
int n, l = 2;
|
||||||
|
|
||||||
n = buf[0] + 256*buf[1];
|
n = buf[0] + 256 * buf[1];
|
||||||
while(n){
|
while (n) {
|
||||||
n--;
|
n--;
|
||||||
while(buf[l] != 0) {
|
while (buf[l] != 0) {
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
l++;
|
l++;
|
||||||
|
@ -414,14 +442,14 @@ int read_undef(unsigned char *buf) {
|
||||||
|
|
||||||
#define reldiff(s) (((s)==2)?fp->tdiff:(((s)==3)?fp->ddiff:(((s)==4)?fp->bdiff:(((s)==5)?fp->zdiff:0))))
|
#define reldiff(s) (((s)==2)?fp->tdiff:(((s)==3)?fp->ddiff:(((s)==4)?fp->bdiff:(((s)==5)?fp->zdiff:0))))
|
||||||
|
|
||||||
unsigned char *reloc_seg(unsigned char *buf, int len, unsigned char *rtab,
|
unsigned char* reloc_seg(unsigned char *buf, int len, unsigned char *rtab,
|
||||||
file65 *fp, int undefwarn) {
|
file65 *fp, int undefwarn) {
|
||||||
int adr = -1;
|
int adr = -1;
|
||||||
int type, seg, old, new;
|
int type, seg, old, new;
|
||||||
/*printf("tdiff=%04x, ddiff=%04x, bdiff=%04x, zdiff=%04x\n",
|
/*printf("tdiff=%04x, ddiff=%04x, bdiff=%04x, zdiff=%04x\n",
|
||||||
fp->tdiff, fp->ddiff, fp->bdiff, fp->zdiff);*/
|
fp->tdiff, fp->ddiff, fp->bdiff, fp->zdiff);*/
|
||||||
while(*rtab) {
|
while (*rtab) {
|
||||||
if((*rtab & 255) == 255) {
|
if ((*rtab & 255) == 255) {
|
||||||
adr += 254;
|
adr += 254;
|
||||||
rtab++;
|
rtab++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -429,19 +457,19 @@ unsigned char *reloc_seg(unsigned char *buf, int len, unsigned char *rtab,
|
||||||
rtab++;
|
rtab++;
|
||||||
type = *rtab & 0xe0;
|
type = *rtab & 0xe0;
|
||||||
seg = *rtab & 0x07;
|
seg = *rtab & 0x07;
|
||||||
/*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",rtab-1, *(rtab-1), adr, type, seg);*/
|
/*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",rtab-1, *(rtab-1), adr, type, seg);*/
|
||||||
rtab++;
|
rtab++;
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case 0x80: /* WORD - two byte address */
|
case 0x80: /* WORD - two byte address */
|
||||||
old = buf[adr] + 256*buf[adr+1];
|
old = buf[adr] + 256 * buf[adr + 1];
|
||||||
new = old + reldiff(seg);
|
new = old + reldiff(seg);
|
||||||
buf[adr] = new & 255;
|
buf[adr] = new & 255;
|
||||||
buf[adr+1] = (new>>8)&255;
|
buf[adr + 1] = (new >> 8) & 255;
|
||||||
break;
|
break;
|
||||||
case 0x40: /* HIGH - high byte of an address */
|
case 0x40: /* HIGH - high byte of an address */
|
||||||
old = buf[adr]*256 + *rtab;
|
old = buf[adr] * 256 + *rtab;
|
||||||
new = old + reldiff(seg);
|
new = old + reldiff(seg);
|
||||||
buf[adr] = (new>>8)&255;
|
buf[adr] = (new >> 8) & 255;
|
||||||
*rtab = new & 255;
|
*rtab = new & 255;
|
||||||
rtab++;
|
rtab++;
|
||||||
break;
|
break;
|
||||||
|
@ -451,39 +479,43 @@ unsigned char *reloc_seg(unsigned char *buf, int len, unsigned char *rtab,
|
||||||
buf[adr] = new & 255;
|
buf[adr] = new & 255;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
return ++rtab;
|
return ++rtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *reloc_globals(unsigned char *buf, file65 *fp) {
|
unsigned char* reloc_globals(unsigned char *buf, file65 *fp) {
|
||||||
int n, old, new, seg;
|
int n, old, new, seg;
|
||||||
|
|
||||||
n = buf[0] + 256*buf[1];
|
n = buf[0] + 256 * buf[1];
|
||||||
buf +=2;
|
buf += 2;
|
||||||
|
|
||||||
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);
|
||||||
/*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/
|
/*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/
|
||||||
buf[1] = new & 255;
|
buf[1] = new & 255;
|
||||||
buf[2] = (new>>8) & 255;
|
buf[2] = (new >> 8) & 255;
|
||||||
buf +=3;
|
buf += 3;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
|
|
176
xa/misc/uncpk.c
176
xa/misc/uncpk.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
|
||||||
* 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"
|
||||||
|
@ -52,13 +50,12 @@ void usage(FILE *fp)
|
||||||
programname);
|
programname);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
usage(stderr);
|
usage(stderr);
|
||||||
|
@ -75,133 +72,142 @@ int main(int argc, char *argv[])
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strchr(argv[1],(int)'l')) {
|
if (strchr(argv[1], (int) 'l')) {
|
||||||
list=1;
|
list = 1;
|
||||||
}
|
}
|
||||||
if(strchr(argv[1],(int)'v')) {
|
if (strchr(argv[1], (int) 'v')) {
|
||||||
verbose=1;
|
verbose = 1;
|
||||||
}
|
}
|
||||||
if(strchr(argv[1],(int)'a')) {
|
if (strchr(argv[1], (int) 'a')) {
|
||||||
add=1;
|
add = 1;
|
||||||
}
|
}
|
||||||
if(strchr(argv[1],(int)'c')) {
|
if (strchr(argv[1], (int) 'c')) {
|
||||||
create=1;
|
create = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(add||create) {
|
if (add || create) {
|
||||||
if (argc <= 3) {
|
if (argc <= 3) {
|
||||||
usage(stderr);
|
usage(stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
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)
|
||||||
for(i=3;i<argc;i++) {
|
fputc(1, fpo); /* Version Byte */
|
||||||
if(verbose) printf("%s\n",argv[i]);
|
for (i = 3; i < argc; i++) {
|
||||||
fp=fopen(argv[i],"rb");
|
if (verbose)
|
||||||
if(fp) {
|
printf("%s\n", argv[i]);
|
||||||
while((s=strchr(argv[i],':'))) *s='/';
|
fp = fopen(argv[i], "rb");
|
||||||
fprintf(fpo,"%s",argv[i]);
|
if (fp) {
|
||||||
fputc(0,fpo);
|
while ((s = strchr(argv[i], ':')))
|
||||||
c=fgetc(fp);
|
*s = '/';
|
||||||
while(c!=EOF) {
|
fprintf(fpo, "%s", argv[i]);
|
||||||
n=1;
|
fputc(0, fpo);
|
||||||
while((c2=fgetc(fp))==c) {
|
c = fgetc(fp);
|
||||||
|
while (c != EOF) {
|
||||||
|
n = 1;
|
||||||
|
while ((c2 = fgetc(fp)) == c) {
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
while(n) {
|
while (n) {
|
||||||
if(n>=4 || c==0xf7) {
|
if (n >= 4 || c == 0xf7) {
|
||||||
n2=min(255,n);
|
n2 = min(255, n);
|
||||||
fprintf(fpo,"\xf7%c%c",(char)n2,(char)c);
|
fprintf(fpo, "\xf7%c%c", (char) n2, (char) c);
|
||||||
n-=n2;
|
n -= n2;
|
||||||
} else {
|
} else {
|
||||||
fputc(c,fpo);
|
fputc(c, fpo);
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"Couldn't open file '%s' for writing!",argv[1]);
|
fprintf(stderr, "Couldn't open file '%s' for writing!", argv[1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
usage(stderr);
|
usage(stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fp=fopen(argv[2],"rb");
|
fp = fopen(argv[2], "rb");
|
||||||
if(fp){
|
if (fp) {
|
||||||
if(fgetc(fp)==1){
|
if (fgetc(fp) == 1) {
|
||||||
do{
|
do {
|
||||||
/* read name */
|
/* read name */
|
||||||
i=0;
|
i = 0;
|
||||||
while((c=fgetc(fp))){
|
while ((c = fgetc(fp))) {
|
||||||
if(c==EOF) break;
|
if (c == EOF)
|
||||||
name[i++]=c;
|
break;
|
||||||
|
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;
|
||||||
while((c=fgetc(fp))!=EOF){
|
while ((c = fgetc(fp)) != EOF) {
|
||||||
/* test if 'compressed' */
|
/* test if 'compressed' */
|
||||||
if(c==0xf7){
|
if (c == 0xf7) {
|
||||||
nc=fgetc(fp);
|
nc = fgetc(fp);
|
||||||
if(!nc) {
|
if (!nc) {
|
||||||
fileok=1;
|
fileok = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c=fgetc(fp);
|
c = fgetc(fp);
|
||||||
if(fpo) { /* extract */
|
if (fpo) { /* extract */
|
||||||
if(nc!=EOF && c!=EOF) {
|
if (nc != EOF && c != EOF) {
|
||||||
nc &= 255;
|
nc &= 255;
|
||||||
while(nc--) {
|
while (nc--) {
|
||||||
fputc(c,fpo);
|
fputc(c, fpo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(fpo) {
|
if (fpo) {
|
||||||
fputc(c,fpo);
|
fputc(c, fpo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(fpo) {
|
if (fpo) {
|
||||||
fclose(fpo);
|
fclose(fpo);
|
||||||
fpo=NULL;
|
fpo = NULL;
|
||||||
}
|
}
|
||||||
if(!fileok) {
|
if (!fileok) {
|
||||||
fprintf(stderr,"Unexpected end of file!\n");
|
fprintf(stderr, "Unexpected end of file!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(c!=EOF);
|
} while (c != EOF);
|
||||||
} else
|
} else
|
||||||
fprintf(stderr,"Wrong Version!\n");
|
fprintf(stderr, "Wrong Version!\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"File %s not found!\n",argv[1]);
|
fprintf(stderr, "File %s not found!\n", argv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return (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__ */
|
||||||
|
|
861
xa/src/xa.c
861
xa/src/xa.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
|
||||||
|
@ -41,7 +41,7 @@ extern int dlen, dbase;
|
||||||
extern int zlen, zbase;
|
extern int zlen, zbase;
|
||||||
extern int romable, romaddr;
|
extern int romable, romaddr;
|
||||||
|
|
||||||
extern int memode,xmode;
|
extern int memode, xmode;
|
||||||
extern int segment;
|
extern int segment;
|
||||||
extern int pc[SEG_MAX];
|
extern int pc[SEG_MAX];
|
||||||
|
|
||||||
|
|
268
xa/src/xaa.c
268
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,83 +30,79 @@
|
||||||
#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_EQU,P_CMP,P_CMP,P_EQU,P_AND,P_XOR,P_OR,
|
P_CMP,
|
||||||
P_LAND,P_LOR,P_EQU,P_START };
|
P_CMP, P_EQU, P_CMP, P_CMP, P_EQU, P_AND, P_XOR, P_OR,
|
||||||
|
P_LAND, P_LOR, P_EQU, P_START };
|
||||||
|
|
||||||
static int pp,pcc;
|
static int pp, pcc;
|
||||||
static int fundef;
|
static int fundef;
|
||||||
|
|
||||||
static int ag_term(signed char*,int,int*,int*,int*);
|
static int ag_term(signed char*, int, int*, int*, int*);
|
||||||
static int get_op(signed char*,int*);
|
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;
|
||||||
|
|
||||||
*pfl = 0;
|
*pfl = 0;
|
||||||
fundef = f;
|
fundef = 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);
|
||||||
if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_LOW>>8)) ) {
|
if (bfl && (bfl != (A_ADR >> 8)) && (bfl != (A_LOW >> 8))) {
|
||||||
/*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);
|
||||||
if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_HIGH>>8)) ) {
|
if (bfl && (bfl != (A_ADR >> 8)) && (bfl != (A_HIGH >> 8))) {
|
||||||
/*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)
|
||||||
*v=(*v>>8)&255;
|
*pfl = A_HIGH | ((afl << 8) & A_FMASK) | (*v & 255);
|
||||||
}
|
*v = (*v >> 8) & 255;
|
||||||
else
|
} else if (s[pp] != T_END) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
*l=pp;
|
*l = pp;
|
||||||
//fprintf(stderr, "a_term: nolink=%d, noundef=%d ->er=%d; l=%d, pp=%d, afl->%04x *pfl=%04x, (pc=%04x)\n",nolink, noundef ,er, *l, pp, afl,*pfl, xpc);
|
//fprintf(stderr, "a_term: nolink=%d, noundef=%d ->er=%d; l=%d, pp=%d, afl->%04x *pfl=%04x, (pc=%04x)\n",nolink, noundef ,er, *l, pp, afl,*pfl, xpc);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if(0) /* NYI: this is hacked into .assert for now */
|
#if(0) /* NYI: this is hacked into .assert for now */
|
||||||
|
@ -123,198 +119,180 @@ 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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
|
printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
|
||||||
er, segment, afl, nolink, fundef);
|
er, segment, afl, nolink, fundef);
|
||||||
*/
|
*/
|
||||||
if(er==E_NODEF && segment != SEG_ABS && fundef ) {
|
if (er == E_NODEF && segment != SEG_ABS && fundef) {
|
||||||
if( nolink || ((afl==SEG_UNDEF) || (afl==SEG_UNDEFZP))) {
|
if (nolink || ((afl == SEG_UNDEF) || (afl == SEG_UNDEFZP))) {
|
||||||
er = E_OK;
|
er = E_OK;
|
||||||
*v = 0;
|
*v = 0;
|
||||||
if(afl!=SEG_UNDEFZP) {
|
if (afl != SEG_UNDEFZP) {
|
||||||
afl = SEG_UNDEF;
|
afl = SEG_UNDEF;
|
||||||
}
|
}
|
||||||
*label = cval(s+pp+1);
|
*label = cval(s + pp + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
*v=lval(s+pp+1);
|
*v = lval(s + pp + 1);
|
||||||
pp+=5;
|
pp += 5;
|
||||||
/*
|
/*
|
||||||
printf("value: v=%04x\n",*v);
|
printf("value: v=%04x\n",*v);
|
||||||
*/
|
*/
|
||||||
}
|
} else if (s[pp] == T_POINTER) {
|
||||||
else
|
afl = s[pp + 1];
|
||||||
if(s[pp]==T_POINTER)
|
*v = cval(s + pp + 2);
|
||||||
{
|
pp += 6;
|
||||||
afl = s[pp+1];
|
/*
|
||||||
*v=cval(s+pp+2);
|
printf("pointer: v=%04x, afl=%04x\n",*v,afl);
|
||||||
pp+=6;
|
*/
|
||||||
/*
|
} else if (s[pp] == '*') {
|
||||||
printf("pointer: v=%04x, afl=%04x\n",*v,afl);
|
*v = pcc;
|
||||||
*/
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(s[pp]=='*')
|
|
||||||
{
|
|
||||||
*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) && (afl != SEG_UNDEFZP)
|
||||||
if(afl || *nafl) { /* check pointer arithmetic */
|
&& (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 if ((afl && !*nafl) && o == 2) {
|
||||||
} else
|
afl = (afl | *nafl); /* subtract constant from pointer */
|
||||||
if((afl && !*nafl) && o==2) {
|
|
||||||
afl=(afl | *nafl); /* subtract constant from pointer */
|
|
||||||
} else {
|
} else {
|
||||||
if((!afl && *nafl) && o==2) {
|
if ((!afl && *nafl) && o == 2) {
|
||||||
/* subtract pointer from constant */
|
/* subtract pointer from constant */
|
||||||
errout(W_SUBTRACT);
|
errout(W_SUBTRACT);
|
||||||
}
|
}
|
||||||
/* allow math in the same segment */
|
/* allow math in the same segment */
|
||||||
if(segment!=SEG_ABS && segment != afl) {
|
if (segment != SEG_ABS && segment != afl) {
|
||||||
if(!dsb_len) {
|
if (!dsb_len) {
|
||||||
/*printf("ILLPOINTER=dsb_len=%d,segment=%d\n",dsb_len, segment);*/
|
/*printf("ILLPOINTER=dsb_len=%d,segment=%d\n",dsb_len, segment);*/
|
||||||
/* e.g. adding two pointers, adding two undefined values */
|
/* e.g. adding two pointers, adding two undefined values */
|
||||||
er=E_ILLSEGMENT;
|
er = E_ILLSEGMENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
afl=0;
|
afl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!er) er=do_op(v,w,o);
|
if (!er)
|
||||||
|
er = do_op(v, w, o);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*nafl = afl;
|
*nafl = 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];
|
||||||
|
|
||||||
if(*o<1 || *o>17) {
|
if (*o < 1 || *o > 17) {
|
||||||
/*
|
/*
|
||||||
printf("*o=%d, pp=%d, s=%s\n", *o, pp, s);
|
printf("*o=%d, pp=%d, s=%s\n", *o, pp, s);
|
||||||
for (int i=0; i< 10; i++) {
|
for (int i=0; i< 10; i++) {
|
||||||
printf(" %02x", s[i]);
|
printf(" %02x", s[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
*/
|
*/
|
||||||
er=E_SYNTAX;
|
er = E_SYNTAX;
|
||||||
} else {
|
} else {
|
||||||
er=E_OK;
|
er = E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
||||||
*w +=w2;
|
*w += w2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
*w -=w2;
|
*w -= w2;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
*w *=w2;
|
*w *= w2;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (w2!=0)
|
if (w2 != 0)
|
||||||
*w /=w2;
|
*w /= w2;
|
||||||
else
|
else
|
||||||
er =E_DIV;
|
er = E_DIV;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
*w >>=w2;
|
*w >>= w2;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
*w <<=w2;
|
*w <<= w2;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
*w = *w<w2;
|
*w = *w < w2;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
*w = *w>w2;
|
*w = *w > w2;
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
*w = *w==w2;
|
*w = *w == w2;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
*w = *w<=w2;
|
*w = *w <= w2;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
*w = *w>=w2;
|
*w = *w >= w2;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
*w = *w!=w2;
|
*w = *w != w2;
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
*w &=w2;
|
*w &= w2;
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
*w ^=w2;
|
*w ^= w2;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
*w |=w2;
|
*w |= w2;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
*w =*w&&w2;
|
*w = *w && w2;
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 17:
|
||||||
*w =*w||w2;
|
*w = *w || w2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return(er);
|
return (er);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
@ -58,11 +57,11 @@ static signed char convert_char_petscii(signed char c) {
|
||||||
static signed char convert_char_petscreen(signed char c) {
|
static signed char convert_char_petscreen(signed char c) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = (int)convert_char_petscii(c);
|
i = (int) convert_char_petscii(c);
|
||||||
#ifdef SIGH
|
#ifdef SIGH
|
||||||
fprintf(stderr, "input: %i output: %i\n", c, i);
|
fprintf(stderr, "input: %i output: %i\n", c, i);
|
||||||
#endif
|
#endif
|
||||||
if (i< 0)
|
if (i < 0)
|
||||||
i += 0x80;
|
i += 0x80;
|
||||||
i ^= 0xe0;
|
i ^= 0xe0;
|
||||||
#ifdef SIGH
|
#ifdef SIGH
|
||||||
|
@ -74,19 +73,19 @@ fprintf(stderr, "(1)input: %i output: %i\n", c, i);
|
||||||
fprintf(stderr, "(2)input: %i output: %i\n", c, i);
|
fprintf(stderr, "(2)input: %i output: %i\n", c, i);
|
||||||
#endif
|
#endif
|
||||||
if (i < 0x80)
|
if (i < 0x80)
|
||||||
return (signed char)i;
|
return (signed char) i;
|
||||||
i += 0x40;
|
i += 0x40;
|
||||||
i &= 0xff;
|
i &= 0xff;
|
||||||
#ifdef SIGH
|
#ifdef SIGH
|
||||||
fprintf(stderr, "(3)input: %i output: %i\n", c, i);
|
fprintf(stderr, "(3)input: %i output: %i\n", c, i);
|
||||||
#endif
|
#endif
|
||||||
if (i < 0x80)
|
if (i < 0x80)
|
||||||
return (signed char)i;
|
return (signed char) i;
|
||||||
i ^= 0xa0;
|
i ^= 0xa0;
|
||||||
#ifdef SIGH
|
#ifdef SIGH
|
||||||
fprintf(stderr, "(4)input: %i output: %i\n", c, i);
|
fprintf(stderr, "(4)input: %i output: %i\n", c, i);
|
||||||
#endif
|
#endif
|
||||||
return (signed char)i;
|
return (signed char) i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static signed char convert_char_high(signed char c) {
|
static signed char convert_char_high(signed char c) {
|
||||||
|
@ -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
|
||||||
|
|
14
xa/src/xah.h
14
xa/src/xah.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)
|
||||||
* 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))
|
||||||
|
@ -91,9 +87,9 @@ typedef struct {
|
||||||
#define DIRCHAR '/'
|
#define DIRCHAR '/'
|
||||||
#define DIRCSTRING "/"
|
#define DIRCSTRING "/"
|
||||||
/* for Atari:
|
/* for Atari:
|
||||||
#define DIRCHAR '\\'
|
#define DIRCHAR '\\'
|
||||||
#define DIRCSTRING "\\"
|
#define DIRCSTRING "\\"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BUFSIZE 4096 /* File-Puffegroesse (wg Festplatte) */
|
#define BUFSIZE 4096 /* File-Puffegroesse (wg Festplatte) */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
615
xa/src/xal.c
615
xa/src/xal.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
|
||||||
|
@ -27,18 +27,17 @@
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
long gm_labm(void);
|
long gm_labm(void);
|
||||||
long ga_labm(void);
|
long ga_labm(void);
|
||||||
|
|
||||||
int lg_set(char *);
|
int lg_set(char*);
|
||||||
int lg_import(int);
|
int lg_import(int);
|
||||||
int lg_importzp(int);
|
int lg_importzp(int);
|
||||||
// used to re-define undef'd labels as global for -U option
|
// used to re-define undef'd labels as global for -U option
|
||||||
int lg_toglobal(char *);
|
int lg_toglobal(char*);
|
||||||
|
|
||||||
int b_init(void);
|
int b_init(void);
|
||||||
int b_depth(void);
|
int b_depth(void);
|
||||||
|
@ -46,7 +45,7 @@ int b_depth(void);
|
||||||
void printllist(FILE *fp);
|
void printllist(FILE *fp);
|
||||||
int ga_blk(void);
|
int ga_blk(void);
|
||||||
|
|
||||||
int l_def(char *s, int* l, int *x, int *f);
|
int l_def(char *s, int *l, int *x, int *f);
|
||||||
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);
|
||||||
void l_set(int n, int v, int afl);
|
void l_set(int n, int v, int afl);
|
||||||
char* l_get_name(int n, xalabel_t *is_cll);
|
char* l_get_name(int n, xalabel_t *is_cll);
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -66,19 +65,19 @@ typedef struct {
|
||||||
void (*start_listing)(char *name);
|
void (*start_listing)(char *name);
|
||||||
void (*start_line)();
|
void (*start_line)();
|
||||||
int (*set_anchor)(char *buf, char *name); // returns number of bytes added to buf
|
int (*set_anchor)(char *buf, char *name); // returns number of bytes added to buf
|
||||||
int (*start_label)(char *buf, char *name); // returns number of bytes added to buf
|
int (*start_label)(char *buf, char *name);// returns number of bytes added to buf
|
||||||
int (*end_label)(char *buf);
|
int (*end_label)(char *buf);
|
||||||
void (*end_line)();
|
void (*end_line)();
|
||||||
void (*end_listing)();
|
void (*end_listing)();
|
||||||
char* (*escape)(char *toescape); // returns pointer to static buffer, valid until next call
|
char* (*escape)(char *toescape);// returns pointer to static buffer, valid until next call
|
||||||
char* (*escape_char)(char toescape); // returns pointer to static buffer, valid until next call
|
char* (*escape_char)(char toescape);// returns pointer to static buffer, valid until next call
|
||||||
} formatter_t;
|
} formatter_t;
|
||||||
|
|
||||||
static char *def_escape(char *toescape) {
|
static char* def_escape(char *toescape) {
|
||||||
return toescape;
|
return toescape;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *def_escape_char(char toescape) {
|
static char* def_escape_char(char toescape) {
|
||||||
static char buf[2];
|
static char buf[2];
|
||||||
buf[0] = toescape;
|
buf[0] = toescape;
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
|
@ -86,10 +85,8 @@ 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
|
||||||
|
@ -116,7 +113,7 @@ static void html_end_listing() {
|
||||||
fprintf(listfp, "</pre></body></html>\n");
|
fprintf(listfp, "</pre></body></html>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *html_escape(char *toescape) {
|
static char* html_escape(char *toescape) {
|
||||||
static char buf[MAXLINE];
|
static char buf[MAXLINE];
|
||||||
|
|
||||||
char *p = toescape;
|
char *p = toescape;
|
||||||
|
@ -125,17 +122,15 @@ static char *html_escape(char *toescape) {
|
||||||
while (*p != 0) {
|
while (*p != 0) {
|
||||||
if (*p == '<') {
|
if (*p == '<') {
|
||||||
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++;
|
||||||
} else {
|
} else {
|
||||||
*q = *p;
|
*q = *p;
|
||||||
|
@ -147,7 +142,7 @@ static char *html_escape(char *toescape) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *html_escape_char(char toescape) {
|
static char* html_escape_char(char toescape) {
|
||||||
static char buf[2];
|
static char buf[2];
|
||||||
|
|
||||||
buf[0] = toescape;
|
buf[0] = toescape;
|
||||||
|
@ -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;
|
||||||
|
@ -226,7 +217,7 @@ void list_setfile(FILE *fp) {
|
||||||
listfp = fp;
|
listfp = fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *list_preamble(char *buf, int lineno, int seg, int pc) {
|
char* list_preamble(char *buf, int lineno, int seg, int pc) {
|
||||||
int i;
|
int i;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
|
@ -238,13 +229,25 @@ 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,25 +265,27 @@ 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];
|
||||||
char *buf = outline;
|
char *buf = outline;
|
||||||
|
|
||||||
int lst_seg = listing[0];
|
int lst_seg = listing[0];
|
||||||
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) {
|
||||||
/* yes */
|
/* yes */
|
||||||
/*fprintf(listfp, "line=%d, last=%d\n", list_lineno, list_last_lineno);*/
|
/*fprintf(listfp, "line=%d, last=%d\n", list_lineno, list_last_lineno);*/
|
||||||
fprintf(listfp, "\n");
|
fprintf(listfp, "\n");
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -306,18 +311,20 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||||
/* binary output (up to 8 byte. If more than 8 byte, print 7 plus "..." */
|
/* binary output (up to 8 byte. If more than 8 byte, print 7 plus "..." */
|
||||||
n_hexb = bincode_len;
|
n_hexb = bincode_len;
|
||||||
if (list_numbytes != 0 && n_hexb >= list_numbytes) {
|
if (list_numbytes != 0 && n_hexb >= list_numbytes) {
|
||||||
n_hexb = list_numbytes-1;
|
n_hexb = list_numbytes - 1;
|
||||||
overflow = 1;
|
overflow = 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < n_hexb; i++) {
|
for (i = 0; i < n_hexb; i++) {
|
||||||
buf = buf + list_byte(buf, bincode[i]);
|
buf = buf + list_byte(buf, bincode[i]);
|
||||||
buf = buf + list_sp(buf);
|
buf = buf + list_sp(buf);
|
||||||
if ( (i%16) == 15) {
|
if ((i % 16) == 15) {
|
||||||
// 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,43 +396,43 @@ 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;
|
||||||
|
|
||||||
tabval = 0;
|
tabval = 0;
|
||||||
if (tmp == (T_DEFINE & 255)) {
|
if (tmp == (T_DEFINE & 255)) {
|
||||||
while (inp < len && tmp == (T_DEFINE & 255)) {
|
while (inp < len && tmp == (T_DEFINE & 255)) {
|
||||||
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255);
|
||||||
/*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/
|
/*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/
|
||||||
name=l_get_name(tmp, &is_cll);
|
name = l_get_name(tmp, &is_cll);
|
||||||
|
|
||||||
// duplicate anchor names?
|
// duplicate anchor names?
|
||||||
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 == 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) {
|
||||||
tmp = list_string(buf+outp, name);
|
tmp = list_string(buf + outp, name);
|
||||||
tabval += tmp + 1 + is_cll;
|
tabval += tmp + 1 + is_cll;
|
||||||
outp += tmp;
|
outp += tmp;
|
||||||
}
|
}
|
||||||
outp += list_char(buf+outp, ' ');
|
outp += list_char(buf + outp, ' ');
|
||||||
inp += 3;
|
inp += 3;
|
||||||
tmp = input[inp] & 255;
|
tmp = input[inp] & 255;
|
||||||
}
|
}
|
||||||
if (tabval < 10) {
|
if (tabval < 10) {
|
||||||
outp += list_nchar(buf+outp, ' ', 10-tabval);
|
outp += list_nchar(buf + outp, ' ', 10 - tabval);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (tmp >= 0 && tmp < number_of_valid_tokens) {
|
if (tmp >= 0 && tmp < number_of_valid_tokens) {
|
||||||
outp += list_string(buf+outp, " ");
|
outp += list_string(buf + outp, " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +440,7 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
/* assembler keyword */
|
/* assembler keyword */
|
||||||
/*printf("tmp=%d, kt[tmp]=%p\n", tmp, kt[tmp]);*/
|
/*printf("tmp=%d, kt[tmp]=%p\n", tmp, kt[tmp]);*/
|
||||||
if (kt[tmp] != NULL) {
|
if (kt[tmp] != NULL) {
|
||||||
outp += list_string(buf+outp, kt[tmp]);
|
outp += list_string(buf + outp, kt[tmp]);
|
||||||
}
|
}
|
||||||
outp += list_sp(buf + outp);
|
outp += list_sp(buf + outp);
|
||||||
inp += 1;
|
inp += 1;
|
||||||
|
@ -453,58 +463,63 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
operator = 0;
|
operator = 0;
|
||||||
while (inp < len) {
|
while (inp < 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,
|
||||||
inp+=2;
|
formatp->escape_char(input[inp + 1]));
|
||||||
|
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)
|
||||||
format = input[inp+4];
|
| (input[inp + 1] & 255);
|
||||||
outp += list_value(buf+outp, tmp, format);
|
format = input[inp + 4];
|
||||||
|
outp += list_value(buf + outp, tmp, format);
|
||||||
inp += 5;
|
inp += 5;
|
||||||
operator = 1; /* check if arithmetic operator follows */
|
operator = 1; /* check if arithmetic operator follows */
|
||||||
break;
|
break;
|
||||||
case T_LABEL:
|
case T_LABEL:
|
||||||
/*outp += list_char(buf+outp, 'L');*/
|
/*outp += list_char(buf+outp, 'L');*/
|
||||||
/* 16 bit label number */
|
/* 16 bit label number */
|
||||||
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255);
|
||||||
name=l_get_name(tmp, &is_cll);
|
name = l_get_name(tmp, &is_cll);
|
||||||
|
|
||||||
// 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 */
|
||||||
break;
|
break;
|
||||||
case T_OP:
|
case T_OP:
|
||||||
/* label arithmetic operation; inp[3] is operation like '=' or '+' */
|
/* label arithmetic operation; inp[3] is operation like '=' or '+' */
|
||||||
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255);
|
||||||
name=l_get_name(tmp, &is_cll);
|
name = l_get_name(tmp, &is_cll);
|
||||||
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_string(buf+outp, name);
|
outp += list_char(buf + outp, '@');
|
||||||
outp += list_char(buf+outp, input[inp+3]);
|
outp += list_string(buf + outp, name);
|
||||||
|
outp += list_char(buf + outp, input[inp + 3]);
|
||||||
inp += 4;
|
inp += 4;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -516,11 +531,11 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
break;
|
break;
|
||||||
case T_COMMENT:
|
case T_COMMENT:
|
||||||
if (inp > 0 && inp < 20) {
|
if (inp > 0 && inp < 20) {
|
||||||
outp += list_nchar(buf+outp, ' ', 20-inp);
|
outp += list_nchar(buf + outp, ' ', 20 - inp);
|
||||||
}
|
}
|
||||||
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255);
|
||||||
outp += list_char(buf+outp, ';');
|
outp += list_char(buf + outp, ';');
|
||||||
outp += list_string(buf+outp, (char*)input+inp+3);
|
outp += list_string(buf + outp, (char*) input + inp + 3);
|
||||||
inp += tmp + 3;
|
inp += tmp + 3;
|
||||||
break;
|
break;
|
||||||
case T_LINE:
|
case T_LINE:
|
||||||
|
@ -530,15 +545,18 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
/* what is this? It's actually resolved during token conversion */
|
/* what is this? It's actually resolved during token conversion */
|
||||||
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_string(buf+outp, name);
|
outp += list_char(buf + outp, '@');
|
||||||
|
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, '#');
|
||||||
|
@ -553,30 +571,31 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
|
|
||||||
// string display
|
// string display
|
||||||
inp++;
|
inp++;
|
||||||
outp += list_char(buf+outp, '"');
|
outp += list_char(buf + outp, '"');
|
||||||
len = input[inp] & 0xff;
|
len = input[inp] & 0xff;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
inp++;
|
inp++;
|
||||||
outp += list_char(buf+outp, input[inp]);
|
outp += list_char(buf + outp, input[inp]);
|
||||||
}
|
}
|
||||||
inp++;
|
inp++;
|
||||||
outp += list_char(buf+outp, '"');
|
outp += list_char(buf + outp, '"');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '*': {
|
case '*': {
|
||||||
// If '*' appears as operand, it is the PC. We need to switch to operator then
|
// If '*' appears as operand, it is the PC. We need to switch to operator then
|
||||||
inp++;
|
inp++;
|
||||||
outp += list_char(buf+outp, '*');
|
outp += list_char(buf + outp, '*');
|
||||||
operator = 1;
|
operator = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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]);
|
||||||
}
|
}
|
||||||
inp += 1;
|
inp += 1;
|
||||||
break;
|
break;
|
||||||
|
@ -585,7 +604,7 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||||
if (operator && inp < len) {
|
if (operator && inp < len) {
|
||||||
signed char op = input[inp];
|
signed char op = input[inp];
|
||||||
if (op > 0 && op <= 20) { // sizeof(arith_ops)
|
if (op > 0 && op <= 20) { // sizeof(arith_ops)
|
||||||
outp += list_string(buf+outp, formatp->escape(arith_ops[op]));
|
outp += list_string(buf + outp, formatp->escape(arith_ops[op]));
|
||||||
inp += 1;
|
inp += 1;
|
||||||
operator = 0;
|
operator = 0;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -621,54 +639,51 @@ int list_value(char *buf, int val, signed char format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case '$':
|
case '$':
|
||||||
p += list_char(buf + p, '$');
|
p += list_char(buf + p, '$');
|
||||||
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);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
p += list_char(buf + p, '%');
|
p += list_char(buf + p, '%');
|
||||||
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, '%');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
snprintf(valbuf, 32, "%o",val);
|
snprintf(valbuf, 32, "%o", val);
|
||||||
p+= list_char(buf+p, '&');
|
p += list_char(buf + p, '&');
|
||||||
p+= list_string(buf+p, valbuf);
|
p += list_string(buf + p, valbuf);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
snprintf(valbuf, 32, "%d",val);
|
snprintf(valbuf, 32, "%d", val);
|
||||||
p+= list_string(buf+p, valbuf);
|
p += list_string(buf + p, valbuf);
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
case '"':
|
case '"':
|
||||||
p+= list_char(buf+p, format);
|
p += list_char(buf + p, format);
|
||||||
p+= list_char(buf+p, val);
|
p += list_char(buf + p, val);
|
||||||
p+= list_char(buf+p, format);
|
p += list_char(buf + p, format);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* hex format as fallback */
|
/* hex format as fallback */
|
||||||
p += list_char(buf + p, '$');
|
p += list_char(buf + p, '$');
|
||||||
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);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +693,7 @@ int list_value(char *buf, int val, signed char format) {
|
||||||
int list_nchar(char *buf, signed char c, int n) {
|
int list_nchar(char *buf, signed char c, int n) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
buf[i]=c;
|
buf[i] = c;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -699,8 +714,8 @@ int list_word(char *buf, int outword) {
|
||||||
|
|
||||||
int list_word_f(char *buf, int outword, signed char format) {
|
int list_word_f(char *buf, int outword, signed char format) {
|
||||||
int p = 0;
|
int p = 0;
|
||||||
p+= list_byte_f(buf+p, outword >> 8, format);
|
p += list_byte_f(buf + p, outword >> 8, format);
|
||||||
p+= list_byte_f(buf+p, outword, format);
|
p += list_byte_f(buf + p, outword, format);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,35 +725,35 @@ int list_byte(char *buf, int outbyte) {
|
||||||
|
|
||||||
int list_byte_f(char *buf, int outbyte, signed char format) {
|
int list_byte_f(char *buf, int outbyte, signed char format) {
|
||||||
int p = 0;
|
int p = 0;
|
||||||
p+= list_nibble_f(buf+p, (outbyte >> 4), format);
|
p += list_nibble_f(buf + p, (outbyte >> 4), format);
|
||||||
p+= list_nibble_f(buf+p, outbyte, format);
|
p += list_nibble_f(buf + p, outbyte, format);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_nibble_f(char *buf, int outnib, signed char format) {
|
int list_nibble_f(char *buf, int outnib, signed char format) {
|
||||||
int p = 0;
|
int p = 0;
|
||||||
outnib = outnib & 0xf;
|
outnib = outnib & 0xf;
|
||||||
switch(format) {
|
switch (format) {
|
||||||
case '$':
|
case '$':
|
||||||
if (outnib < 10) {
|
if (outnib < 10) {
|
||||||
buf[p]='0'+outnib;
|
buf[p] = '0' + outnib;
|
||||||
} else {
|
} else {
|
||||||
buf[p]='a'-10+outnib;
|
buf[p] = 'a' - 10 + outnib;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
buf[p++] = (outnib&8)?'1':'0';
|
buf[p++] = (outnib & 8) ? '1' : '0';
|
||||||
buf[p++] = (outnib&4)?'1':'0';
|
buf[p++] = (outnib & 4) ? '1' : '0';
|
||||||
buf[p++] = (outnib&2)?'1':'0';
|
buf[p++] = (outnib & 2) ? '1' : '0';
|
||||||
buf[p++] = (outnib&1)?'1':'0';
|
buf[p++] = (outnib & 1) ? '1' : '0';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* hex as default */
|
/* hex as default */
|
||||||
if (outnib < 10) {
|
if (outnib < 10) {
|
||||||
buf[p]='0'+outnib;
|
buf[p] = '0' + outnib;
|
||||||
} else {
|
} else {
|
||||||
buf[p]='a'-10+outnib;
|
buf[p] = 'a' - 10 + outnib;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
|
@ -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__ */
|
||||||
|
|
126
xa/src/xam.c
126
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
|
||||||
*
|
*
|
||||||
|
@ -30,102 +30,96 @@ static char **nip = NULL;
|
||||||
|
|
||||||
void reg_include(char *path) {
|
void reg_include(char *path) {
|
||||||
char **nip2;
|
char **nip2;
|
||||||
if(path && *path) {
|
if (path && *path) {
|
||||||
nip2 = realloc(nip,sizeof(char*)*(ninc+1));
|
nip2 = realloc(nip, sizeof(char*) * (ninc + 1));
|
||||||
if(nip2) {
|
if (nip2) {
|
||||||
nip = nip2;
|
nip = nip2;
|
||||||
nip[ninc++] = path;
|
nip[ninc++] = path;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"Warning: couldn' alloc mem (reg_include)\n");
|
fprintf(stderr, "Warning: couldn' alloc mem (reg_include)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
||||||
int i,l=(int)strlen(fn);
|
int i, l = (int) strlen(fn);
|
||||||
|
|
||||||
if(l>=MAXLINE) {
|
if (l >= MAXLINE) {
|
||||||
fprintf(stderr,"filename '%s' too long!\n",fn);
|
fprintf(stderr, "filename '%s' too long!\n", fn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy to xname by replacing windows backslashes with the proper DIRCHAR
|
// copy to xname by replacing windows backslashes with the proper DIRCHAR
|
||||||
for(i=0;i<l+1;i++) {
|
for (i = 0; i < l + 1; i++) {
|
||||||
xname[i]=((fn[i]=='\\')?DIRCHAR:fn[i]);
|
xname[i] = ((fn[i] == '\\') ? DIRCHAR : fn[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//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)
|
||||||
if(c!=DIRCHAR) strcat(n,DIRCSTRING);
|
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]) {
|
||||||
{
|
strcpy(n, cp);
|
||||||
if(cp[0])
|
c = n[(int) strlen(n) - 1];
|
||||||
{
|
if (c != DIRCHAR && c != ':')
|
||||||
strcpy(n,cp);
|
strcat(n, DIRCSTRING);
|
||||||
c=n[(int)strlen(n)-1];
|
strcpy(n2, n);
|
||||||
if(c!=DIRCHAR&&c!=':')
|
strcat(n2, xname);
|
||||||
strcat(n,DIRCSTRING);
|
strcat(n, fn);
|
||||||
strcpy(n2,n);
|
file = fopen(n, mode);
|
||||||
strcat(n2,xname);
|
if (!file)
|
||||||
strcat(n,fn);
|
file = fopen(n2, mode);
|
||||||
file=fopen(n,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);
|
||||||
{
|
if (n[0]) {
|
||||||
strcpy(n,cp);
|
c = n[(int) strlen(n) - 1];
|
||||||
if(n[0])
|
if (c != DIRCHAR && c != ':')
|
||||||
{
|
strcat(n, DIRCSTRING);
|
||||||
c=n[(int)strlen(n)-1];
|
|
||||||
if(c!=DIRCHAR&&c!=':')
|
|
||||||
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;
|
|
||||||
else
|
else
|
||||||
cp++;
|
cp++;
|
||||||
} else
|
} else
|
||||||
cp++;
|
cp++;
|
||||||
strcat(n,cp);
|
strcat(n, cp);
|
||||||
file=fopen(n,mode);
|
file = fopen(n, mode);
|
||||||
} else
|
} else
|
||||||
file=fopen(fn,mode);
|
file = fopen(fn, mode);
|
||||||
}
|
}
|
||||||
if(file)
|
if (file)
|
||||||
setvbuf(file,NULL,_IOFBF,BUFSIZE);
|
setvbuf(file, NULL, _IOFBF, BUFSIZE);
|
||||||
|
|
||||||
return(file);
|
return (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
#ifndef __XA65_XAM_H__
|
#ifndef __XA65_XAM_H__
|
||||||
#define __XA65_XAM_H__
|
#define __XA65_XAM_H__
|
||||||
|
|
||||||
FILE *xfopen(const char *fn, const char *mode);
|
FILE* xfopen(const char *fn, const char *mode);
|
||||||
void reg_include(char *);
|
void reg_include(char*);
|
||||||
|
|
||||||
#endif /* __XA65_XAM_H__ */
|
#endif /* __XA65_XAM_H__ */
|
||||||
|
|
62
xa/src/xao.c
62
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)
|
||||||
*
|
*
|
||||||
|
@ -30,27 +30,29 @@
|
||||||
#include "xao.h"
|
#include "xao.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static Fopt *olist =NULL;
|
static Fopt *olist =NULL;
|
||||||
static int mlist =0;
|
static int mlist =0;
|
||||||
static int nlist =0;
|
static int nlist =0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* sets file option after pass 1 */
|
/* sets file option after pass 1 */
|
||||||
void set_fopt(int l, signed char *buf, int reallen) {
|
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,
|
||||||
if(!afile->fo.olist) {
|
afile->fo.mlist * sizeof(Fopt));
|
||||||
fprintf(stderr, "Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n",
|
if (!afile->fo.olist) {
|
||||||
(unsigned long)(
|
fprintf(stderr,
|
||||||
afile->fo.mlist*sizeof(Fopt)));
|
"Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n",
|
||||||
|
(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);
|
||||||
|
@ -59,29 +61,29 @@ void set_fopt(int l, signed char *buf, int reallen) {
|
||||||
|
|
||||||
/* writes file options to a file */
|
/* writes file options to a file */
|
||||||
void o_write(FILE *fp) {
|
void o_write(FILE *fp) {
|
||||||
int i,j,l,afl;
|
int i, j, l, afl;
|
||||||
signed char *t;
|
signed char *t;
|
||||||
|
|
||||||
for(i=0;i<afile->fo.nlist;i++) {
|
for (i = 0; i < afile->fo.nlist; i++) {
|
||||||
l=afile->fo.olist[i].len;
|
l = afile->fo.olist[i].len;
|
||||||
t=afile->fo.olist[i].text;
|
t = afile->fo.olist[i].text;
|
||||||
/* do not optimize */
|
/* do not optimize */
|
||||||
t_p2_l(t, &l, &afl);
|
t_p2_l(t, &l, &afl);
|
||||||
|
|
||||||
if(l>254) {
|
if (l > 254) {
|
||||||
errout(E_OPTLEN);
|
errout(E_OPTLEN);
|
||||||
} else {
|
} else {
|
||||||
fputc((l+1)&0xff,fp);
|
fputc((l + 1) & 0xff, fp);
|
||||||
}
|
}
|
||||||
for(j=0;j<l;j++) {
|
for (j = 0; j < l; j++) {
|
||||||
fputc(t[j],fp);
|
fputc(t[j], fp);
|
||||||
/*printf("%02x ", t[j]); */
|
/*printf("%02x ", t[j]); */
|
||||||
}
|
}
|
||||||
/*printf("\n");*/
|
/*printf("\n");*/
|
||||||
}
|
}
|
||||||
fputc(0,fp); /* end option list */
|
fputc(0, fp); /* end option list */
|
||||||
|
|
||||||
for(i=0;i<afile->fo.nlist;i++) {
|
for (i = 0; i < afile->fo.nlist; i++) {
|
||||||
free(afile->fo.olist[i].text);
|
free(afile->fo.olist[i].text);
|
||||||
}
|
}
|
||||||
free(afile->fo.olist);
|
free(afile->fo.olist);
|
||||||
|
@ -93,9 +95,9 @@ void o_write(FILE *fp) {
|
||||||
size_t o_length(void) {
|
size_t o_length(void) {
|
||||||
int i;
|
int i;
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for(i=0;i<afile->fo.nlist;i++) {
|
for (i = 0; i < afile->fo.nlist; i++) {
|
||||||
/*printf("found option: %s, len=%d, n=%d\n", afile->fo.olist[i].text, afile->fo.olist[i].len,n);*/
|
/*printf("found option: %s, len=%d, n=%d\n", afile->fo.olist[i].text, afile->fo.olist[i].len,n);*/
|
||||||
n += afile->fo.olist[i].len +1;
|
n += afile->fo.olist[i].len + 1;
|
||||||
}
|
}
|
||||||
return ++n;
|
return ++n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
876
xa/src/xap.c
876
xa/src/xap.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
|
||||||
|
@ -28,7 +28,7 @@ int pp_define(char *name);
|
||||||
void pp_close(void);
|
void pp_close(void);
|
||||||
void pp_end(void);
|
void pp_end(void);
|
||||||
int pgetline(char *t);
|
int pgetline(char *t);
|
||||||
Datei *pp_getidat(void);
|
Datei* pp_getidat(void);
|
||||||
|
|
||||||
/* needed for .include pseudo opcode */
|
/* needed for .include pseudo opcode */
|
||||||
int icl_open(char*);
|
int icl_open(char*);
|
||||||
|
|
174
xa/src/xar.c
174
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)
|
||||||
*
|
*
|
||||||
|
@ -37,33 +37,34 @@ File *afile = NULL;
|
||||||
int rmode = RMODE_RELOC;
|
int rmode = RMODE_RELOC;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
int r_set(int pc, int afl, int l) {
|
int r_set(int pc, int afl, int l) {
|
||||||
if(segment==SEG_TEXT) return rt_set(pc,afl,l,0);
|
if(segment==SEG_TEXT) return rt_set(pc,afl,l,0);
|
||||||
if(segment==SEG_DATA) return rd_set(pc,afl,l,0);
|
if(segment==SEG_DATA) return rd_set(pc,afl,l,0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int u_set(int pc, int afl, int label, int l) {
|
int u_set(int pc, int afl, int label, int l) {
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf("set relocation @$%04x, l=%d, afl=%04x, segment=%d, label=%d\n",
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void r_mode(int m) {
|
void r_mode(int m) {
|
||||||
static int old_segment = SEG_TEXT;
|
static int old_segment = SEG_TEXT;
|
||||||
/*printf("setting mode to %s\n",(m==RMODE_RELOC)?"reloc":"abs");*/
|
/*printf("setting mode to %s\n",(m==RMODE_RELOC)?"reloc":"abs");*/
|
||||||
if(rmode!=m) {
|
if (rmode != m) {
|
||||||
if(m==RMODE_RELOC) {
|
if (m == RMODE_RELOC) {
|
||||||
segment = old_segment;
|
segment = old_segment;
|
||||||
} else { /* absolute mode */
|
} else { /* absolute mode */
|
||||||
old_segment = segment;
|
old_segment = segment;
|
||||||
|
@ -74,32 +75,33 @@ 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);*/
|
||||||
|
|
||||||
if(l==2 && ((afl & A_MASK)!=A_ADR)) {
|
if (l == 2 && ((afl & A_MASK) != A_ADR)) {
|
||||||
errout(W_BYTRELOC);
|
errout(W_BYTRELOC);
|
||||||
/*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))
|
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);
|
||||||
}
|
}
|
||||||
/*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->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");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -107,25 +109,25 @@ int rt_set(int pc, int afl, int l, int lab) {
|
||||||
afile->rt.rlist[afile->rt.nlist].adr = pc;
|
afile->rt.rlist[afile->rt.nlist].adr = pc;
|
||||||
afile->rt.rlist[afile->rt.nlist].afl = afl;
|
afile->rt.rlist[afile->rt.nlist].afl = afl;
|
||||||
afile->rt.rlist[afile->rt.nlist].lab = lab;
|
afile->rt.rlist[afile->rt.nlist].lab = lab;
|
||||||
afile->rt.rlist[afile->rt.nlist].next= -1;
|
afile->rt.rlist[afile->rt.nlist].next = -1;
|
||||||
|
|
||||||
/* sorting this into the list is not optimized, to be honest... */
|
/* sorting this into the list is not optimized, to be honest... */
|
||||||
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;
|
||||||
while(afile->rt.rlist[p].adr<pc && afile->rt.rlist[p].next>=0) {
|
pp = -1;
|
||||||
pp=p;
|
while (afile->rt.rlist[p].adr < pc && afile->rt.rlist[p].next >= 0) {
|
||||||
p=afile->rt.rlist[p].next;
|
pp = p;
|
||||||
|
p = afile->rt.rlist[p].next;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
||||||
p,p<0?0:afile->rt.rlist[p].adr,pp,pp<0?0:afile->rt.rlist[pp].adr,afile->rt.nlist,afile->rt.nlist<0?0:afile->rt.rlist[afile->rt.nlist].adr);
|
p,p<0?0:afile->rt.rlist[p].adr,pp,pp<0?0:afile->rt.rlist[pp].adr,afile->rt.nlist,afile->rt.nlist<0?0:afile->rt.rlist[afile->rt.nlist].adr);
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
|
@ -139,38 +141,40 @@ printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
int rt_write(FILE *fp, int pc) {
|
int rt_write(FILE *fp, int pc) {
|
||||||
int p=afile->rt.first;
|
int p = afile->rt.first;
|
||||||
int pc2, afl;
|
int pc2, afl;
|
||||||
|
|
||||||
while(p>=0) {
|
while (p >= 0) {
|
||||||
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)
|
||||||
/*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/
|
afl ^= 0x100;
|
||||||
if((pc2-pc) < 0) {
|
/*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/
|
||||||
|
if ((pc2 - pc) < 0) {
|
||||||
fprintf(stderr, "Oops, negative offset!\n");
|
fprintf(stderr, "Oops, negative offset!\n");
|
||||||
} else {
|
} else {
|
||||||
while((pc2-pc)>254) {
|
while ((pc2 - pc) > 254) {
|
||||||
fputc(255,fp);
|
fputc(255, fp);
|
||||||
pc+=254;
|
pc += 254;
|
||||||
}
|
}
|
||||||
fputc(pc2-pc, fp);
|
fputc(pc2 - pc, fp);
|
||||||
pc=pc2;
|
pc = pc2;
|
||||||
if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEFZP<<8)) {
|
if ((afile->rt.rlist[p].afl & A_FMASK) == (SEG_UNDEFZP << 8)) {
|
||||||
fputc( (((afl & ~A_FMASK)>>8)&255)|SEG_UNDEF, fp);
|
fputc((((afl & ~A_FMASK) >> 8) & 255) | SEG_UNDEF, fp);
|
||||||
fputc(afile->rt.rlist[p].lab & 255, fp);
|
fputc(afile->rt.rlist[p].lab & 255, fp);
|
||||||
fputc((afile->rt.rlist[p].lab>>8) & 255, fp);
|
fputc((afile->rt.rlist[p].lab >> 8) & 255, fp);
|
||||||
} else {
|
} else {
|
||||||
fputc( (afl>>8)&255, fp);
|
fputc((afl >> 8) & 255, fp);
|
||||||
if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8)) {
|
if ((afile->rt.rlist[p].afl & A_FMASK) == (SEG_UNDEF << 8)) {
|
||||||
fputc(afile->rt.rlist[p].lab & 255, fp);
|
fputc(afile->rt.rlist[p].lab & 255, fp);
|
||||||
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;
|
||||||
}
|
}
|
||||||
fputc(0, fp);
|
fputc(0, fp);
|
||||||
|
|
||||||
|
@ -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,40 +201,43 @@ 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;
|
||||||
|
|
||||||
afile = malloc(sizeof(File));
|
afile = malloc(sizeof(File));
|
||||||
if(!afile) {
|
if (!afile) {
|
||||||
fprintf(stderr,"Oops: not enough memory!\n");
|
fprintf(stderr, "Oops: not enough memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
afile->mn.tmp = malloc(TMPMEM);
|
afile->mn.tmp = malloc(TMPMEM);
|
||||||
if(!afile->mn.tmp) {
|
if (!afile->mn.tmp) {
|
||||||
fprintf(stderr,"Oops: not enough memory!\n");
|
fprintf(stderr, "Oops: not enough memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -255,15 +261,15 @@ void seg_end(FILE *fpout) {
|
||||||
afile->len[SEG_ZERO] = pc[SEG_ZERO] - afile->base[SEG_ZERO];
|
afile->len[SEG_ZERO] = pc[SEG_ZERO] - afile->base[SEG_ZERO];
|
||||||
#endif
|
#endif
|
||||||
/* TODO: file length to embed */
|
/* TODO: file length to embed */
|
||||||
/* pc[SEG_ABS] = afile->old_abspc + seg_flen();*/
|
/* pc[SEG_ABS] = afile->old_abspc + seg_flen();*/
|
||||||
|
|
||||||
/*printf("seg_end: len[text]=%d, len[data]=%d, len[bss]=%d, len[zero]=%d\n",
|
/*printf("seg_end: len[text]=%d, len[data]=%d, len[bss]=%d, len[zero]=%d\n",
|
||||||
afile->len[SEG_TEXT], afile->len[SEG_DATA], afile->len[SEG_BSS], afile->len[SEG_ZERO]);*/
|
afile->len[SEG_TEXT], afile->len[SEG_DATA], afile->len[SEG_BSS], afile->len[SEG_ZERO]);*/
|
||||||
segment = SEG_ABS;
|
segment = SEG_ABS;
|
||||||
|
|
||||||
u_write(fpout);
|
u_write(fpout);
|
||||||
rt_write(fpout, afile->base[SEG_TEXT]-1);
|
rt_write(fpout, afile->base[SEG_TEXT] - 1);
|
||||||
rd_write(fpout, afile->base[SEG_DATA]-1);
|
rd_write(fpout, afile->base[SEG_DATA] - 1);
|
||||||
l_write(fpout);
|
l_write(fpout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +279,7 @@ int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen,
|
||||||
|
|
||||||
afile->len[SEG_TEXT] = tlen;
|
afile->len[SEG_TEXT] = tlen;
|
||||||
afile->len[SEG_DATA] = dlen;
|
afile->len[SEG_DATA] = dlen;
|
||||||
afile->len[SEG_BSS ] = blen;
|
afile->len[SEG_BSS] = blen;
|
||||||
afile->len[SEG_ZERO] = zlen;
|
afile->len[SEG_ZERO] = zlen;
|
||||||
|
|
||||||
fputc(1, fp); /* version byte */
|
fputc(1, fp); /* version byte */
|
||||||
|
@ -283,15 +289,15 @@ int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen,
|
||||||
fputc('5', fp);
|
fputc('5', fp);
|
||||||
fputc(0, fp); /* format version */
|
fputc(0, fp); /* format version */
|
||||||
fputw(mode, fp); /* file mode */
|
fputw(mode, fp); /* file mode */
|
||||||
fputw(afile->base[SEG_TEXT],fp); /* text base */
|
fputw(afile->base[SEG_TEXT], fp); /* text base */
|
||||||
fputw(tlen,fp); /* text length */
|
fputw(tlen, fp); /* text length */
|
||||||
fputw(afile->base[SEG_DATA],fp); /* data base */
|
fputw(afile->base[SEG_DATA], fp); /* data base */
|
||||||
fputw(dlen,fp); /* data length */
|
fputw(dlen, fp); /* data length */
|
||||||
fputw(afile->base[SEG_BSS],fp); /* bss base */
|
fputw(afile->base[SEG_BSS], fp); /* bss base */
|
||||||
fputw(blen,fp); /* bss length */
|
fputw(blen, fp); /* bss length */
|
||||||
fputw(afile->base[SEG_ZERO],fp); /* zerop base */
|
fputw(afile->base[SEG_ZERO], fp); /* zerop base */
|
||||||
fputw(zlen,fp); /* zerop length */
|
fputw(zlen, fp); /* zerop length */
|
||||||
fputw(stack,fp); /* needed stack size */
|
fputw(stack, fp); /* needed stack size */
|
||||||
|
|
||||||
o_write(fp);
|
o_write(fp);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#define RMODE_ABS 0
|
#define RMODE_ABS 0
|
||||||
#define RMODE_RELOC 1
|
#define RMODE_RELOC 1
|
||||||
|
|
||||||
extern File *alloc_file(void);
|
extern File* alloc_file(void);
|
||||||
|
|
||||||
/* jumps to r[td]_set, depending on segment */
|
/* jumps to r[td]_set, depending on segment */
|
||||||
/*int r_set(int pc, int reloc, int len);*/
|
/*int r_set(int pc, int reloc, int len);*/
|
||||||
|
@ -42,7 +42,7 @@ int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen,
|
||||||
|
|
||||||
void seg_start(int fmode, int tbase, int dbase, int bbase, int zbase,
|
void seg_start(int fmode, int tbase, int dbase, int bbase, int zbase,
|
||||||
int stacklen, int relmode);
|
int stacklen, int relmode);
|
||||||
void seg_end(FILE *);
|
void seg_end(FILE*);
|
||||||
void seg_pass2(void);
|
void seg_pass2(void);
|
||||||
|
|
||||||
#endif /* __XA65_XAR_H__ */
|
#endif /* __XA65_XAR_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
|
||||||
|
@ -25,35 +25,37 @@
|
||||||
#include "xar.h"
|
#include "xar.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static relocateInfo *rlist = NULL;
|
static relocateInfo *rlist = NULL;
|
||||||
static int mlist = 0, nlist = 0;
|
static int mlist = 0, nlist = 0;
|
||||||
static int first = -1;
|
static int first = -1;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* int rmode; */
|
/* int rmode; */
|
||||||
|
|
||||||
int rd_set(int pc, int afl, int l, int lab) {
|
int rd_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);*/
|
||||||
|
|
||||||
if(l==2 && ((afl & A_MASK)!=A_ADR)) {
|
if (l == 2 && ((afl & A_MASK) != A_ADR)) {
|
||||||
errout(W_BYTRELOC);
|
errout(W_BYTRELOC);
|
||||||
/*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");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -61,25 +63,25 @@ int rd_set(int pc, int afl, int l, int lab) {
|
||||||
afile->rd.rlist[afile->rd.nlist].adr = pc;
|
afile->rd.rlist[afile->rd.nlist].adr = pc;
|
||||||
afile->rd.rlist[afile->rd.nlist].afl = afl;
|
afile->rd.rlist[afile->rd.nlist].afl = afl;
|
||||||
afile->rd.rlist[afile->rd.nlist].lab = lab;
|
afile->rd.rlist[afile->rd.nlist].lab = lab;
|
||||||
afile->rd.rlist[afile->rd.nlist].next= -1;
|
afile->rd.rlist[afile->rd.nlist].next = -1;
|
||||||
|
|
||||||
/* sorting this into the list is not optimized, to be honest... */
|
/* sorting this into the list is not optimized, to be honest... */
|
||||||
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;
|
||||||
while(afile->rd.rlist[p].adr<pc && afile->rd.rlist[p].next>=0) {
|
pp = -1;
|
||||||
pp=p;
|
while (afile->rd.rlist[p].adr < pc && afile->rd.rlist[p].next >= 0) {
|
||||||
p=afile->rd.rlist[p].next;
|
pp = p;
|
||||||
|
p = afile->rd.rlist[p].next;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
||||||
p,p<0?0:afile->rd.rlist[p].adr,pp,pp<0?0:afile->rd.rlist[pp].adr,afile->rd.nlist,afile->rd.nlist<0?0:afile->rd.rlist[afile->rd.nlist].adr);
|
p,p<0?0:afile->rd.rlist[p].adr,pp,pp<0?0:afile->rd.rlist[pp].adr,afile->rd.nlist,afile->rd.nlist<0?0:afile->rd.rlist[afile->rd.nlist].adr);
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
|
@ -93,38 +95,40 @@ printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
int rd_write(FILE *fp, int pc) {
|
int rd_write(FILE *fp, int pc) {
|
||||||
int p=afile->rd.first;
|
int p = afile->rd.first;
|
||||||
int pc2, afl;
|
int pc2, afl;
|
||||||
|
|
||||||
while(p>=0) {
|
while (p >= 0) {
|
||||||
pc2=afile->rd.rlist[p].adr;
|
pc2 = afile->rd.rlist[p].adr;
|
||||||
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)
|
||||||
if((pc2-pc) < 0) {
|
afl ^= 0x100;
|
||||||
|
if ((pc2 - pc) < 0) {
|
||||||
fprintf(stderr, "Oops, negative offset!\n");
|
fprintf(stderr, "Oops, negative offset!\n");
|
||||||
} else {
|
} else {
|
||||||
while((pc2-pc)>254) {
|
while ((pc2 - pc) > 254) {
|
||||||
fputc(255,fp);
|
fputc(255, fp);
|
||||||
pc+=254;
|
pc += 254;
|
||||||
}
|
}
|
||||||
fputc(pc2-pc, fp);
|
fputc(pc2 - pc, fp);
|
||||||
pc=pc2;
|
pc = pc2;
|
||||||
if((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEFZP<<8)) {
|
if ((afile->rd.rlist[p].afl & A_FMASK) == (SEG_UNDEFZP << 8)) {
|
||||||
fputc((((afl & ~A_FMASK)>>8)&255)|SEG_UNDEF, fp);
|
fputc((((afl & ~A_FMASK) >> 8) & 255) | SEG_UNDEF, fp);
|
||||||
fputc(afile->rd.rlist[p].lab & 255, fp);
|
fputc(afile->rd.rlist[p].lab & 255, fp);
|
||||||
fputc((afile->rd.rlist[p].lab>>8) & 255, fp);
|
fputc((afile->rd.rlist[p].lab >> 8) & 255, fp);
|
||||||
} else {
|
} else {
|
||||||
fputc((afl>>8)&255, fp);
|
fputc((afl >> 8) & 255, fp);
|
||||||
if(((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8))) {
|
if (((afile->rd.rlist[p].afl & A_FMASK) == (SEG_UNDEF << 8))) {
|
||||||
fputc(afile->rd.rlist[p].lab & 255, fp);
|
fputc(afile->rd.rlist[p].lab & 255, fp);
|
||||||
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;
|
||||||
}
|
}
|
||||||
fputc(0, fp);
|
fputc(0, fp);
|
||||||
|
|
||||||
|
|
2252
xa/src/xat.c
2252
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
|
||||||
|
|
28
xa/src/xau.c
28
xa/src/xau.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 (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)
|
||||||
*
|
*
|
||||||
|
@ -34,18 +34,20 @@ int u_label(int labnr) {
|
||||||
#ifdef DEBUG_UNDEF
|
#ifdef DEBUG_UNDEF
|
||||||
printf("u_label: %d\n",labnr);
|
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;
|
||||||
afile->ud.ulist = realloc(afile->ud.ulist, afile->ud.um * sizeof(int));
|
afile->ud.ulist = realloc(afile->ud.ulist, afile->ud.um * sizeof(int));
|
||||||
if(!afile->ud.ulist) {
|
if (!afile->ud.ulist) {
|
||||||
fprintf(stderr, "Panic: No memory!\n");
|
fprintf(stderr, "Panic: No memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -57,15 +59,15 @@ printf("u_label: %d\n",labnr);
|
||||||
void u_write(FILE *fp) {
|
void u_write(FILE *fp) {
|
||||||
int i, d;
|
int i, d;
|
||||||
char *s;
|
char *s;
|
||||||
/*printf("u_write: un=%d\n",afile->ud.un);*/
|
/*printf("u_write: un=%d\n",afile->ud.un);*/
|
||||||
fputw(afile->ud.un, fp);
|
fputw(afile->ud.un, fp);
|
||||||
|
|
||||||
for(i=0;i<afile->ud.un;i++) {
|
for (i = 0; i < afile->ud.un; i++) {
|
||||||
l_vget(afile->ud.ulist[i], &d, &s);
|
l_vget(afile->ud.ulist[i], &d, &s);
|
||||||
fprintf(fp,"%s", s);
|
fprintf(fp, "%s", s);
|
||||||
fputc(0,fp);
|
fputc(0, fp);
|
||||||
}
|
}
|
||||||
free(afile->ud.ulist);
|
free(afile->ud.ulist);
|
||||||
afile->ud.ulist=NULL;
|
afile->ud.ulist = NULL;
|
||||||
afile->ud.um = afile->ud.un = 0;
|
afile->ud.um = afile->ud.un = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -16,8 +15,7 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
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