1
0
mirror of https://github.com/fachat/xa65.git synced 2024-06-16 13:29:28 +00:00

formatted source according to K&R

This commit is contained in:
A. Fachat 2024-03-19 09:32:45 +01:00
parent 3be092964c
commit b5cda1bd88
22 changed files with 6614 additions and 6737 deletions

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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
@ -103,126 +103,148 @@ 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], "-?")
usage(stdout); || strstr(argv[i], "-h")) {
exit(0); usage(stdout);
exit(0);
} }
if (strstr(argv[i], "--version")) { if (strstr(argv[i], "--version")) {
version(programname, progversion, author, copyright); version(programname, progversion, author, copyright);
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);
break; else if (i + 1 < argc)
case 'P': romoff = atoi(argv[++i]);
xapar = 1; else
break; fprintf(stderr, "%s: missing offset\n", programname);
default: break;
fprintf(stderr,"%s: %s unknown option, use '-h' for help\n",programname,argv[i]); case 'P':
break; xapar = 1;
} break;
} else { default:
fp = fopen(argv[i],"rb"); fprintf(stderr, "%s: %s unknown option, use '-h' for help\n",
if(fp) { programname, argv[i]);
n = fread(hdr, 1, 8, fp); break;
if((n>=8) && (!memcmp(hdr, cmp, 5))) { }
mode=hdr[7]*256+hdr[6];
if(!xapar && !rompar) {
printf("%s: o65 version %d %s file\n", argv[i], hdr[5],
hdr[7]&0x10 ? "object" : "executable");
printf(" mode: %04x =",mode );
printf("[%s][%sbit][%s relocation][CPU %s][CPU2 %s]%s\n",
(mode & 0x1000)?"object":"executable",
(mode & 0x2000)?"32":"16",
(mode & 0x4000)?"page":"byte",
(mode & 0x8000)?"65816":"6502",
cpunames[(mode & FM_CPU2) >> 4],
aligntxt[mode & 3]);
}
if(mode & 0x2000) {
fprintf(stderr,"file65: %s: 32 bit size not supported\n", argv[i]);
} else { } else {
n=fread(hdr+8, 1, 18, fp); fp = fopen(argv[i], "rb");
if(n<18) { if (fp) {
fprintf(stderr,"file65: %s: truncated file\n", argv[i]); n = fread(hdr, 1, 8, fp);
} else { if ((n >= 8) && (!memcmp(hdr, cmp, 5))) {
if(!xapar && !rompar) { mode = hdr[7] * 256 + hdr[6];
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]); if (!xapar && !rompar) {
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("%s: o65 version %d %s file\n", argv[i], hdr[5],
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[7] & 0x10 ? "object" : "executable");
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(" mode: %04x =", mode);
printf(" stack size $%04x bytes %s\n", hdr[25]*256+hdr[24], printf(
(hdr[25]*256+hdr[24])==0?"(i.e. unknown)":""); "[%s][%sbit][%s relocation][CPU %s][CPU2 %s]%s\n",
if(verbose) { (mode & 0x1000) ? "object" : "executable",
read_options(fp); (mode & 0x2000) ? "32" : "16",
print_labels(fp, hdr[11]*256+hdr[10] + hdr[15]*256+hdr[14]); (mode & 0x4000) ? "page" : "byte",
} (mode & 0x8000) ? "65816" : "6502",
} else { cpunames[(mode & FM_CPU2) >> 4],
struct stat fbuf; aligntxt[mode & 3]);
hlen = 8+18+read_options(fp); }
stat(argv[i],&fbuf); if (mode & 0x2000) {
if(xapar) { fprintf(stderr,
if(!rompar) printf("-bt %d ", "file65: %s: 32 bit size not supported\n",
(hdr[9]*256+hdr[8]) + (hdr[11]*256+hdr[10]) argv[i]);
); } else {
printf("-bd %d -bb %d -bz %d ", n = fread(hdr + 8, 1, 18, fp);
(hdr[13]*256+hdr[12]) + (hdr[15]*256+hdr[14]), if (n < 18) {
(hdr[17]*256+hdr[16]) + (hdr[19]*256+hdr[18]), fprintf(stderr, "file65: %s: truncated file\n",
(hdr[21]*256+hdr[20]) + (hdr[23]*256+hdr[22]) argv[i]);
); } else {
} if (!xapar && !rompar) {
if(rompar==1) { printf(" text segment @ $%04x - $%04x [$%04x bytes]\n",
printf("-A %lu ", (unsigned long)((hdr[9]*256+hdr[8]) hdr[9]*256+hdr[8], hdr[9]*256+hdr[8]+hdr[11]*256+hdr[10], hdr[11]*256+hdr[10]);
-hlen +romoff +(fbuf.st_size))); printf(" data segment @ $%04x - $%04x [$%04x bytes]\n",
} else hdr[13]*256+hdr[12], hdr[13]*256+hdr[12]+hdr[15]*256+hdr[14], hdr[15]*256+hdr[14]);
if(rompar==2) { printf(" bss segment @ $%04x - $%04x [$%04x bytes]\n",
printf("%lu ", (unsigned long)((hdr[9]*256+hdr[8]) hdr[17]*256+hdr[16], hdr[17]*256+hdr[16]+hdr[19]*256+hdr[18], hdr[19]*256+hdr[18]);
-hlen +romoff +(fbuf.st_size))); 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("\n"); 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);
print_labels(fp,
hdr[11] * 256 + hdr[10]
+ hdr[15] * 256 + hdr[14]);
}
} else {
struct stat fbuf;
hlen = 8 + 18 + read_options(fp);
stat(argv[i], &fbuf);
if (xapar) {
if (!rompar)
printf("-bt %d ",
(hdr[9]*256+hdr[8])+(hdr[11]*256+hdr[10]));
printf("-bd %d -bb %d -bz %d ",
(hdr[13]*256+hdr[12]) + (hdr[15]*256+hdr[14]),
(hdr[17]*256+hdr[16]) + (hdr[19]*256+hdr[18]),
(hdr[21]*256+hdr[20]) + (hdr[23]*256+hdr[22])
);
}
if (rompar == 1) {
printf("-A %lu ",
(unsigned long) ((hdr[9] * 256
+ hdr[8]) - hlen + romoff
+ (fbuf.st_size)));
} else if (rompar == 2) {
printf("%lu ",
(unsigned long) ((hdr[9] * 256
+ hdr[8]) - hlen + romoff
+ (fbuf.st_size)));
}
printf("\n");
}
}
}
} else {
fprintf(stderr, "file65: %s: not an o65 file!\n", argv[i]);
if (hdr[0] == 1 && hdr[1] == 8 && hdr[3] == 8) {
printf(
"%s: C64 BASIC executable (start address $0801)?\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 {
fprintf(stderr, "file65: %s: %s\n", argv[i], strerror(errno));
}
} }
} else { i++;
fprintf(stderr,"file65: %s: not an o65 file!\n", argv[i]);
if(hdr[0]==1 && hdr[1]==8 && hdr[3]==8) {
printf("%s: C64 BASIC executable (start address $0801)?\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 {
fprintf(stderr,"file65: %s: %s\n", argv[i], strerror(errno));
}
}
i++;
} }
return 0; return 0;
} }
@ -248,48 +270,54 @@ static char* stab[] = {
}; };
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)
printf("fopt: %-17s: ", otab[i].string); break;
strfl = otab[i].strfl; if (otab[i].opt >= 0) {
printf("fopt: %-17s: ", otab[i].string);
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");
} }
} }
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;
} }
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[] =
const char *reltype[] = { "-", "LOW", "HIGH", "-", "WORD", "SEG", "SEGADDR" }; { "undef", "abs", "text", "data", "bss", "zero" };
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,92 +328,94 @@ 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");
} }
// --------------------------------------------------------- // ---------------------------------------------------------
// 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);
while(c && c!=EOF) {
c&= 0xff;
while(c == 255 && c!= EOF) {
offset += 254;
c=fgetc(fp);
if(c==EOF) break;
c&= 0xff;
}
if(c==EOF) break;
offset += c;
c=fgetc(fp);
if( (c & 0xe0) == 0x40 ) {
lowbyte = fgetc(fp);
}
if( (c & 0x07) == 0 ) {
index = fgetc(fp) & 0xff;
index += (fgetc(fp) & 0xff) << 8;
}
if (verbose > 1) {
printf("\t%d:%s(%s (%d)", offset, reltype[ (c>>5) & 0xf], segments[c & 0x07], (c&0x07));
if ( (c & 0xe0) == 0x40) {
printf(", %02x", lowbyte);
} }
if ( (c & 0x07) == 0) {
printf(", %04x", index); c = fgetc(fp);
while (c && c != EOF) {
c &= 0xff;
while (c == 255 && c != EOF) {
offset += 254;
c = fgetc(fp);
if (c == EOF)
break;
c &= 0xff;
}
if (c == EOF)
break;
offset += c;
c = fgetc(fp);
if ((c & 0xe0) == 0x40) {
lowbyte = fgetc(fp);
}
if ((c & 0x07) == 0) {
index = fgetc(fp) & 0xff;
index += (fgetc(fp) & 0xff) << 8;
}
if (verbose > 1) {
printf("\t%d:%s(%s (%d)", offset, reltype[(c >> 5) & 0xf],
segments[c & 0x07], (c & 0x07));
if ((c & 0xe0) == 0x40) {
printf(", %02x", lowbyte);
}
if ((c & 0x07) == 0) {
printf(", %04x", index);
}
printf(")");
}
c = fgetc(fp);
}
if (verbose > 1) {
printf("\n");
} }
printf(")");
}
c=fgetc(fp);
}
if (verbose > 1) {
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;
} }

