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

Compare commits

...

2 Commits

Author SHA1 Message Date
Andre Fachat
f2dac69090 email address Andre 2023-12-07 23:34:19 +01:00
Andre Fachat
4eb72b1896 formatting for K&R style 2023-12-07 23:28:55 +01:00
34 changed files with 6961 additions and 7118 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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -52,20 +52,13 @@
#define FM_CPU2_NMOS 0x0040 #define FM_CPU2_NMOS 0x0040
#define FM_CPU2_65816E 0x0050 #define FM_CPU2_65816E 0x0050
const char *cpunames[16] = { const char *cpunames[16] = { "6502", "65C02", "65SC02", "65CE02", "NMOS6502",
"6502", "65816",
"65C02", NULL, NULL, "6809", NULL, // 1000 -
"65SC02", "Z80", NULL, NULL, // 1010 -
"65CE02", "8086", // 1101 -
"NMOS6502", "80286", // 1110 -
"65816", NULL };
NULL, NULL,
"6809", NULL, // 1000 -
"Z80", NULL, NULL, // 1010 -
"8086", // 1101 -
"80286", // 1110 -
NULL
};
int read_options(FILE *fp); int read_options(FILE *fp);
int print_labels(FILE *fp, int offset); int print_labels(FILE *fp, int offset);
@ -80,204 +73,240 @@ int labels = 0;
int verbose = 0; int verbose = 0;
void usage(FILE *fp) void usage(FILE *fp) {
{ fprintf(fp, "Usage: %s [options] [file]\n"
"Print file information about o65 files\n"
"\n",
programname);
fprintf(fp, fprintf(fp,
"Usage: %s [options] [file]\n" " -P print the segment end addresses according to `xa' command line\n"
"Print file information about o65 files\n" " parameters `-b?'\n"
"\n", " -a offset print `xa' ``romable'' parameter for another file behind this one\n"
programname); " in the same ROM. Add offset to start address.\n"
fprintf(fp, " -A offset same as `-a', but only print the start address of the next\n"
" -P print the segment end addresses according to `xa' command line\n" " file in the ROM\n"
" parameters `-b?'\n" " -v print undefined and global labels\n"
" -a offset print `xa' ``romable'' parameter for another file behind this one\n" " -vv print undefined and global labels, and relocation tables\n"
" in the same ROM. Add offset to start address.\n" " --version output version information and exit\n"
" -A offset same as `-a', but only print the start address of the next\n" " --help display this help and exit\n");
" file in the ROM\n"
" -v print undefined and global labels\n"
" -vv print undefined and global labels, and relocation tables\n"
" --version output version information and exit\n"
" --help display this help and exit\n");
} }
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(
printf("-A %lu ", (unsigned long)((hdr[9]*256+hdr[8]) " text segment @ $%04x - $%04x [$%04x bytes]\n",
-hlen +romoff +(fbuf.st_size))); hdr[9] * 256 + hdr[8],
} else hdr[9] * 256 + hdr[8] + hdr[11] * 256
if(rompar==2) { + hdr[10],
printf("%lu ", (unsigned long)((hdr[9]*256+hdr[8]) hdr[11] * 256 + hdr[10]);
-hlen +romoff +(fbuf.st_size))); printf(
} " data segment @ $%04x - $%04x [$%04x bytes]\n",
printf("\n"); hdr[13] * 256 + hdr[12],
} hdr[13] * 256 + hdr[12] + hdr[15] * 256
} + hdr[14],
hdr[15] * 256 + hdr[14]);
printf(
" bss segment @ $%04x - $%04x [$%04x bytes]\n",
hdr[17] * 256 + hdr[16],
hdr[17] * 256 + hdr[16] + hdr[19] * 256
+ hdr[18],
hdr[19] * 256 + hdr[18]);
printf(
" zero segment @ $%04x - $%04x [$%04x bytes]\n",
hdr[21] * 256 + hdr[20],
hdr[21] * 256 + hdr[20] + hdr[23] * 256
+ hdr[22],
hdr[23] * 256 + hdr[22]);
printf(" stack size $%04x bytes %s\n",
hdr[25] * 256 + hdr[24],
(hdr[25] * 256 + hdr[24]) == 0 ?
"(i.e. unknown)" : "");
if (verbose) {
read_options(fp);
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;
} }
static struct { int opt; int strfl; char *string; } otab[] = { static struct {
{ 0, 1, "Filename" }, int opt;
{ 1, 0, "O/S Type" }, int strfl;
{ 2, 1, "Assembler" }, char *string;
{ 3, 1, "Author" }, } otab[] = { { 0, 1, "Filename" }, { 1, 0, "O/S Type" }, { 2, 1, "Assembler" },
{ 4, 1, "Creation Date" }, { 3, 1, "Author" }, { 4, 1, "Creation Date" }, { -1, -1, NULL } };
{ -1, -1, NULL }
};
static char* stab[] = { static char *stab[] = { "undefined", "absolute", "text", "data", "bss", "zero",
"undefined" , "-", "-" };
"absolute" ,
"text" ,
"data" ,
"bss" ,
"zero" ,
"-" ,
"-"
};
void print_option(unsigned char *buf, int len) { void print_option(unsigned char *buf, int len) {
int i, strfl=0; int i, strfl = 0;
for(i=0;otab[i].opt>=0; i++) if(*buf==otab[i].opt) break; for (i = 0; otab[i].opt >= 0; i++)
if(otab[i].opt>=0) { if (*buf == otab[i].opt)
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;
} }
@ -285,11 +314,12 @@ int read_options(FILE *fp) {
int print_labels(FILE *fp, int offset) { int print_labels(FILE *fp, int offset) {
int i, nud, c, seg, off; int i, nud, c, seg, off;
const char *segments[] = { "undef", "abs", "text", "data", "bss", "zero" }; const char *segments[] = { "undef", "abs", "text", "data", "bss", "zero" };
const char *reltype[] = { "-", "LOW", "HIGH", "-", "WORD", "SEG", "SEGADDR" }; const char *reltype[] =
{ "-", "LOW", "HIGH", "-", "WORD", "SEG", "SEGADDR" };
/* /*
printf("print_labels:offset=%d\n",offset); printf("print_labels:offset=%d\n",offset);
*/ */
fseek(fp, offset, SEEK_CUR); fseek(fp, offset, SEEK_CUR);
// ----------------------------------------------------------- // -----------------------------------------------------------
@ -300,92 +330,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

@ -2,7 +2,7 @@
# #
# xa65 - 6502 cross assembler and utility suite # xa65 - 6502 cross assembler and utility suite
# mkrom.sh - assemble several 'romable' files into one binary # mkrom.sh - assemble several 'romable' files into one binary
# Copyright (C) 1997 André Fachat (a.fachat@physik.tu-chemnitz.de) # Copyright (C) 1997 Andre Fachat (afachat@gmx.de)
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -29,33 +29,28 @@
#define author "Written by Andre Fachat" #define author "Written by Andre Fachat"
#define copyright "Copyright (C) 1997-2002 Andre Fachat." #define copyright "Copyright (C) 1997-2002 Andre Fachat."
char *cmd[] = { char *cmd[] = { "end", "for", "next", "data", "input#", "input", "dim", "read",
"end", "for", "next", "data", "input#", "input", "dim", "read", "let", "goto", "run", "if", "restore", "gosub", "return", "rem", "stop",
"let", "goto", "run", "if", "restore", "gosub", "return", "on", "wait", "load", "save", "verify", "def", "poke", "print#",
"rem", "stop", "on", "wait", "load", "save", "verify", "def", "print", "cont", "list", "clr", "cmd", "sys", "open", "close", "get",
"poke", "print#", "print", "cont", "list", "clr", "cmd", "sys", "new", "tab(", "to", "fn", "spc(", "then", "not", "step", "+", "-", "*",
"open", "close", "get", "new", "tab(", "to", "fn", "spc(", "/", "^", "and", "or", ">", "=", "<", "sgn", "int", "abs", "usr", "fre",
"then", "not", "step", "+", "-", "*", "/", "^", "and", "or", "pos", "sqr", "rnd", "log", "exp", "cos", "sin", "tan", "atn", "peek",
">", "=", "<", "sgn", "int", "abs", "usr", "fre", "pos", "sqr", "len", "str$", "val", "asc", "chr$", "left$", "right$", "mid$", "go" };
"rnd", "log", "exp", "cos", "sin", "tan", "atn", "peek", "len",
"str$", "val", "asc", "chr$", "left$", "right$", "mid$", "go"
};
void usage(FILE *fp) void usage(FILE *fp) {
{
fprintf(fp, fprintf(fp,
"Usage: %s [OPTION]... [FILE]...\n" "Usage: %s [OPTION]... [FILE]...\n"
"List CBM BASIC programs\n" "List CBM BASIC programs\n"
"This tool is deprecated as of xa 2.4 and will be removed in a future version.\n" "This tool is deprecated as of xa 2.4 and will be removed in a future version.\n"
"Please consider migrating to VICE petcat, which has many more options.\n" "Please consider migrating to VICE petcat, which has many more options.\n"
"\n" "\n"
" --version output version information and exit\n" " --version output version information and exit\n"
" --help display this help and exit\n", " --help display this help and exit\n",
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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -50,67 +50,59 @@
#define FM_CPU2_65816E 0x0050 #define FM_CPU2_65816E 0x0050
typedef struct { typedef struct {
char *fname; char *fname;
size_t fsize; size_t fsize;
unsigned char *buf; unsigned char *buf;
int tbase, tlen, dbase, dlen, bbase, blen, zbase, zlen; int tbase, tlen, dbase, dlen, bbase, blen, zbase, zlen;
int tdiff, ddiff, bdiff, zdiff; int tdiff, ddiff, bdiff, zdiff;
unsigned char *segt; unsigned char *segt;
unsigned char *segd; unsigned char *segd;
unsigned char *utab; unsigned char *utab;
unsigned char *rttab; unsigned char *rttab;
unsigned char *rdtab; unsigned char *rdtab;
unsigned char *extab; unsigned char *extab;
} file65; } file65;
int read_options(unsigned char *f); int read_options(unsigned char *f);
int read_undef(unsigned char *f); int read_undef(unsigned char *f);
unsigned char *reloc_seg(unsigned char *f, int len, unsigned char *rtab, file65 *fp, int undefwarn); unsigned char* reloc_seg(unsigned char *f, int len, unsigned char *rtab,
unsigned char *reloc_globals(unsigned char *, file65 *fp); file65 *fp, int undefwarn);
unsigned char* reloc_globals(unsigned char*, file65 *fp);
file65 file; file65 file;
unsigned char cmp[] = { 1, 0, 'o', '6', '5' }; unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
void usage(FILE *fp) void usage(FILE *fp) {
{
fprintf(fp, fprintf(fp,
"Usage: %s [OPTION]... [FILE]...\n" "Usage: %s [OPTION]... [FILE]...\n"
"Relocator for o65 object files\n" "Relocator for o65 object files\n"
"\n" "\n"
" -b? addr relocates segment '?' (i.e. 't' for text segment,\n" " -b? addr relocates segment '?' (i.e. 't' for text segment,\n"
" 'd' for data, 'b' for bss and 'z' for zeropage) to the new\n" " 'd' for data, 'b' for bss and 'z' for zeropage) to the new\n"
" address `addr'\n" " address `addr'\n"
" -o file uses `file' as output file. Default is `a.o65'\n" " -o file uses `file' as output file. Default is `a.o65'\n"
" -x? extracts text `?' = `t' or data `?' = `d' segment from file\n", " -x? extracts text `?' = `t' or data `?' = `d' segment from file\n",
programname); programname);
fprintf(fp, fprintf(fp,
" instead of writing back the whole file\n" " instead of writing back the whole file\n"
" -X extracts the file such that text and data\n" " -X extracts the file such that text and data\n"
" segments are chained, i.e. possibly relocating\n" " segments are chained, i.e. possibly relocating\n"
" the data segment to the end of the text segment\n" " the data segment to the end of the text segment\n"
" -C <CPU> Set the o65 CPU flags in the output for the following CPUs:\n" " -C <CPU> Set the o65 CPU flags in the output for the following CPUs:\n"
" 6502, 65SC02, 65C02, 65CE02, 65816, NMOS6502\n" " 6502, 65SC02, 65C02, 65CE02, 65816, NMOS6502\n"
" (for details see the man page)\n" " (for details see the man page)\n"
" -v verbose output\n" " -v verbose output\n"
" --version output version information and exit\n" " --version output version information and exit\n"
" --help display this help and exit\n"); " --help display this help and exit\n");
} }
const char *cpunames[16] = { const char *cpunames[16] = { "6502", "65C02", "65SC02", "65CE02", "NMOS6502",
"6502", "65816",
"65C02", NULL, NULL, "6809", NULL, // 1000 -
"65SC02", "Z80", NULL, NULL, // 1010 -
"65CE02", "8086", // 1101 -
"NMOS6502", "80286", // 1110 -
"65816", NULL };
NULL, NULL,
"6809", NULL, // 1000 -
"Z80", NULL, NULL, // 1010 -
"8086", // 1101 -
"80286", // 1110 -
NULL
};
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int i = 1, mode, hlen; int i = 1, mode, hlen;
@ -127,273 +119,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!\n");
} 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!\n");
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 +429,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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -36,172 +36,178 @@ FILE *fp;
char name[100]; char name[100];
char *s; char *s;
void usage(FILE *fp) void usage(FILE *fp) {
{ fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n"
fprintf(fp, "Manage c64 cpk archives\n"
"Usage: %s [OPTION]... [FILE]...\n" "\n"
"Manage c64 cpk archives\n" " c create an archive\n"
"\n" " a add a file to an archive\n"
" c create an archive\n" " x extract archive\n"
" a add a file to an archive\n" " l list contents of archive\n"
" x extract archive\n" " v verbose output\n"
" l list contents of archive\n" " --version output version information and exit\n"
" v verbose output\n" " --help display this help and exit\n",
" --version output version information and exit\n" programname);
" --help display this help and exit\n",
programname);
} }
int list=0,verbose=0,add=0,create=0; int list = 0, verbose = 0, add = 0, create = 0;
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{ int i, c, c2, fileok, nc;
int i,c,c2,fileok, nc; size_t n, n2;
size_t n,n2; FILE *fp, *fpo = NULL;
FILE *fp,*fpo=NULL;
if (argc <= 1) { if (argc <= 1) {
usage(stderr); usage(stderr);
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);
} }

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,18 +20,16 @@
#define __XA65_VERSION_H__ #define __XA65_VERSION_H__
void version(const char *programname, const char *progversion, void version(const char *programname, const char *progversion,
const char *authors, const char *copyright) const char *authors, const char *copyright) {
{ fprintf(stdout, "%s (xa65) %s\n"
fprintf(stdout, "%s\n"
"%s (xa65) %s\n" "\n"
"%s\n" "%s\n"
"\n" "This is free software; see the source for "
"%s\n" "copying conditions. There is NO\n"
"This is free software; see the source for " "warranty; not even for MERCHANTABILIY or "
"copying conditions. There is NO\n" "FITNESS FOR A PARTICULAR PURPOSE.\n", programname, progversion,
"warranty; not even for MERCHANTABILIY or " authors, copyright);
"FITNESS FOR A PARTICULAR PURPOSE.\n",
programname, progversion, authors, copyright);
} }
#endif /* __XA65_VERSION_H__ */ #endif /* __XA65_VERSION_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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,19 +19,17 @@
#ifndef __XA65_VERSION_H__ #ifndef __XA65_VERSION_H__
#define __XA65_VERSION_H__ #define __XA65_VERSION_H__
void version(const char *programname, const char *version, void version(const char *programname, const char *version, const char *authors,
const char *authors, const char *copyright) const char *copyright) {
{ fprintf(stdout, "%s (xa65) %s\n"
fprintf(stdout, "%s\n"
"%s (xa65) %s\n" "\n"
"%s\n" "%s\n"
"\n" "This is free software; see the source for "
"%s\n" "copying conditions. There is NO\n"
"This is free software; see the source for " "warranty; not even for MERCHANTABILIY or "
"copying conditions. There is NO\n" "FITNESS FOR A PARTICULAR PURPOSE.\n", programname, version,
"warranty; not even for MERCHANTABILIY or " authors, copyright);
"FITNESS FOR A PARTICULAR PURPOSE.\n",
programname, version, authors, copyright);
} }
#endif /* __XA65_VERSION_H__ */ #endif /* __XA65_VERSION_H__ */

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -41,7 +41,7 @@ extern int dlen, dbase;
extern int zlen, zbase; extern int zlen, zbase;
extern int romable, romaddr; extern int romable, romaddr;
extern int memode,xmode; extern int memode, xmode;
extern int segment; extern int segment;
extern int pc[SEG_MAX]; extern int pc[SEG_MAX];

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 Andre Fachat (afachat@gmx.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

@ -1,6 +1,6 @@
/* xa65 - 65xx/65816 cross-assembler and utility suite /* xa65 - 65xx/65816 cross-assembler and utility suite
* *
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#define __XA65_XAA_H__ #define __XA65_XAA_H__
/* f = 0 -> label must exist; f = 1 -> SEG_UNDEF entry */ /* f = 0 -> label must exist; f = 1 -> SEG_UNDEF entry */
int a_term(signed char *s, int *v, int *l, int xpc, int *afl, int a_term(signed char *s, int *v, int *l, int xpc, int *afl, int *label,
int *label, int f); int f);
#endif /* __XA65_XAA_H__ */ #endif /* __XA65_XAA_H__ */

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 Andre Fachat (a.fachat@physik.tu-chemnitz.de) * Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
* Maintained by Cameron Kaiser * Maintained by Cameron Kaiser
* *
* Charset conversion module * Charset conversion module
@ -20,7 +20,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -58,11 +57,11 @@ static signed char convert_char_petscii(signed char c) {
static signed char convert_char_petscreen(signed char c) { static signed char convert_char_petscreen(signed char c) {
int i; int i;
i = (int)convert_char_petscii(c); i = (int) convert_char_petscii(c);
#ifdef SIGH #ifdef SIGH
fprintf(stderr, "input: %i output: %i\n", c, i); fprintf(stderr, "input: %i output: %i\n", c, i);
#endif #endif
if (i< 0) if (i < 0)
i += 0x80; i += 0x80;
i ^= 0xe0; i ^= 0xe0;
#ifdef SIGH #ifdef SIGH
@ -74,37 +73,33 @@ 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 }, { "PETSCII",
{ "ASCII", convert_char_ascii }, convert_char_petscii }, { "PETSCREEN", convert_char_petscreen }, {
{ "PETSCII", convert_char_petscii }, "HIGH", convert_char_high }, { NULL, NULL } };
{ "PETSCREEN", convert_char_petscreen },
{ "HIGH", convert_char_high },
{ NULL, NULL }
};
int set_charset(char *charset_name) { int set_charset(char *charset_name) {
int i = 0; int i = 0;
@ -122,4 +117,3 @@ signed char convert_char(signed char c) {
return convert_func(c); return convert_func(c);
} }

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-2006 André Fachat (a.fachat@physik.tu-chemnitz.de) * Copyright (C) 1989-2006 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,8 +20,8 @@
#define __XA65_XA_CHARSET_H__ #define __XA65_XA_CHARSET_H__
/* set the target character set the chars - values in quotes - should /* set the target character set the chars - values in quotes - should
be converted to be converted to
returns 0 on success and -1 when the name is not found */ returns 0 on success and -1 when the name is not found */
int set_charset(char *charset_name); int set_charset(char *charset_name);
/* convert a char */ /* convert a char */

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

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 Andre Fachat (afachat@gmx.de)
* Maintained by Cameron Kaiser * Maintained by Cameron Kaiser
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -38,10 +38,7 @@
#define TMPMEM 2000000L /* temporary memory buffer from Pass1 to Pass 2 (includes all source, thus enlarged) */ #define TMPMEM 2000000L /* temporary memory buffer from Pass1 to Pass 2 (includes all source, thus enlarged) */
typedef enum { typedef enum {
STD = 0, STD = 0, CHEAP = 1, UNNAMED = 2, UNNAMED_DEF = 3
CHEAP = 1,
UNNAMED = 2,
UNNAMED_DEF = 3
} xalabel_t; } xalabel_t;
typedef struct LabOcc { typedef struct LabOcc {
@ -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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#define __XA65_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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,18 +27,17 @@
*/ */
extern char *lz; extern char *lz;
int l_init(void); int l_init(void);
int ga_lab(void); int ga_lab(void);
int gm_lab(void); int gm_lab(void);
long gm_labm(void); long gm_labm(void);
long ga_labm(void); long ga_labm(void);
int lg_set(char *); int lg_set(char*);
int lg_import(int); int lg_import(int);
int lg_importzp(int); int lg_importzp(int);
// used to re-define undef'd labels as global for -U option // used to re-define undef'd labels as global for -U option
int lg_toglobal(char *); int lg_toglobal(char*);
int b_init(void); int b_init(void);
int b_depth(void); int b_depth(void);
@ -46,7 +45,7 @@ int b_depth(void);
void printllist(FILE *fp); void printllist(FILE *fp);
int ga_blk(void); int ga_blk(void);
int l_def(char *s, int* l, int *x, int *f); int l_def(char *s, int *l, int *x, int *f);
int l_search(char *s, int *l, int *x, int *v, int *afl); int l_search(char *s, int *l, int *x, int *v, int *afl);
void l_set(int n, int v, int afl); void l_set(int n, int v, int afl);
char* l_get_name(int n, xalabel_t *is_cll); char* l_get_name(int n, xalabel_t *is_cll);

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 Andre Fachat (afachat@gmx.de)
* maintained by Cameron Kaiser * maintained by Cameron Kaiser
* *
* Assembler listing * Assembler listing
@ -31,7 +31,6 @@
#include "xal.h" #include "xal.h"
#include "xat.h" #include "xat.h"
/*********************************************************************************************/ /*********************************************************************************************/
/* this is the listing code /* this is the listing code
* *
@ -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

@ -1,6 +1,6 @@
/* xa65 - 65xx/65816 cross-assembler and utility suite /* xa65 - 65xx/65816 cross-assembler and utility suite
* *
* Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,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 Andre Fachat (afachat@gmx.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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,7 +19,7 @@
#ifndef __XA65_XAM_H__ #ifndef __XA65_XAM_H__
#define __XA65_XAM_H__ #define __XA65_XAM_H__
FILE *xfopen(const char *fn, const char *mode); FILE* xfopen(const char *fn, const char *mode);
void reg_include(char *); void reg_include(char*);
#endif /* __XA65_XAM_H__ */ #endif /* __XA65_XAM_H__ */

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 Andre Fachat (afachat@gmx.de)
* *
* Options module (handles pass options and writing them out to disk) * Options module (handles pass options and writing them out to disk)
* *
@ -30,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;
} }

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -28,7 +28,7 @@ int pp_define(char *name);
void pp_close(void); void pp_close(void);
void pp_end(void); void pp_end(void);
int pgetline(char *t); int pgetline(char *t);
Datei *pp_getidat(void); Datei* pp_getidat(void);
/* needed for .include pseudo opcode */ /* needed for .include pseudo opcode */
int icl_open(char*); int icl_open(char*);

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 Andre Fachat (afachat@gmx.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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,7 +22,7 @@
#define RMODE_ABS 0 #define RMODE_ABS 0
#define RMODE_RELOC 1 #define RMODE_RELOC 1
extern File *alloc_file(void); extern File* alloc_file(void);
/* jumps to r[td]_set, depending on segment */ /* jumps to r[td]_set, depending on segment */
/*int r_set(int pc, int reloc, int len);*/ /*int r_set(int pc, int reloc, int len);*/
@ -38,11 +38,11 @@ void r_mode(int mode);
/* int rmode; */ /* int rmode; */
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 stacklen); int stacklen);
void seg_start(int fmode, int tbase, int dbase, int bbase, int zbase, void seg_start(int fmode, int tbase, int dbase, int bbase, int zbase,
int stacklen, int relmode); int stacklen, int relmode);
void seg_end(FILE *); void seg_end(FILE*);
void seg_pass2(void); void seg_pass2(void);
#endif /* __XA65_XAR_H__ */ #endif /* __XA65_XAR_H__ */

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 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,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 (a.fachat@physik.tu-chemnitz.de) * Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

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;
} }

View File

@ -1,23 +1,21 @@
/* /*
xa65 - 6502 cross assembler and utility suite xa65 - 6502 cross assembler and utility suite
Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) Copyright (C) 1989-1997 Andre Fachat (afachat@gmx.de)
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
extern int u_label(int labnr); extern int u_label(int labnr);
extern void u_write(FILE *fp); extern void u_write(FILE *fp);