File diff suppressed because it is too large Load Diff

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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
@ -54,8 +54,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;

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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
@ -127,273 +127,309 @@ int main(int argc, char *argv[]) {
char *arg; // temporary argument pointer char *arg; // temporary argument pointer
if (argc <= 1) { if (argc <= 1) {
usage(stderr); usage(stderr);
exit(1); exit(1);
} }
if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) { if (strstr(argv[1], "--help") || strstr(argv[1], "-?")
usage(stdout); || strstr(argv[1], "-h")) {
exit(0); usage(stdout);
exit(0);
} }
if (strstr(argv[1], "--version")) { if (strstr(argv[1], "--version")) {
version(programname, progversion, author, copyright); version(programname, progversion, author, copyright);
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)
break; outfile = argv[++i];
case 'X': else
extract=3; fprintf(stderr, "%s: missing output file\n", programname);
break; break;
case 'b': case 'X':
base=NULL; extract = 3;
switch(argv[i][2]) { break;
case 't': case 'b':
tflag= 1; base = NULL;
base=&tbase; switch (argv[i][2]) {
break; case 't':
case 'd': tflag = 1;
dflag= 1; base = &tbase;
base=&dbase; break;
break; case 'd':
case 'b': dflag = 1;
bflag= 1; base = &dbase;
base=&bbase; break;
break; case 'b':
case 'z': bflag = 1;
zflag= 1; base = &bbase;
base=&zbase; break;
break; case 'z':
default: zflag = 1;
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]); base = &zbase;
break; break;
} default:
if (base != NULL) { printf("Unknown segment type '%c' - ignored!\n",
if(argv[i][3]) *base = atoi(argv[i]+3); argv[i][2]);
else if(i + 1 < argc) *base = atoi(argv[++i]); break;
else fprintf(stderr,"%s: missing address\n",programname); }
} if (base != NULL) {
break; if (argv[i][3])
case 'x': /* extract segment */ *base = atoi(argv[i] + 3);
switch(argv[i][2]) { else if (i + 1 < argc)
case 't': *base = atoi(argv[++i]);
extract = 1; else
break; fprintf(stderr, "%s: missing address\n", programname);
case 'd': }
extract = 2; break;
break; case 'x': /* extract segment */
case 'z': switch (argv[i][2]) {
case 'b': case 't':
printf("Cannot extract segment type '%c' - ignored!\n", argv[i][2]); extract = 1;
break; break;
default: case 'd':
printf("Unknown segment type '%c' - ignored!\n", argv[i][2]); extract = 2;
break; break;
} case 'z':
break; case 'b':
case 'C': printf("Cannot extract segment type '%c' - ignored!\n",
if(argv[i][2]) arg=argv[i]+2; argv[i][2]);
else if(i + 1 < argc) arg=argv[++i]; break;
if (arg == NULL) { default:
printf("Missing CPU parameter to -C - ignored\n"); printf("Unknown segment type '%c' - ignored!\n",
break; argv[i][2]);
} break;
for(j = 0; j < 16; j++) { }
if (cpunames[j] != NULL && !strcmp(arg, cpunames[j])) { break;
case 'C':
if (argv[i][2])
arg = argv[i] + 2;
else if (i + 1 < argc)
arg = argv[++i];
if (arg == NULL) {
printf("Missing CPU parameter to -C - ignored\n");
break;
}
for (j = 0; j < 16; j++) {
if (cpunames[j] != NULL && !strcmp(arg, cpunames[j])) {
break;
}
}
if (j == 16) {
printf("Unknown CPU identifier '%s' for -C - ignored\n",
arg);
} else {
trgcpu = j;
}
break;
default:
fprintf(stderr, "%s: %s unknown option, use '-h' for help\n",
programname, argv[i]);
break; break;
} }
}
if (j == 16) {
printf("Unknown CPU identifier '%s' for -C - ignored\n",
arg);
} else { } else {
trgcpu = j; struct stat fs;
} file.fname = argv[i];
break; stat(argv[i], &fs);
default: file.fsize = fs.st_size;
fprintf(stderr,"%s: %s unknown option, use '-h' for help\n",programname,argv[i]); file.buf = malloc(file.fsize);
break; if (!file.buf) {
} fprintf(stderr, "Oops, no more memory! (%d)\n", file.fsize);
} else { exit(1);
struct stat fs;
file.fname=argv[i];
stat(argv[i], &fs);
file.fsize=fs.st_size;
file.buf=malloc(file.fsize);
if(!file.buf) {
fprintf(stderr,"Oops, no more memory! (%d)\n", file.fsize);
exit(1);
}
printf("reloc65: read file %s -> %s\n",argv[i],outfile);
fp = fopen(argv[i],"rb");
if(fp) {
n = fread(file.buf, 1, file.fsize, fp);
fclose(fp);
if((n>=file.fsize) && (!memcmp(file.buf, cmp, 5))) {
mode=file.buf[7]*256+file.buf[6];
if(mode & FM_SIZE) {
fprintf(stderr,"reloc65: %s: 32 bit size not supported\n", argv[i]);
} else
if(mode & FM_RELOC) {
fprintf(stderr,"reloc65: %s: pagewise relocation not supported\n", argv[i]);
} else {
if (trgcpu >= 0) {
// change CPU flags
mode &= ~FM_CPU;
mode &= ~FM_CPU2;
mode |= (trgcpu << 4);
if (trgcpu == 5) {
// this trgcpu is actually 65816 in emulation mode
// unsure if we should do an own cmdline option
mode |= FM_CPU; // 65816 native
} }
} printf("reloc65: read file %s -> %s\n", argv[i], outfile);
file.buf[6] = mode & 0xff; fp = fopen(argv[i], "rb");
file.buf[7] = (mode >> 8) & 0xff; if (fp) {
n = fread(file.buf, 1, file.fsize, fp);
fclose(fp);
if ((n >= file.fsize) && (!memcmp(file.buf, cmp, 5))) {
mode = file.buf[7] * 256 + file.buf[6];
if (mode & FM_SIZE) {
fprintf(stderr,
"reloc65: %s: 32 bit size not supported\n",
argv[i]);
} else if (mode & FM_RELOC) {
fprintf(stderr,
"reloc65: %s: pagewise relocation not supported\n",
argv[i]);
} else {
if (trgcpu >= 0) {
// change CPU flags
mode &= ~FM_CPU;
mode &= ~FM_CPU2;
mode |= (trgcpu << 4);
if (trgcpu == 5) {
// this trgcpu is actually 65816 in emulation mode
// unsure if we should do an own cmdline option
mode |= FM_CPU; // 65816 native
}
}
file.buf[6] = mode & 0xff;
file.buf[7] = (mode >> 8) & 0xff;
hlen = BUF+read_options(file.buf+BUF); hlen = BUF + read_options(file.buf + BUF);
file.tbase = file.buf[ 9]*256+file.buf[ 8];
file.tlen = file.buf[11]*256+file.buf[10];
file.tdiff = tflag ? tbase - file.tbase : 0;
file.dbase = file.buf[13]*256+file.buf[12]; file.tbase = file.buf[9] * 256 + file.buf[8];
file.dlen = file.buf[15]*256+file.buf[14]; file.tlen = file.buf[11] * 256 + file.buf[10];
file.ddiff = dflag ? dbase - file.dbase : 0; file.tdiff = tflag ? tbase - file.tbase : 0;
if (extract == 3) {
if (dflag) {
fprintf(stderr,"reloc65: %s: Warning: data segment address overrides -X option\n", argv[i]);
} else {
dbase = file.tbase + file.tdiff + file.tlen;
file.ddiff = dbase - file.dbase;
}
}
file.bbase = file.buf[17]*256+file.buf[16]; file.dbase = file.buf[13] * 256 + file.buf[12];
file.blen = file.buf[19]*256+file.buf[18]; file.dlen = file.buf[15] * 256 + file.buf[14];
file.bdiff = bflag ? bbase - file.bbase : 0; file.ddiff = dflag ? dbase - file.dbase : 0;
if (extract == 3) { if (extract == 3) {
if (bflag) { if (dflag) {
fprintf(stderr,"reloc65: %s: Warning: bss segment address overrides -X option\n", argv[i]); fprintf(stderr,
} else { "reloc65: %s: Warning: data segment address overrides -X option\n",
bbase = file.dbase + file.ddiff + file.dlen; argv[i]);
file.bdiff = bbase - file.bbase; } else {
} dbase = file.tbase + file.tdiff + file.tlen;
} file.ddiff = dbase - file.dbase;
}
}
file.zbase = file.buf[21]*256+file.buf[20]; file.bbase = file.buf[17] * 256 + file.buf[16];
file.zlen = file.buf[23]*256+file.buf[22]; file.blen = file.buf[19] * 256 + file.buf[18];
file.zdiff = zflag ? zbase - file.zbase : 0; file.bdiff = bflag ? bbase - file.bbase : 0;
if (extract == 3) {
if (bflag) {
fprintf(stderr,
"reloc65: %s: Warning: bss segment address overrides -X option\n",
argv[i]);
} else {
bbase = file.dbase + file.ddiff + file.dlen;
file.bdiff = bbase - file.bbase;
}
}
if (verbose) { file.zbase = file.buf[21] * 256 + file.buf[20];
printf("Relocating segments to:\n"); file.zlen = file.buf[23] * 256 + file.buf[22];
printf("text segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n", file.zdiff = zflag ? zbase - file.zbase : 0;
file.tbase + file.tdiff, file.tbase + file.tdiff + file.tlen,
file.tlen, file.tlen, file.tdiff, file.tdiff & 0xffff);
printf("data segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
file.dbase + file.ddiff, file.dbase + file.ddiff + file.dlen,
file.dlen, file.dlen, file.ddiff, 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 */ if (verbose) {
file.segt = file.buf + hlen; printf("Relocating segments to:\n");
file.segd = file.segt + file.tlen; printf(
file.utab = file.segd + file.dlen; "text segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
file.tbase + file.tdiff,
file.tbase + file.tdiff + file.tlen,
file.tlen, file.tlen, file.tdiff,
file.tdiff & 0xffff);
printf(
"data segment @ $%04x - $%04x, %5d ($%04x) bytes, diff is %5d ($%04x)\n",
file.dbase + file.ddiff,
file.dbase + file.ddiff + file.dlen,
file.dlen, file.dlen, file.ddiff,
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);
}
file.rttab = file.utab + read_undef(file.utab); /* pointer of position in file */
file.rdtab = reloc_seg(file.segt, file.tlen, file.rttab, file.segt = file.buf + hlen;
&file, extract); file.segd = file.segt + file.tlen;
file.extab = reloc_seg(file.segd, file.dlen, file.rdtab, file.utab = file.segd + file.dlen;
&file, extract);
reloc_globals(file.extab, &file); file.rttab = file.utab + read_undef(file.utab);
file.rdtab = reloc_seg(file.segt, file.tlen, file.rttab,
&file, extract);
file.extab = reloc_seg(file.segd, file.dlen, file.rdtab,
&file, extract);
if(tflag) { reloc_globals(file.extab, &file);
file.buf[ 9]= (tbase>>8)&255;
file.buf[ 8]= tbase & 255;
}
if(dflag) {
file.buf[13]= (dbase>>8)&255;
file.buf[12]= dbase & 255;
}
if(bflag) {
file.buf[17]= (bbase>>8)&255;
file.buf[16]= bbase & 255;
}
if(zflag) {
file.buf[21]= (zbase>>8)&255;
file.buf[20]= zbase & 255;
}
fp = fopen(outfile, "wb"); if (tflag) {
if(fp) { file.buf[9] = (tbase >> 8) & 255;
switch(extract) { file.buf[8] = tbase & 255;
case 0: /* whole file */ }
fwrite(file.buf, 1, file.fsize, fp); if (dflag) {
break; file.buf[13] = (dbase >> 8) & 255;
case 1: /* text segment */ file.buf[12] = dbase & 255;
fwrite(file.segt, 1, file.tlen, fp); }
break; if (bflag) {
case 2: /* data segment */ file.buf[17] = (bbase >> 8) & 255;
fwrite(file.segd, 1, file.dlen, fp); file.buf[16] = bbase & 255;
break; }
case 3: /* text+data */ if (zflag) {
fwrite(file.segt, 1, file.tlen, fp); file.buf[21] = (zbase >> 8) & 255;
fwrite(file.segd, 1, file.dlen, fp); file.buf[20] = zbase & 255;
break; }
}
fclose(fp); fp = fopen(outfile, "wb");
} else { if (fp) {
fprintf(stderr,"reloc65: write '%s': %s\n", switch (extract) {
outfile, strerror(errno)); case 0: /* whole file */
} fwrite(file.buf, 1, file.fsize, fp);
break;
case 1: /* text segment */
fwrite(file.segt, 1, file.tlen, fp);
break;
case 2: /* data segment */
fwrite(file.segd, 1, file.dlen, fp);
break;
case 3: /* text+data */
fwrite(file.segt, 1, file.tlen, fp);
fwrite(file.segd, 1, file.dlen, fp);
break;
}
fclose(fp);
} else {
fprintf(stderr, "reloc65: write '%s': %s\n",
outfile, strerror(errno));
}
}
} else {
fprintf(stderr, "reloc65: %s: not an o65 file!\n", argv[i]);
if (file.buf[0] == 1 && file.buf[1] == 8
&& file.buf[3] == 8) {
printf(
"%s: C64 BASIC executable (start address $0801)?\n",
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 {
fprintf(stderr, "reloc65: read '%s': %s\n", argv[i],
strerror(errno));
}
} }
} else { 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) {
printf("%s: C64 BASIC executable (start address $0801)?\n", 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 {
fprintf(stderr,"reloc65: read '%s': %s\n",
argv[i], strerror(errno));
}
}
i++;
} }
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,90 +437,94 @@ 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++;
} }
return l; return l;
} }
#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 {
adr += *rtab & 255; adr += *rtab & 255;
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;
case 0x20: /* LOW - low byt of an address */ case 0x20: /* LOW - low byt of an address */
old = buf[adr]; old = buf[adr];
new = old + reldiff(seg); new = old + reldiff(seg);
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,
fp->fname); "reloc65: %s: Warning: relocation table entries past segment end!\n",
fprintf(stderr, "reloc65: adr=%x len=%x\n", adr, len); fp->fname);
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; ;
old = buf[1] + 256*buf[2]; seg = *buf;
new = old + reldiff(seg); old = buf[1] + 256 * buf[2];
/*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ new = old + reldiff(seg);
buf[1] = new & 255; /*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/
buf[2] = (new>>8) & 255; buf[1] = new & 255;
buf +=3; buf[2] = (new >> 8) & 255;
n--; buf += 3;
n--;
} }
return buf; return buf;
} }

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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
@ -54,154 +54,162 @@ void usage(FILE *fp)
int list=0,verbose=0,add=0,create=0; int list=0,verbose=0,add=0,create=0;
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{ int i, c, c2, fileok, nc;
int i,c,c2,fileok, nc; size_t n, n2;
size_t n,n2; FILE *fp, *fpo = NULL;
FILE *fp,*fpo=NULL;
if (argc <= 1) { if (argc <= 1) {
usage(stderr); usage(stderr);
exit(1); exit(1);
} }
if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) { if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) {
usage(stdout); usage(stdout);
exit(0); exit(0);
} }
if (strstr(argv[1], "--version")) { if (strstr(argv[1], "--version")) {
version(programname, progversion, author, copyright); version(programname, progversion, author, copyright);
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)
if(!add) fputc(1,fpo); /* Version Byte */ fputc(1, fpo); /* Version Byte */
for(i=3;i<argc;i++) { for (i = 3; i < argc; i++) {
if(verbose) printf("%s\n",argv[i]); if (verbose)
fp=fopen(argv[i],"rb"); printf("%s\n", argv[i]);
if(fp) { fp = fopen(argv[i], "rb");
while((s=strchr(argv[i],':'))) *s='/'; if (fp) {
fprintf(fpo,"%s",argv[i]); while ((s = strchr(argv[i], ':')))
fputc(0,fpo); *s = '/';
c=fgetc(fp); fprintf(fpo, "%s", argv[i]);
while(c!=EOF) { fputc(0, fpo);
n=1; c = fgetc(fp);
while((c2=fgetc(fp))==c) { while (c != EOF) {
n++; n = 1;
} while ((c2 = fgetc(fp)) == c) {
while(n) { n++;
if(n>=4 || c==0xf7) { }
n2=min(255,n); while (n) {
fprintf(fpo,"\xf7%c%c",(char)n2,(char)c); if (n >= 4 || c == 0xf7) {
n-=n2; n2 = min(255, n);
} else { fprintf(fpo, "\xf7%c%c", (char) n2, (char) c);
fputc(c,fpo); n -= n2;
n--; } else {
} fputc(c, fpo);
} n--;
c=c2; }
} }
fclose(fp); c = c2;
fputc(0xf7,fpo); fputc(0,fpo); }
} else { fclose(fp);
fprintf(stderr,"Couldn't open file '%s' for reading!",argv[i]); fputc(0xf7, fpo);
} fputc(0, fpo);
} } else {
fclose(fpo); fprintf(stderr, "Couldn't open file '%s' for reading!",
} else { argv[i]);
fprintf(stderr,"Couldn't open file '%s' for writing!",argv[1]); }
} }
} else { fclose(fpo);
if (argc != 3) { } else {
usage(stderr); fprintf(stderr, "Couldn't open file '%s' for writing!", argv[1]);
exit(1); }
} } else {
fp=fopen(argv[2],"rb"); if (argc != 3) {
if(fp){ usage(stderr);
if(fgetc(fp)==1){ exit(1);
do{ }
/* read name */ fp = fopen(argv[2], "rb");
i=0; if (fp) {
while((c=fgetc(fp))){ if (fgetc(fp) == 1) {
if(c==EOF) break; do {
name[i++]=c; /* read name */
} i = 0;
name[i++]='\0'; while ((c = fgetc(fp))) {
if(!c){ /* end of archive ? */ if (c == EOF)
while((s=strchr(name,'/'))) *s=':'; break;
name[i++] = c;
if(verbose+list) printf("%s\n",name); }
name[i++] = '\0';
if(!list) { if (!c) { /* end of archive ? */
fpo=fopen(name,"wb"); while ((s = strchr(name, '/')))
if(!fpo) { *s = ':';
fprintf(stderr,"Couldn't open output file %s !\n",name);
} if (verbose + list)
} printf("%s\n", name);
fileok=0;
while((c=fgetc(fp))!=EOF){ if (!list) {
/* test if 'compressed' */ fpo = fopen(name, "wb");
if(c==0xf7){ if (!fpo) {
nc=fgetc(fp); fprintf(stderr,
if(!nc) { "Couldn't open output file %s !\n",
fileok=1; name);
break; }
} }
c=fgetc(fp); fileok = 0;
if(fpo) { /* extract */ while ((c = fgetc(fp)) != EOF) {
if(nc!=EOF && c!=EOF) { /* test if 'compressed' */
nc &= 255; if (c == 0xf7) {
while(nc--) { nc = fgetc(fp);
fputc(c,fpo); if (!nc) {
} fileok = 1;
} break;
} }
} else { c = fgetc(fp);
if(fpo) { if (fpo) { /* extract */
fputc(c,fpo); if (nc != EOF && c != EOF) {
} nc &= 255;
} while (nc--) {
} fputc(c, fpo);
if(fpo) { }
fclose(fpo); }
fpo=NULL; }
} } else {
if(!fileok) { if (fpo) {
fprintf(stderr,"Unexpected end of file!\n"); fputc(c, fpo);
}
}
}
if (fpo) {
fclose(fpo);
fpo = NULL;
}
if (!fileok) {
fprintf(stderr, "Unexpected end of file!\n");
}
}
} while (c != EOF);
} else
fprintf(stderr, "Wrong Version!\n");
fclose(fp);
} else {
fprintf(stderr, "File %s not found!\n", argv[1]);
} }
}
} while(c!=EOF);
} else
fprintf(stderr,"Wrong Version!\n");
fclose(fp);
} else {
fprintf(stderr,"File %s not found!\n",argv[1]);
}
} }
return(0); return (0);
} }

File diff suppressed because it is too large Load Diff

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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];

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.de)
* *
* Preprocessing arithmetic module * Preprocessing arithmetic module
* *
@ -30,84 +30,80 @@
#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)
if(afl) *pfl=A_LOW | ((afl<<8) & A_FMASK); *pfl = A_LOW | ((afl << 8) & A_FMASK);
*v = *v & 255; *v = *v & 255;
} else } else if (s[pp] == '>') {
if(s[pp]=='>') pp++;
{ er = ag_term(s, P_START, v, &afl, label);
pp++; bfl = afl & (A_MASK >> 8);
er=ag_term(s,P_START,v,&afl, label); if (bfl && (bfl != (A_ADR >> 8)) && (bfl != (A_HIGH >> 8))) {
bfl = afl & (A_MASK>>8); /*fprintf(stderr,"high byte relocation for a low byte - won't work!\n");*/
if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_HIGH>>8)) ) { errout(W_HIGHACC);
/*fprintf(stderr,"high byte relocation for a low byte - won't work!\n");*/ }
errout(W_HIGHACC); if (afl)
} *pfl = A_HIGH | ((afl << 8) & A_FMASK) | (*v & 255);
if(afl) *pfl=A_HIGH | ((afl<<8) & A_FMASK) | (*v & 255); *v = (*v >> 8) & 255;
*v=(*v>>8)&255; } else if (s[pp] != T_END) {
} er = ag_term(s, P_START, v, &afl, label);
else bfl = afl & (A_MASK >> 8);
if(s[pp]!=T_END) { if (bfl && (bfl != (A_ADR >> 8))) {
er=ag_term(s,P_START,v,&afl, label); /*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/
bfl = afl & (A_MASK>>8); errout(W_ADDRACC);
if(bfl && (bfl != (A_ADR>>8)) ) { }
/*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/ if (afl)
errout(W_ADDRACC); *pfl = A_ADR | ((afl << 8) & A_FMASK);
} } else {
if(afl) *pfl = A_ADR | ((afl<<8) & A_FMASK); er = E_SYNTAX;
} else { }
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 */
if(s[pp]==18) /* logical not */ if(s[pp]==18) /* logical not */
@ -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] != ')')
{ er = E_SYNTAX;
if(s[pp]!=')') else
er=E_SYNTAX; pp++;
else }
pp++; } else if (s[pp] == T_LABEL) {
} er = l_get(cval(s + pp + 1), v, &afl);
} else
if(s[pp]==T_LABEL)
{
er=l_get(cval(s+pp+1),v, &afl);
/* /*
printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n", 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 while (s[pp] == T_CAST) {
if(s[pp]==T_VALUE || s[pp] == T_CAST) pp += 2;
{ }
while (s[pp] == T_CAST) { *v = lval(s + pp + 1);
pp+=2; pp += 5;
} /*
*v=lval(s+pp+1); printf("value: v=%04x\n",*v);
pp+=5; */
/* } else if (s[pp] == T_POINTER) {
printf("value: v=%04x\n",*v); afl = s[pp + 1];
*/ *v = cval(s + pp + 2);
} pp += 6;
else /*
if(s[pp]==T_POINTER) printf("pointer: v=%04x, afl=%04x\n",*v,afl);
{ */
afl = s[pp+1]; } else if (s[pp] == '*') {
*v=cval(s+pp+2); *v = pcc;
pp+=6; pp++;
/* afl = segment;
printf("pointer: v=%04x, afl=%04x\n",*v,afl); } else {
*/ er = E_SYNTAX;
}
else
if(s[pp]=='*')
{
*v=pcc;
pp++;
afl = segment;
}
else {
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 if (((afl && !*nafl) || (*nafl && !afl)) && o == 1) {
} else afl = (afl | *nafl); /* add constant to pointer */
if(((afl && !*nafl) || (*nafl && !afl)) && o==1) { } else if ((afl && !*nafl) && o == 2) {
afl=(afl | *nafl); /* add constant to pointer */ afl = (afl | *nafl); /* subtract constant from pointer */
} else } else {
if((afl && !*nafl) && o==2) { if ((!afl && *nafl) && o == 2) {
afl=(afl | *nafl); /* subtract constant from pointer */ /* subtract pointer from constant */
} else { errout(W_SUBTRACT);
if((!afl && *nafl) && o==2) { }
/* subtract pointer from constant */ /* allow math in the same segment */
errout(W_SUBTRACT); if (segment != SEG_ABS && segment != afl) {
if (!dsb_len) {
/*printf("ILLPOINTER=dsb_len=%d,segment=%d\n",dsb_len, segment);*/
/* e.g. adding two pointers, adding two undefined values */
er = E_ILLSEGMENT;
}
}
afl = 0;
}
}
if (!er)
er = do_op(v, w, o);
} }
/* allow math in the same segment */ } else {
if(segment!=SEG_ABS && segment != afl) { break;
if(!dsb_len) { }
/*printf("ILLPOINTER=dsb_len=%d,segment=%d\n",dsb_len, segment);*/
/* e.g. adding two pointers, adding two undefined values */
er=E_ILLSEGMENT;
}
}
afl=0;
}
}
if(!er) er=do_op(v,w,o);
}
} else {
break;
}
}
*nafl = afl;
return(er);
}
static int get_op(signed char *s, int *o)
{
int er;
*o=s[pp];
if(*o<1 || *o>17) {
/*
printf("*o=%d, pp=%d, s=%s\n", *o, pp, s);
for (int i=0; i< 10; i++) {
printf(" %02x", s[i]);
} }
printf("\n"); *nafl = afl;
*/ return (er);
er=E_SYNTAX; }
} else {
er=E_OK; static int get_op(signed char *s, int *o) {
} int er;
return(er); *o = s[pp];
}
if (*o < 1 || *o > 17) {
static int do_op(int *w,int w2,int o) /*
{ printf("*o=%d, pp=%d, s=%s\n", *o, pp, s);
int er=E_OK; for (int i=0; i< 10; i++) {
switch (o) { printf(" %02x", s[i]);
case 1: }
*w +=w2; printf("\n");
break; */
case 2: er = E_SYNTAX;
*w -=w2; } else {
break; er = E_OK;
case 3: }
*w *=w2;
break; return (er);
case 4: }
if (w2!=0)
*w /=w2; static int do_op(int *w, int w2, int o) {
else int er = E_OK;
er =E_DIV; switch (o) {
break; case 1:
case 5: *w += w2;
*w >>=w2; break;
break; case 2:
case 6: *w -= w2;
*w <<=w2; break;
break; case 3:
case 7: *w *= w2;
*w = *w<w2; break;
break; case 4:
case 8: if (w2 != 0)
*w = *w>w2; *w /= w2;
break; else
case 9: er = E_DIV;
*w = *w==w2; break;
break; case 5:
case 10: *w >>= w2;
*w = *w<=w2; break;
break; case 6:
case 11: *w <<= w2;
*w = *w>=w2; break;
break; case 7:
case 12: *w = *w < w2;
*w = *w!=w2; break;
break; case 8:
case 13: *w = *w > w2;
*w &=w2; break;
break; case 9:
case 14: *w = *w == w2;
*w ^=w2; break;
break; case 10:
case 15: *w = *w <= w2;
*w |=w2; break;
break; case 11:
case 16: *w = *w >= w2;
*w =*w&&w2; break;
break; case 12:
case 17: *w = *w != w2;
*w =*w||w2; break;
break; case 13:
} *w &= w2;
return(er); break;
case 14:
*w ^= w2;
break;
case 15:
*w |= w2;
break;
case 16:
*w = *w && w2;
break;
case 17:
*w = *w || w2;
break;
}
return (er);
} }

View File

@ -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,36 +73,36 @@ 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) {
return (c | 0x80); return (c | 0x80);
} }
typedef struct { typedef struct {
char *name; char *name;
signed char (*func)(signed char); signed char (*func)(signed char);
} charset; } charset;
static charset charsets[] = { static charset charsets[] = {
{ "ASCII", convert_char_ascii }, { "ASCII", convert_char_ascii },
{ "PETSCII", convert_char_petscii }, { "PETSCII", convert_char_petscii },
{ "PETSCREEN", convert_char_petscreen }, { "PETSCREEN", convert_char_petscreen },
{ "HIGH", convert_char_high }, { "HIGH", convert_char_high },
{ NULL, NULL } { NULL, NULL }
}; };
int set_charset(char *charset_name) { int set_charset(char *charset_name) {
@ -122,4 +121,3 @@ signed char convert_char(signed char c) {
return convert_func(c); return convert_func(c);
} }

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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 {
@ -58,14 +55,14 @@ typedef struct {
int origblk; // only for fl=3 int origblk; // only for fl=3
int val; int val;
int len; int len;
int fl; /* 0 = label value not valid/known, int fl; /* 0 = label value not valid/known,
* 1 = label value known * 1 = label value known
* 2 = label value not known, external global label (imported on link) * 2 = label value not known, external global label (imported on link)
* 3 = label value not known, temporarily on external global label list (for -U) * 3 = label value not known, temporarily on external global label list (for -U)
*/ */
int afl; /* 0 = no address (no relocation), 1 = address label */ int afl; /* 0 = no address (no relocation), 1 = address label */
int nextindex; int nextindex;
xalabel_t is_cll; /* 0 is normal label, 1 is cheap local label (used for listing) */ xalabel_t is_cll; /* 0 is normal label, 1 is cheap local label (used for listing) */
char *n; char *n;
struct LabOcc *occlist; struct LabOcc *occlist;
// within a block, make a linked list for the unnamed label counting // within a block, make a linked list for the unnamed label counting
@ -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) */
@ -219,7 +215,7 @@ typedef struct {
#define SEG_UNDEFZP 7 /* is being mapped to UNDEF */ #define SEG_UNDEFZP 7 /* is being mapped to UNDEF */
typedef struct Fopt { typedef struct Fopt {
signed char *text; /* text after pass1 */ signed char *text; /* text after pass1 */
int len; int len;
} Fopt; } Fopt;

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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_XAH2_H__ #define __XA65_XAH2_H__
typedef struct { typedef struct {
char *fname; /* fname[MAXLINE]; */ char *fname; /* fname[MAXLINE]; */
int fline; int fline;
int bdepth; int bdepth;
FILE *filep; FILE *filep;

File diff suppressed because it is too large Load Diff

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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);

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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
* *
@ -41,9 +40,9 @@
*/ */
static FILE *listfp = NULL; static FILE *listfp = NULL;
static int list_lineno = 1; /* current line number */ static int list_lineno = 1; /* current line number */
static int list_last_lineno = 0; /* current line number */ static int list_last_lineno = 0; /* current line number */
static char *list_filenamep = NULL; /* current file name pointer */ static char *list_filenamep = NULL; /* current file name pointer */
static int list_numbytes = 8; static int list_numbytes = 8;
@ -63,38 +62,36 @@ static int list_nibble_f(char *buf, int outnib, signed char format);
// formatter // formatter
typedef struct { 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;
return buf; return buf;
} }
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
fprintf(listfp, "<html><head><title>%s</title></head><body><pre>\n", fprintf(listfp, "<html><head><title>%s</title></head><body><pre>\n",
(name == NULL) ? "(null)" : name); (name == NULL) ? "(null)" : name);
} }
static int html_set_anchor(char *buf, char *name) { static int html_set_anchor(char *buf, char *name) {
@ -116,26 +113,24 @@ 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;
char *q = buf; char *q = buf;
while (*p != 0) { while (*p != 0) {
if (*p == '<') { if (*p == '<') {
strcpy(q, "&lt;"); strcpy(q, "&lt;");
q+=4; q += 4;
p++; p++;
} else } else if (*p == '&') {
if (*p == '&') {
strcpy(q, "&amp;"); strcpy(q, "&amp;");
q+=5; q += 5;
p++; p++;
} else } else if (*p == '>') {
if (*p == '>') {
strcpy(q, "&gt;"); strcpy(q, "&gt;");
q+=4; q += 4;
p++; p++;
} else { } else {
*q = *p; *q = *p;
@ -147,25 +142,18 @@ 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;
buf[1] = 0; buf[1] = 0;
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,12 +346,14 @@ 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;
} }
i = num_last_line - i; i = num_last_line - i;
buf = buf + list_nchar(buf, ' ', i * 3); buf = buf + list_nchar(buf, ' ', i * 3);
@ -370,10 +379,11 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
} }
#endif #endif
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)
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,60 +463,65 @@ 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;
case T_END: case T_END:
/* end of operation */ /* end of operation */
@ -516,67 +531,71 @@ 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:
case T_FILE: case T_FILE:
/* those two are meta-tokens, evaluated outside the t_p2 call, /* those two are meta-tokens, evaluated outside the t_p2 call,
* they result in calls to list_line(), list_filename() */ * they result in calls to list_line(), list_filename() */
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, '#');
tmp = ((input[inp+3]&255)<<8) | (input[inp+2]&255); tmp = ((input[inp+3]&255)<<8) | (input[inp+2]&255);
outp += list_value(buf+outp, tmp); outp += list_value(buf+outp, tmp);
*/ */
inp += 6; inp += 6;
operator = 1; /* check if arithmetic operator follows */ operator = 1; /* check if arithmetic operator follows */
break; break;
case '"': { case '"': {
int i, len; int i, 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;
} }

View File

@ -25,10 +25,11 @@ void list_end();
void list_flush(); // debug helper void list_flush(); // debug helper
void list_setfile(FILE *fp); void list_setfile(FILE *fp);
void list_line(int l); /* set line number for the coming listing output */ 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__ */

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.de)
* *
* Memory manager/malloc() stub module * Memory manager/malloc() stub module
* *
@ -27,105 +27,99 @@
static int ninc = 0; static int ninc = 0;
static char **nip = NULL; 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]) {
if(cp[0]) strcpy(n, cp);
{ c = n[(int) strlen(n) - 1];
strcpy(n,cp); if (c != DIRCHAR && c != ':')
c=n[(int)strlen(n)-1]; strcat(n, DIRCSTRING);
if(c!=DIRCHAR&&c!=':') strcpy(n2, n);
strcat(n,DIRCSTRING); strcat(n2, xname);
strcpy(n2,n); strcat(n, fn);
strcat(n2,xname); file = fopen(n, mode);
strcat(n,fn); if (!file)
file=fopen(n,mode); file = fopen(n2, mode);
if(!file) file=fopen(n2,mode); }
cp = strtok(NULL, ",");
} }
cp=strtok(NULL,",");
} }
} }
} } else {
} else if ((cp = getenv("XAOUTPUT")) != NULL) {
{ strcpy(n, cp);
if((cp=getenv("XAOUTPUT"))!=NULL) if (n[0]) {
{ c = n[(int) strlen(n) - 1];
strcpy(n,cp); if (c != DIRCHAR && c != ':')
if(n[0]) 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

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.de)
* *
* Options module (handles pass options and writing them out to disk) * Options module (handles pass options and writing them out to disk)
* *
@ -30,28 +30,30 @@
#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",
exit(1); (unsigned long) (afile->fo.mlist * sizeof(Fopt)));
} 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",
exit(1); l);
exit(1);
} }
memcpy(afile->fo.olist[afile->fo.nlist].text, buf, l); memcpy(afile->fo.olist[afile->fo.nlist].text, buf, l);
afile->fo.olist[afile->fo.nlist++].len = reallen; afile->fo.olist[afile->fo.nlist++].len = reallen;
@ -59,30 +61,30 @@ 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) {
errout(E_OPTLEN);
} else {
fputc((l+1)&0xff,fp);
}
for(j=0;j<l;j++) {
fputc(t[j],fp);
/*printf("%02x ", t[j]); */
}
/*printf("\n");*/
}
fputc(0,fp); /* end option list */
for(i=0;i<afile->fo.nlist;i++) { if (l > 254) {
free(afile->fo.olist[i].text); errout(E_OPTLEN);
} else {
fputc((l + 1) & 0xff, fp);
}
for (j = 0; j < l; j++) {
fputc(t[j], fp);
/*printf("%02x ", t[j]); */
}
/*printf("\n");*/
}
fputc(0, fp); /* end option list */
for (i = 0; i < afile->fo.nlist; i++) {
free(afile->fo.olist[i].text);
} }
free(afile->fo.olist); free(afile->fo.olist);
afile->fo.olist = NULL; afile->fo.olist = NULL;
@ -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;
} }

File diff suppressed because it is too large Load Diff

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.de)
* *
* Relocation module (for relocatable objects) * Relocation module (for relocatable objects)
* *
@ -37,101 +37,103 @@ 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;
segment = SEG_ABS; segment = SEG_ABS;
} }
} }
rmode = m; rmode = 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);
} }
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", /*
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); 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);
if(afile->rt.rlist[p].next<0 && afile->rt.rlist[p].adr<pc) { */
afile->rt.rlist[p].next=afile->rt.nlist; if (afile->rt.rlist[p].next < 0 && afile->rt.rlist[p].adr < pc) {
} else afile->rt.rlist[p].next = afile->rt.nlist;
if(pp==-1) { } else 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 {
afile->rt.rlist[afile->rt.nlist].next = p; afile->rt.rlist[afile->rt.nlist].next = p;
afile->rt.rlist[pp].next = afile->rt.nlist; afile->rt.rlist[pp].next = afile->rt.nlist;
} }
} }
afile->rt.nlist++; afile->rt.nlist++;
@ -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);*/
fprintf(stderr, "Oops, negative offset!\n"); if ((pc2 - pc) < 0) {
} else { fprintf(stderr, "Oops, negative offset!\n");
while((pc2-pc)>254) { } else {
fputc(255,fp); while ((pc2 - pc) > 254) {
pc+=254; fputc(255, fp);
} pc += 254;
fputc(pc2-pc, fp); }
pc=pc2; fputc(pc2 - pc, fp);
if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEFZP<<8)) { pc = pc2;
fputc( (((afl & ~A_FMASK)>>8)&255)|SEG_UNDEF, fp); if ((afile->rt.rlist[p].afl & A_FMASK) == (SEG_UNDEFZP << 8)) {
fputc(afile->rt.rlist[p].lab & 255, fp); fputc((((afl & ~A_FMASK) >> 8) & 255) | SEG_UNDEF, fp);
fputc((afile->rt.rlist[p].lab>>8) & 255, fp); fputc(afile->rt.rlist[p].lab & 255, fp);
} else { fputc((afile->rt.rlist[p].lab >> 8) & 255, fp);
fputc( (afl>>8)&255, fp); } else {
if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8)) { fputc((afl >> 8) & 255, fp);
fputc(afile->rt.rlist[p].lab & 255, fp); if ((afile->rt.rlist[p].afl & A_FMASK) == (SEG_UNDEF << 8)) {
fputc((afile->rt.rlist[p].lab>>8) & 255, fp); fputc(afile->rt.rlist[p].lab & 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)
p=afile->rt.rlist[p].next; fputc(afl & 255, fp);
}
p = afile->rt.rlist[p].next;
} }
fputc(0, fp); fputc(0, fp);
@ -182,56 +186,58 @@ 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;
afile->slen = slen; afile->slen = slen;
afile->relmode = relmode; afile->relmode = relmode;
pc[SEG_TEXT] = afile->base[SEG_TEXT] = t_base; pc[SEG_TEXT] = afile->base[SEG_TEXT] = t_base;
pc[SEG_DATA] = afile->base[SEG_DATA] = d_base; pc[SEG_DATA] = afile->base[SEG_DATA] = d_base;
pc[SEG_BSS] = afile->base[SEG_BSS] = b_base; pc[SEG_BSS] = afile->base[SEG_BSS] = b_base;
pc[SEG_ZERO] = afile->base[SEG_ZERO] = z_base; pc[SEG_ZERO] = afile->base[SEG_ZERO] = z_base;
afile->old_abspc = pc[SEG_ABS]; afile->old_abspc = pc[SEG_ABS];
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.lt = NULL; afile->la.hashindex[i] = 0;
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;
} }
@ -240,11 +246,11 @@ void seg_pass2(void) {
pc[SEG_TEXT] = afile->base[SEG_TEXT]; pc[SEG_TEXT] = afile->base[SEG_TEXT];
pc[SEG_DATA] = afile->base[SEG_DATA]; pc[SEG_DATA] = afile->base[SEG_DATA];
pc[SEG_BSS] = afile->base[SEG_BSS]; pc[SEG_BSS] = afile->base[SEG_BSS];
pc[SEG_ZERO] = afile->base[SEG_ZERO]; pc[SEG_ZERO] = afile->base[SEG_ZERO];
afile->old_abspc = pc[SEG_ABS]; afile->old_abspc = pc[SEG_ABS];
pc[SEG_ABS] = pc[SEG_TEXT]; pc[SEG_ABS] = pc[SEG_TEXT];
} }
void seg_end(FILE *fpout) { void seg_end(FILE *fpout) {
@ -255,46 +261,46 @@ 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);
} }
/* write header for relocatable output format */ /* write header for relocatable output format */
int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen, int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen,
int stack) { int stack) {
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 */
fputc(0, fp); /* hi address 0 -> no C64 */ fputc(0, fp); /* hi address 0 -> no C64 */
fputc('o', fp); fputc('o', fp);
fputc('6', fp); fputc('6', fp);
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);
return 0; return 0;
} }

View File

@ -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 Andr<EFBFBD> Fachat (a.fachat@physik.tu-chemnitz.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,67 +25,69 @@
#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 p,pp;
/* if(!rmode) return 0; */ int rd_set(int pc, int afl, int l, int lab) {
int p, pp;
/* 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))
/*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/ errout(W_ADRRELOC);
afl = (afl & (~A_MASK)) | A_LOW; /*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/
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);
} }
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", /*
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); 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);
if(afile->rd.rlist[p].next<0 && afile->rd.rlist[p].adr<pc) { */
afile->rd.rlist[p].next=afile->rd.nlist; if (afile->rd.rlist[p].next < 0 && afile->rd.rlist[p].adr < pc) {
} else afile->rd.rlist[p].next = afile->rd.nlist;
if(pp==-1) { } else 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 {
afile->rd.rlist[afile->rd.nlist].next = p; afile->rd.rlist[afile->rd.nlist].next = p;
afile->rd.rlist[pp].next = afile->rd.nlist; afile->rd.rlist[pp].next = afile->rd.nlist;
} }
} }
afile->rd.nlist++; afile->rd.nlist++;
@ -93,45 +95,47 @@ 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;
fprintf(stderr, "Oops, negative offset!\n"); if ((pc2 - pc) < 0) {
} else { fprintf(stderr, "Oops, negative offset!\n");
while((pc2-pc)>254) { } else {
fputc(255,fp); while ((pc2 - pc) > 254) {
pc+=254; fputc(255, fp);
} pc += 254;
fputc(pc2-pc, fp); }
pc=pc2; fputc(pc2 - pc, fp);
if((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEFZP<<8)) { pc = pc2;
fputc((((afl & ~A_FMASK)>>8)&255)|SEG_UNDEF, fp); if ((afile->rd.rlist[p].afl & A_FMASK) == (SEG_UNDEFZP << 8)) {
fputc(afile->rd.rlist[p].lab & 255, fp); fputc((((afl & ~A_FMASK) >> 8) & 255) | SEG_UNDEF, fp);
fputc((afile->rd.rlist[p].lab>>8) & 255, fp); fputc(afile->rd.rlist[p].lab & 255, fp);
} else { fputc((afile->rd.rlist[p].lab >> 8) & 255, fp);
fputc((afl>>8)&255, fp); } else {
if(((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8))) { fputc((afl >> 8) & 255, fp);
fputc(afile->rd.rlist[p].lab & 255, fp); if (((afile->rd.rlist[p].afl & A_FMASK) == (SEG_UNDEF << 8))) {
fputc((afile->rd.rlist[p].lab>>8) & 255, fp); fputc(afile->rd.rlist[p].lab & 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)
p=afile->rd.rlist[p].next; fputc(afl & 255, fp);
}
p = afile->rd.rlist[p].next;
} }
fputc(0, fp); fputc(0, fp);
free(afile->rd.rlist); free(afile->rd.rlist);
afile->rd.rlist = NULL; afile->rd.rlist = NULL;
afile->rd.mlist = afile->rd.nlist = 0; afile->rd.mlist = afile->rd.nlist = 0;
afile->rd.first = -1; afile->rd.first = -1;
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -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,21 +34,23 @@ 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);
} }
} }
afile->ud.ulist[afile->ud.un] = labnr; afile->ud.ulist[afile->ud.un] = labnr;
return afile->ud.un++; return afile->ud.un++;
@ -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;
} }