diff --git a/xa/misc/file65.c b/xa/misc/file65.c index 6c69b46..9cb9923 100644 --- a/xa/misc/file65.c +++ b/xa/misc/file65.c @@ -1,7 +1,7 @@ /* file65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * Print information about o65 files * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -103,126 +103,148 @@ void usage(FILE *fp) int main(int argc, char *argv[]) { int i, j, n, mode, hlen; FILE *fp; - char *aligntxt[4]= {"[align 1]","[align 2]","[align 4]","[align 256]"}; - if(argc<=1) { + char *aligntxt[4] = { "[align 1]", "[align 2]", "[align 4]", "[align 256]" }; + if (argc <= 1) { usage(stderr); exit(1); } i = 1; - if (strstr(argv[i], "--help") || strstr(argv[i], "-?") || strstr(argv[i], "-h")) { - usage(stdout); - exit(0); + if (strstr(argv[i], "--help") || strstr(argv[i], "-?") + || strstr(argv[i], "-h")) { + usage(stdout); + exit(0); } if (strstr(argv[i], "--version")) { - version(programname, progversion, author, copyright); - exit(0); + version(programname, progversion, author, copyright); + exit(0); } - while(i=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]); + while (i < argc) { + if (argv[i][0] == '-') { + /* process options */ + switch (argv[i][1]) { + case 'v': + j = 1; + while (argv[i][j] == 'v') { + verbose++; + j++; + } + break; + case 'a': + case 'A': + rompar = 1; + if (argv[i][1] == 'A') + rompar++; + if (argv[i][2]) + romoff = atoi(argv[i] + 2); + else if (i + 1 < argc) + romoff = atoi(argv[++i]); + else + fprintf(stderr, "%s: missing offset\n", programname); + break; + case 'P': + xapar = 1; + break; + default: + fprintf(stderr, "%s: %s unknown option, use '-h' for help\n", + programname, argv[i]); + break; + } } else { - n=fread(hdr+8, 1, 18, fp); - if(n<18) { - fprintf(stderr,"file65: %s: truncated file\n", argv[i]); - } else { - if(!xapar && !rompar) { - printf(" text segment @ $%04x - $%04x [$%04x bytes]\n", hdr[9]*256+hdr[8], hdr[9]*256+hdr[8]+hdr[11]*256+hdr[10], hdr[11]*256+hdr[10]); - printf(" data segment @ $%04x - $%04x [$%04x bytes]\n", hdr[13]*256+hdr[12], hdr[13]*256+hdr[12]+hdr[15]*256+hdr[14], hdr[15]*256+hdr[14]); - printf(" bss segment @ $%04x - $%04x [$%04x bytes]\n", hdr[17]*256+hdr[16], hdr[17]*256+hdr[16]+hdr[19]*256+hdr[18], hdr[19]*256+hdr[18]); - printf(" zero segment @ $%04x - $%04x [$%04x bytes]\n", hdr[21]*256+hdr[20], hdr[21]*256+hdr[20]+hdr[23]*256+hdr[22], hdr[23]*256+hdr[22]); - printf(" stack size $%04x bytes %s\n", hdr[25]*256+hdr[24], - (hdr[25]*256+hdr[24])==0?"(i.e. unknown)":""); - if(verbose) { - read_options(fp); - 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"); - } - } + fp = fopen(argv[i], "rb"); + if (fp) { + n = fread(hdr, 1, 8, fp); + 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 { + n = fread(hdr + 8, 1, 18, fp); + if (n < 18) { + fprintf(stderr, "file65: %s: truncated file\n", + argv[i]); + } else { + if (!xapar && !rompar) { + printf(" text segment @ $%04x - $%04x [$%04x bytes]\n", + hdr[9]*256+hdr[8], hdr[9]*256+hdr[8]+hdr[11]*256+hdr[10], hdr[11]*256+hdr[10]); + printf(" data segment @ $%04x - $%04x [$%04x bytes]\n", + hdr[13]*256+hdr[12], hdr[13]*256+hdr[12]+hdr[15]*256+hdr[14], hdr[15]*256+hdr[14]); + printf(" bss segment @ $%04x - $%04x [$%04x bytes]\n", + hdr[17]*256+hdr[16], hdr[17]*256+hdr[16]+hdr[19]*256+hdr[18], hdr[19]*256+hdr[18]); + printf(" zero segment @ $%04x - $%04x [$%04x bytes]\n", + hdr[21]*256+hdr[20], hdr[21]*256+hdr[20]+hdr[23]*256+hdr[22], hdr[23]*256+hdr[22]); + printf(" stack size $%04x bytes %s\n", + hdr[25]*256+hdr[24], (hdr[25]*256+hdr[24])==0?"(i.e. unknown)":""); + if (verbose) { + read_options(fp); + 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 { - 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++; + i++; } return 0; } @@ -248,48 +270,54 @@ static char* stab[] = { }; void print_option(unsigned char *buf, int len) { - int i, strfl=0; - for(i=0;otab[i].opt>=0; i++) if(*buf==otab[i].opt) break; - if(otab[i].opt>=0) { - printf("fopt: %-17s: ", otab[i].string); - strfl = otab[i].strfl; + int i, strfl = 0; + for (i = 0; otab[i].opt >= 0; i++) + if (*buf == otab[i].opt) + break; + if (otab[i].opt >= 0) { + printf("fopt: %-17s: ", otab[i].string); + strfl = otab[i].strfl; } else { - printf("fopt: Unknown Type $%02x : ", (*buf & 0xff)); + printf("fopt: Unknown Type $%02x : ", (*buf & 0xff)); } - if(strfl) { - buf[len]=0; - printf("%s\n", buf+1); + if (strfl) { + buf[len] = 0; + printf("%s\n", buf + 1); } else { - for (i=1; i 1) { - 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 (verbose > 1) { + printf("Relocation table for %s:\n", i ? "text" : "data"); } - 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 nud = (fgetc(fp) & 0xff); nud += ((fgetc(fp) << 8) & 0xff00); printf("Global Labels: %d\n", nud); - if(nud) { - do { - c=fgetc(fp); - while(c && c!=EOF) { - fputc(c, stdout); - c=fgetc(fp); - } - if(c==EOF) break; + if (nud) { + do { + c = fgetc(fp); + while (c && c != EOF) { + fputc(c, stdout); + c = fgetc(fp); + } + if (c == EOF) + break; - seg = fgetc(fp) & 0xff; - off= (fgetc(fp) & 0xff); - off+= ((fgetc(fp) << 8) & 0xff00); - printf(" (segID=%d (%s), offset=%04x)\n", seg, stab[seg&7], off); - - } while(--nud); + seg = fgetc(fp) & 0xff; + off = (fgetc(fp) & 0xff); + off += ((fgetc(fp) << 8) & 0xff00); + printf(" (segID=%d (%s), offset=%04x)\n", seg, stab[seg & 7], off); + + } while (--nud); } return 0; -} - +} diff --git a/xa/misc/ldo65.c b/xa/misc/ldo65.c index 05e48cd..546d255 100644 --- a/xa/misc/ldo65.c +++ b/xa/misc/ldo65.c @@ -3,7 +3,7 @@ * * A part of the xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1997-2023 André Fachat (fachat@web.de) + * Copyright (C) 1997-2023 Andr� Fachat (fachat@web.de) * * 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 @@ -69,74 +69,73 @@ The process of linking works as follows: #define FM_CPU2_NMOS 0x0040 #define FM_CPU2_65816E 0x0050 - typedef struct { - char *name; - int len; - int newidx; /* index in new global undef table (for reloc) */ - int resolved; /* index in current global label table after resolve (-1 is not found) */ + char *name; + int len; + int newidx; /* index in new global undef table (for reloc) */ + int resolved; /* index in current global label table after resolve (-1 is not found) */ } undefs; /* file information */ typedef struct { - char *fname; /* file name */ - size_t fsize; /* length of file */ - unsigned char *buf; /* file content */ + char *fname; /* file name */ + size_t fsize; /* length of file */ + unsigned char *buf; /* file content */ - int mode; /* mode value */ - int align; /* align value */ + int mode; /* mode value */ + int align; /* align value */ - int tbase; /* header: text base */ - int tlen; /* text length */ - int talign; /* insert to get correct alignment */ + int tbase; /* header: text base */ + int tlen; /* text length */ + int talign; /* insert to get correct alignment */ - int dbase; /* data base */ - int dlen; /* data length */ - int dalign; /* insert to get correct alignment */ + int dbase; /* data base */ + int dlen; /* data length */ + int dalign; /* insert to get correct alignment */ - int bbase; /* bss base */ - int blen; /* bss length */ - int balign; /* insert to get correct alignment */ + int bbase; /* bss base */ + int blen; /* bss length */ + int balign; /* insert to get correct alignment */ - int zbase; /* zero base */ - int zlen; /* zero length */ + int zbase; /* zero base */ + int zlen; /* zero length */ - int tdiff; /* text segment relocation diff */ - int ddiff; /* data segment relocation diff */ - int bdiff; /* bss segment relocation diff */ - int zdiff; /* zero segment relocation diff */ + int tdiff; /* text segment relocation diff */ + int ddiff; /* data segment relocation diff */ + int bdiff; /* bss segment relocation diff */ + int zdiff; /* zero segment relocation diff */ - int tpos; /* position of text segment in file */ - int dpos; /* position of data segment in file */ - int upos; /* position of undef'd list in file */ - int trpos; /* position of text reloc tab in file */ - int drpos; /* position of data reloc tab in file */ - int gpos; /* position of globals list in file */ + int tpos; /* position of text segment in file */ + int dpos; /* position of data segment in file */ + int upos; /* position of undef'd list in file */ + int trpos; /* position of text reloc tab in file */ + int drpos; /* position of data reloc tab in file */ + int gpos; /* position of globals list in file */ - int nundef; /* number of undefined labels */ - undefs *ud; /* undefined labels list NULL if none */ + int nundef; /* number of undefined labels */ + undefs *ud; /* undefined labels list NULL if none */ } file65; /* globally defined lables are stored in this struct */ typedef struct { - char *name; - int len; /* length of labelname */ - int fl; /* 0=ok, 1=multiply defined */ - int val; /* address value */ - int seg; /* segment */ - file65 *file; /* in which file is it? */ + char *name; + int len; /* length of labelname */ + int fl; /* 0=ok, 1=multiply defined */ + int val; /* address value */ + int seg; /* segment */ + file65 *file; /* in which file is it? */ } glob; - -file65 *load_file(char *fname); +file65* load_file(char *fname); int read_options(unsigned char *f); int read_undef(unsigned char *f, file65 *fp); int write_undef(FILE *f, file65 *fp); int check_undef(file65 *fp, char *defined[], int ndefined); int len_reloc_seg(unsigned char *buf, int ri); -int reloc_seg(unsigned char *buf, int pos, int addr, int rdiff, int ri, unsigned char *obuf, int *lastaddrp, int *rop, file65 *fp); -unsigned char *reloc_globals(unsigned char *, file65 *fp); +int reloc_seg(unsigned char *buf, int pos, int addr, int rdiff, int ri, + unsigned char *obuf, int *lastaddrp, int *rop, file65 *fp); +unsigned char* reloc_globals(unsigned char*, file65 *fp); int read_globals(file65 *file); int write_options(FILE *fp, file65 *file); int write_reloc(file65 *fp[], int nfp, FILE *f); @@ -187,8 +186,8 @@ void usage(FILE *fp) } int main(int argc, char *argv[]) { - int noglob=0; - int undefok=0; + int noglob = 0; + int undefok = 0; int i = 1; // default output segment addresses, overwritten by cmdline params int tbase = 0x0400, dbase = 0x1000, bbase = 0x4000, zbase = 0x0002; @@ -206,10 +205,10 @@ int main(int argc, char *argv[]) { char alignbuf[256]; // to efficiently write align fillers char *arg; - char **defined = NULL; + char **defined = NULL; int ndefined = 0; int ndefalloc = 0; - + // globals allowed by -g char **globdef = NULL; int nglobal = 0; @@ -220,111 +219,131 @@ int main(int argc, char *argv[]) { exit(1); } - if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) { - usage(stdout); - exit(0); + if (strstr(argv[1], "--help") || strstr(argv[1], "-?") + || strstr(argv[1], "-h")) { + usage(stdout); + exit(0); } if (strstr(argv[1], "--version")) { - version(programname, progversion, author, copyright); - exit(0); + version(programname, progversion, author, copyright); + exit(0); } /* read options */ - while(i= ngloballoc) { - ngloballoc *= 2; - globdef = realloc(globdef, ngloballoc * sizeof(char*)); - } - globdef[nglobal++] = arg; - break; - case 'L': - if(argv[i][2]) arg=argv[i]+2; - else arg=argv[++i]; - if (ndefalloc == 0) { - ndefalloc = 20; - defined = malloc(ndefalloc * sizeof(char*)); - } else - if (ndefined >= ndefalloc) { - ndefalloc *= 2; - defined = realloc(defined, ndefalloc * sizeof(char*)); - } - defined[ndefined++] = arg; - break; - case 'b': - switch(argv[i][2]) { - case 't': - if(argv[i][3]) tbase = atoi(argv[i]+3); - else tbase = atoi(argv[++i]); + while (i < argc && argv[i][0] == '-') { + arg = NULL; + /* process options */ + switch (argv[i][1]) { + case 'v': + j = 1; + while (argv[i][j] == 'v') { + verbose++; + j++; + } break; - case 'd': - if(argv[i][3]) dbase = atoi(argv[i]+3); - else dbase = atoi(argv[++i]); + case 'G': + noglob = 1; + break; + case 'U': + undefok = 1; + break; + case 'o': + if (argv[i][2]) + outfile = argv[i] + 2; + else + outfile = argv[++i]; + break; + case 'g': + noglob = 1; + if (argv[i][2]) + arg = argv[i] + 2; + else + arg = argv[++i]; + if (ngloballoc == 0) { + ngloballoc = 20; + globdef = malloc(ngloballoc * sizeof(char*)); + } else if (nglobal >= ngloballoc) { + ngloballoc *= 2; + globdef = realloc(globdef, ngloballoc * sizeof(char*)); + } + globdef[nglobal++] = arg; + break; + case 'L': + if (argv[i][2]) + arg = argv[i] + 2; + else + arg = argv[++i]; + if (ndefalloc == 0) { + ndefalloc = 20; + defined = malloc(ndefalloc * sizeof(char*)); + } else if (ndefined >= ndefalloc) { + ndefalloc *= 2; + defined = realloc(defined, ndefalloc * sizeof(char*)); + } + defined[ndefined++] = arg; break; case 'b': - if(argv[i][3]) bbase = atoi(argv[i]+3); - else bbase = atoi(argv[++i]); - break; - case 'z': - if(argv[i][3]) zbase = atoi(argv[i]+3); - else zbase = atoi(argv[++i]); + switch (argv[i][2]) { + case 't': + if (argv[i][3]) + tbase = atoi(argv[i] + 3); + else + tbase = atoi(argv[++i]); + break; + case 'd': + if (argv[i][3]) + dbase = atoi(argv[i] + 3); + else + dbase = atoi(argv[++i]); + break; + case 'b': + if (argv[i][3]) + bbase = atoi(argv[i] + 3); + else + bbase = atoi(argv[++i]); + break; + case 'z': + if (argv[i][3]) + zbase = atoi(argv[i] + 3); + else + zbase = atoi(argv[++i]); + break; + default: + printf("Unknown segment type '%c' - ignored!\n", argv[i][2]); + break; + } break; default: - printf("Unknown segment type '%c' - ignored!\n", argv[i][2]); + fprintf(stderr, "file65: %s unknown option, use '-h for help\n", + argv[i]); break; } - break; - default: - fprintf(stderr,"file65: %s unknown option, use '-h for help\n",argv[i]); - break; - } - i++; + i++; } // ------------------------------------------------------------------------- // step 1 - load files /* each file is loaded first */ - j=0; jm=0; fp=NULL; - while(i=jm) fp=realloc(fp, (jm=(jm?jm*2:10))*sizeof(file65*)); - if(!fp) { fprintf(stderr,"Oops, no more memory\n"); exit(1); } - fp[j++] = f; - } else { - exit(1); - } - i++; + j = 0; + jm = 0; + fp = NULL; + while (i < argc) { + file65 *f; + f = load_file(argv[i]); + if (f) { + if (j >= jm) + fp = realloc(fp, (jm = (jm ? jm * 2 : 10)) * sizeof(file65*)); + if (!fp) { + fprintf(stderr, "Oops, no more memory\n"); + exit(1); + } + fp[j++] = f; + } else { + exit(1); + } + i++; } // ------------------------------------------------------------------------- @@ -335,127 +354,137 @@ int main(int argc, char *argv[]) { maxalign = 0; alignfname = ""; { - int er = 0; - int trgcpu = 0; - if (verbose) { - printf("Starting CPU type calculation with mode %s (%d) ...\n", - cpunames[trgcpu], trgcpu); - } - for(i=0;ialign > maxalign) { - maxalign = file->align; - alignfname = file->fname; - } - if (file->mode & 0x8000) { - // 65816 - trgmode |= 0x8000; - if (trgcpu == 4) { - fprintf(stderr, "Error: file '%s' in 65816 CPU mode is incompatible with previous NMOS undocumented opcodes CPU mode\n", - file->fname); - er = 1; - } - } - if (file->mode & 0x0200) { - // zero out bss - trgmode |= 0x0200; - } - // CPU bits - fcpu = (file->mode & FM_CPU2) >> 4; + int er = 0; + int trgcpu = 0; if (verbose) { - printf("Matching file %s with CPU %s (%d) to target %s (%d) ...\n", - file->fname, cpunames[fcpu], fcpu, cpunames[trgcpu], trgcpu); + printf("Starting CPU type calculation with mode %s (%d) ...\n", + cpunames[trgcpu], trgcpu); } - switch (fcpu) { - case 0x0: // bare minimum documented 6502 is just fine - break; + for (i = 0; i < j; i++) { + int fcpu; + file = fp[i]; + if (file->align > maxalign) { + maxalign = file->align; + alignfname = file->fname; + } + if (file->mode & 0x8000) { + // 65816 + trgmode |= 0x8000; + if (trgcpu == 4) { + fprintf(stderr, + "Error: file '%s' in 65816 CPU mode is incompatible with previous NMOS undocumented opcodes CPU mode\n", + file->fname); + er = 1; + } + } + if (file->mode & 0x0200) { + // zero out bss + trgmode |= 0x0200; + } + // CPU bits + fcpu = (file->mode & FM_CPU2) >> 4; + if (verbose) { + printf( + "Matching file %s with CPU %s (%d) to target %s (%d) ...\n", + file->fname, cpunames[fcpu], fcpu, cpunames[trgcpu], + trgcpu); + } + switch (fcpu) { + case 0x0: // bare minimum documented 6502 is just fine + break; - case 0x1: // 65C02 - CMOS with BBR/BBS/RMB/SMB, incompatible with 65816 - case 0x3: // 65CE02 - CMOS with BBR/... and add'l opcodes, incompatible w/ 65816 - if (trgmode & 0x8000 || trgcpu == 5) { - fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) " - "is incompatible with previous 65816 CPU mode\n", - file->fname, fcpu, cpunames[fcpu]); - er = 1; - } - // fall-through - case 0x2: // 65SC02 - CMOS without BBR/BBS/RMB/SMB, compatible with 65816 - if (trgcpu == 4) { - // is incompatible with nmos6502 with undocumented opcodes - fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) " - "is incompatible with previous files with mode %d (%s)\n", - file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]); - er = 1; - } - break; + case 0x1: // 65C02 - CMOS with BBR/BBS/RMB/SMB, incompatible with 65816 + case 0x3: // 65CE02 - CMOS with BBR/... and add'l opcodes, incompatible w/ 65816 + if (trgmode & 0x8000 || trgcpu == 5) { + fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) " + "is incompatible with previous 65816 CPU mode\n", + file->fname, fcpu, cpunames[fcpu]); + er = 1; + } + // fall-through + case 0x2: // 65SC02 - CMOS without BBR/BBS/RMB/SMB, compatible with 65816 + if (trgcpu == 4) { + // is incompatible with nmos6502 with undocumented opcodes + fprintf(stderr, + "Error: file '%s' in CPU mode %d (%s) " + "is incompatible with previous files with mode %d (%s)\n", + file->fname, fcpu, cpunames[fcpu], trgcpu, + cpunames[trgcpu]); + er = 1; + } + break; - case 0x5: // 65816 in 6502 emulation mode - if (trgcpu == 1 || trgcpu == 3) { - // 65C02 and 65CE02 are incompatible with nmos6502 with undocumented opcodes - fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) is " - "incompatible with previous files with mode %d (%s)\n", - file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]); - er = 1; - } - break; + case 0x5: // 65816 in 6502 emulation mode + if (trgcpu == 1 || trgcpu == 3) { + // 65C02 and 65CE02 are incompatible with nmos6502 with undocumented opcodes + fprintf(stderr, + "Error: file '%s' in CPU mode %d (%s) is " + "incompatible with previous files with mode %d (%s)\n", + file->fname, fcpu, cpunames[fcpu], trgcpu, + cpunames[trgcpu]); + er = 1; + } + break; - case 0x4: // NMOS 6502 with undocumented opcodes - if (trgcpu == 1 || trgcpu == 2 || trgcpu == 3 || trgcpu == 5) { - // is incompatible with nmos6502 with undocumented opcodes - fprintf(stderr, "Error: file '%s' in CPU mode %d (%s) is " - "incompatible with previous files with mode %d (%s)\n", - file->fname, fcpu, cpunames[fcpu], trgcpu, cpunames[trgcpu]); - er = 1; + case 0x4: // NMOS 6502 with undocumented opcodes + if (trgcpu == 1 || trgcpu == 2 || trgcpu == 3 || trgcpu == 5) { + // is incompatible with nmos6502 with undocumented opcodes + fprintf(stderr, + "Error: file '%s' in CPU mode %d (%s) is " + "incompatible with previous files with mode %d (%s)\n", + file->fname, fcpu, cpunames[fcpu], trgcpu, + cpunames[trgcpu]); + er = 1; + } + if (trgmode & 0x8000) { + fprintf(stderr, + "Error: file '%s' in mode %d (%s) is incompatible with previous 65816 CPU mode\n", + file->fname, 4, cpunames[4]); + er = 1; + } + break; + default: + if (fcpu > 5) { + printf( + "Warning: unknown CPU mode %d (%s) detected in file %s\n", + fcpu, cpunames[fcpu], file->fname); + } + break; } - if (trgmode & 0x8000) { - fprintf(stderr, "Error: file '%s' in mode %d (%s) is incompatible with previous 65816 CPU mode\n", - file->fname, 4, cpunames[4]); - er = 1; + // setting the new mode + switch (fcpu) { + case 0x0: // compatible with everything, no change + break; + case 0x3: // 65CE02 -> supersedes 6502, 65SC02, and 65C02 + if (trgcpu == 1) { + // 65C02 + trgcpu = fcpu; + } + // fall-through + case 0x5: // 65816 in 6502 emu mode, supersedes documented NMOS and 65SC02 + case 0x1:// CMOS w/ BBR.. -> supersedes documented NMOS and 65SC02 + if (trgcpu == 2) { + // 65SC02 + trgcpu = fcpu; + } + // fall-through + case 0x2: // 65SC02 -> supersedes only NMOS 6502 + case 0x4: // NMOS 6502 w/ undocumented opcodes + default: + if (trgcpu == 0) { + // NMOS 6502 + trgcpu = fcpu; + } + break; } - break; - default: - if (fcpu > 5) { - printf("Warning: unknown CPU mode %d (%s) detected in file %s\n", - fcpu, cpunames[fcpu], file->fname); + if (verbose && !er) { + printf("... to new target %s (%d)\n", cpunames[trgcpu], trgcpu); } - break; } - // setting the new mode - switch (fcpu) { - case 0x0: // compatible with everything, no change - break; - case 0x3: // 65CE02 -> supersedes 6502, 65SC02, and 65C02 - if (trgcpu == 1) { - // 65C02 - trgcpu = fcpu; - } - // fall-through - case 0x5: // 65816 in 6502 emu mode, supersedes documented NMOS and 65SC02 - case 0x1: // CMOS w/ BBR.. -> supersedes documented NMOS and 65SC02 - if (trgcpu == 2) { - // 65SC02 - trgcpu = fcpu; - } - // fall-through - case 0x2: // 65SC02 -> supersedes only NMOS 6502 - case 0x4: // NMOS 6502 w/ undocumented opcodes - default: - if (trgcpu == 0) { - // NMOS 6502 - trgcpu = fcpu; - } - break; + if (er) { + exit(1); } - if (verbose && !er) { - printf("... to new target %s (%d)\n", - cpunames[trgcpu], trgcpu); - } - } - if (er) { - exit(1); - } - trgmode |= trgcpu << 4; + trgmode |= trgcpu << 4; } if (maxalign) { printf("Info: Alignment at %d-boundaries required\n", maxalign + 1); @@ -474,7 +503,6 @@ int main(int argc, char *argv[]) { break; } - // ------------------------------------------------------------------------- // step 2 - calculate new segment base addresses per file, by // concatenating the segments per type @@ -483,27 +511,26 @@ int main(int argc, char *argv[]) { /* set total length to zero */ ttlen = tdlen = tblen = tzlen = 0; - // then check start addresses file = fp[0]; if (file->align != 0) { int er = 0; if (tbase & file->align) { fprintf(stderr, "Error: text segment start address ($%04x) " - "not aligned as required by first file (at %d bytes)\n", - tbase, file->align + 1); + "not aligned as required by first file (at %d bytes)\n", + tbase, file->align + 1); er = 1; } if (dbase & file->align) { fprintf(stderr, "Error: data segment start address ($%04x) " - "not aligned as required by first file (at %d bytes)\n", - dbase, file->align + 1); + "not aligned as required by first file (at %d bytes)\n", + dbase, file->align + 1); er = 1; } if (bbase & file->align) { fprintf(stderr, "Error: bss segment start address ($%04x) " - "not aligned as required (by first file at %d bytes)\n", - bbase, file->align + 1); + "not aligned as required (by first file at %d bytes)\n", + bbase, file->align + 1); er = 1; } if (er) { @@ -512,65 +539,74 @@ int main(int argc, char *argv[]) { } /* find new addresses for the files and read globals */ - for(i=0;italign = 0; - file->dalign = 0; - file->balign = 0; - // filler only needed if align not zero ... - if (file->align) { - // ... and respective segment not empty - if (file->tlen) { - //file->talign = file->align + 1 - ((tbase + ttlen) & file->align); - file->talign = ( -((tbase + ttlen) & file->align) ) & file->align; + /* compute align fillers */ + file->talign = 0; + file->dalign = 0; + file->balign = 0; + // filler only needed if align not zero ... + if (file->align) { + // ... and respective segment not empty + if (file->tlen) { + //file->talign = file->align + 1 - ((tbase + ttlen) & file->align); + file->talign = (-((tbase + ttlen) & file->align)) & file->align; + } + if (file->dlen) { + //file->dalign = file->align + 1 - ((dbase + tdlen) & file->align); + file->dalign = (-((dbase + tdlen) & file->align)) & file->align; + } + if (file->blen) { + //file->balign = file->align + 1 - ((bbase + tblen) & file->align); + file->balign = (-((bbase + tblen) & file->align)) & file->align; + } } - if (file->dlen) { - //file->dalign = file->align + 1 - ((dbase + tdlen) & file->align); - file->dalign = ( -((dbase + tdlen) & file->align) ) & file->align; + + /* insert align fillers */ + ttlen += file->talign; + tdlen += file->dalign; + tblen += file->balign; + + /* compute relocation differences */ + file->tdiff = ((tbase + ttlen) - file->tbase); + file->ddiff = ((dbase + tdlen) - file->dbase); + file->bdiff = ((bbase + tblen) - file->bbase); + file->zdiff = ((zbase + tzlen) - file->zbase); + + /* + printf("tbase=%04x+len=%04x->%04x, file->tbase=%04x, f.tlen=%04x -> tdiff=%04x\n", + tbase, ttlen, (tbase + ttlen), file->tbase, file->tlen, file->tdiff); + printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n", + zbase, tzlen, (zbase + tzlen), file->zbase, file->zlen, file->zdiff); + */ + + if (verbose > 0) { + printf("Relocating file: %s [CPU %s]\n", file->fname, + cpunames[((file->mode & FM_CPU2) >> 4) & 0x0f]); + printf( + " text: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n", + file->talign, file->tbase, file->tbase + file->tdiff, + file->tdiff, file->tlen); + printf( + " data: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n", + file->dalign, file->dbase, file->dbase + file->ddiff, + file->ddiff, file->dlen); + printf( + " bss: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n", + file->balign, file->bbase, file->bbase + file->bdiff, + file->bdiff, file->blen); + printf( + " zero: relocate from %02x to %02x (diff is %02x, length is %02x)\n", + file->zbase, file->zbase + file->zdiff, file->zdiff, + file->zlen); } - if (file->blen) { - //file->balign = file->align + 1 - ((bbase + tblen) & file->align); - file->balign = ( -((bbase + tblen) & file->align) ) & file->align; - } - } - /* insert align fillers */ - ttlen += file->talign; - tdlen += file->dalign; - tblen += file->balign; - - /* compute relocation differences */ - file->tdiff = ((tbase + ttlen) - file->tbase); - file->ddiff = ((dbase + tdlen) - file->dbase); - file->bdiff = ((bbase + tblen) - file->bbase); - file->zdiff = ((zbase + tzlen) - file->zbase); - -/* -printf("tbase=%04x+len=%04x->%04x, file->tbase=%04x, f.tlen=%04x -> tdiff=%04x\n", - tbase, ttlen, (tbase + ttlen), file->tbase, file->tlen, file->tdiff); -printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n", - zbase, tzlen, (zbase + tzlen), file->zbase, file->zlen, file->zdiff); -*/ - - if (verbose > 0) { - printf("Relocating file: %s [CPU %s]\n", file->fname, cpunames[((file->mode & FM_CPU2) >> 4) & 0x0f]); - printf(" text: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n", - file->talign, file->tbase, file->tbase + file->tdiff, file->tdiff, file->tlen); - printf(" data: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n", - file->dalign, file->dbase, file->dbase + file->ddiff, file->ddiff, file->dlen); - printf(" bss: align fill %04x, relocate from %04x to %04x (diff is %04x, length is %04x)\n", - file->balign, file->bbase, file->bbase + file->bdiff, file->bdiff, file->blen); - printf(" zero: relocate from %02x to %02x (diff is %02x, length is %02x)\n", - file->zbase, file->zbase + file->zdiff, file->zdiff, file->zlen); - } - - /* update globals (for result file) */ - ttlen += file->tlen; - tdlen += file->dlen; - tblen += file->blen; - tzlen += file->zlen; + /* update globals (for result file) */ + ttlen += file->tlen; + tdlen += file->dlen; + tblen += file->blen; + tzlen += file->zlen; } // validate various situations. @@ -578,20 +614,20 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n int er = 0; if (tbase & maxalign) { fprintf(stderr, "Error: text segment start address ($%04x) " - "not aligned as first required by file %s (at %d bytes)\n", - tbase, alignfname, maxalign + 1); + "not aligned as first required by file %s (at %d bytes)\n", + tbase, alignfname, maxalign + 1); er = 1; } if (dbase & maxalign) { fprintf(stderr, "Error: data segment start address ($%04x) " - "not aligned as first required by file %s (at %d bytes)\n", - dbase, alignfname, maxalign + 1); + "not aligned as first required by file %s (at %d bytes)\n", + dbase, alignfname, maxalign + 1); er = 1; } if (bbase & maxalign) { fprintf(stderr, "Error: bss segment start address ($%04x) " - "not aligned as first required (by file %s (at %d bytes)\n", - bbase, alignfname, maxalign + 1); + "not aligned as first required (by file %s (at %d bytes)\n", + bbase, alignfname, maxalign + 1); er = 1; } if (er) { @@ -603,30 +639,30 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n int er = 0; if (tbase + ttlen > 0x10000) { fprintf(stderr, - "Overflow in text segment: end at %06x behind 64k limit\n", - tbase + ttlen); + "Overflow in text segment: end at %06x behind 64k limit\n", + tbase + ttlen); er = 1; } if (dbase + tdlen > 0x10000) { fprintf(stderr, - "Overflow in data segment: end at %06x behind 64k limit\n", - dbase + tdlen); + "Overflow in data segment: end at %06x behind 64k limit\n", + dbase + tdlen); er = 1; } if (bbase + tblen > 0x10000) { fprintf(stderr, - "Overflow in bss segment: end at %06x behind 64k limit\n", - bbase + tblen); + "Overflow in bss segment: end at %06x behind 64k limit\n", + bbase + tblen); er = 1; } if (zbase + tzlen > 0x100) { fprintf(stderr, - "Overflow in zero segment: end at %04x behind 256 byte limit\n", - zbase + tzlen); + "Overflow in zero segment: end at %04x behind 256 byte limit\n", + zbase + tzlen); er = 1; } if (er) { - exit (1); + exit(1); } } @@ -634,22 +670,21 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n // step 3 - merge globals from all files into single table // - for(i=0;i%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n routtlen = 1; // end-of-table byte routdlen = 1; // end-of-table byte - for(i=0;idrpos - file->trpos); - routdlen += (file->gpos - file->drpos); + routtlen += (file->drpos - file->trpos); + routdlen += (file->gpos - file->drpos); - reloc_globals(file->buf+file->gpos, file); + reloc_globals(file->buf + file->gpos, file); } // prep global reloc tables @@ -685,34 +720,27 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n lasttaddr = tbase - 1; lastdaddr = dbase - 1; - for(i=0;ibuf, // input buffer - file->tpos, // position of segment in input buffer - file->tbase, // segment base address - file->tdiff, // reloc difference - file->trpos, // position of reloc table in input - treloc, // output reloc buffer - &lasttaddr, // last relocated target address - &tro, // pointer in output reloc bufer - file); + reloc_seg(file->buf, // input buffer + file->tpos, // position of segment in input buffer + file->tbase, // segment base address + file->tdiff, // reloc difference + file->trpos, // position of reloc table in input + treloc, // output reloc buffer + &lasttaddr, // last relocated target address + &tro, // pointer in output reloc bufer + file); - reloc_seg(file->buf, - file->dpos, - file->dbase, - file->ddiff, - file->drpos, - dreloc, - &lastdaddr, - &dro, - file); + reloc_seg(file->buf, file->dpos, file->dbase, file->ddiff, file->drpos, + dreloc, &lastdaddr, &dro, file); - // change file information to relocated values - file->tbase += file->tdiff; - file->dbase += file->ddiff; - file->bbase += file->bdiff; - file->zbase += file->zdiff; + // change file information to relocated values + file->tbase += file->tdiff; + file->dbase += file->ddiff; + file->bbase += file->bdiff; + file->zbase += file->zdiff; } // finalize global reloc table @@ -727,7 +755,7 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n int er = 0; // we have undefined labels, but it's not ok (no -U) // check -L defined labels - for(i=0;i%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n // // prepare header - hdr[ 6] = trgmode & 255; hdr[ 7] = (trgmode>>8)& 255; - hdr[ 8] = tbase & 255; hdr[ 9] = (tbase>>8) & 255; - hdr[10] = ttlen & 255; hdr[11] = (ttlen >>8)& 255; - hdr[12] = dbase & 255; hdr[13] = (dbase>>8) & 255; - hdr[14] = tdlen & 255; hdr[15] = (tdlen >>8)& 255; - hdr[16] = bbase & 255; hdr[17] = (bbase>>8) & 255; - hdr[18] = tblen & 255; hdr[19] = (tblen >>8)& 255; - hdr[20] = zbase & 255; hdr[21] = (zbase>>8) & 255; - hdr[22] = tzlen & 255; hdr[23] = (tzlen >>8)& 255; - hdr[24] = 0; hdr[25] = 0; + hdr[6] = trgmode & 255; + hdr[7] = (trgmode >> 8) & 255; + hdr[8] = tbase & 255; + hdr[9] = (tbase >> 8) & 255; + hdr[10] = ttlen & 255; + hdr[11] = (ttlen >> 8) & 255; + hdr[12] = dbase & 255; + hdr[13] = (dbase >> 8) & 255; + hdr[14] = tdlen & 255; + hdr[15] = (tdlen >> 8) & 255; + hdr[16] = bbase & 255; + hdr[17] = (bbase >> 8) & 255; + hdr[18] = tblen & 255; + hdr[19] = (tblen >> 8) & 255; + hdr[20] = zbase & 255; + hdr[21] = (zbase >> 8) & 255; + hdr[22] = tzlen & 255; + hdr[23] = (tzlen >> 8) & 255; + hdr[24] = 0; + hdr[25] = 0; // open file fd = fopen(outfile, "wb"); - if(!fd) { - fprintf(stderr,"Couldn't open output file %s (%s)\n", - outfile, strerror(errno)); - exit(2); + if (!fd) { + fprintf(stderr, "Couldn't open output file %s (%s)\n", outfile, + strerror(errno)); + exit(2); } // write header fwrite(hdr, 1, 26, fd); // write options - this writes _all_ options from _all_files! - for(i=0;italign) { - fwrite(alignbuf, 1, fp[i]->talign, fd); - } - fwrite(fp[i]->buf + fp[i]->tpos, 1, fp[i]->tlen, fd); + for (i = 0; i < j; i++) { + if (fp[i]->talign) { + fwrite(alignbuf, 1, fp[i]->talign, fd); + } + fwrite(fp[i]->buf + fp[i]->tpos, 1, fp[i]->tlen, fd); } // write data segment - for(i=0;idalign) { - fwrite(alignbuf, 1, fp[i]->dalign, fd); - } - fwrite(fp[i]->buf + fp[i]->dpos, 1, fp[i]->dlen, fd); + for (i = 0; i < j; i++) { + if (fp[i]->dalign) { + fwrite(alignbuf, 1, fp[i]->dalign, fd); + } + fwrite(fp[i]->buf + fp[i]->dpos, 1, fp[i]->dlen, fd); } // write list of undefined labels - fputc(nundef & 0xff,fd); - fputc((nundef >> 8) & 0xff,fd); + fputc(nundef & 0xff, fd); + fputc((nundef >> 8) & 0xff, fd); if (nundef > 0) { - for(i=0;i%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n fwrite(dreloc, dro, 1, fd); // write globals - if(!noglob) { - write_globals(fd); + if (!noglob) { + write_globals(fd); } else { - if (nglobal > 0) { - write_nglobals(fd, globdef, nglobal); - } else { - fputc(0,fd); - fputc(0,fd); - } + if (nglobal > 0) { + write_nglobals(fd, globdef, nglobal); + } else { + fputc(0, fd); + fputc(0, fd); + } } fclose(fd); @@ -822,17 +860,17 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n /***************************************************************************/ int write_options(FILE *fp, file65 *file) { - return fwrite(file->buf+BUF, 1, file->tpos-BUF-1, fp); + return fwrite(file->buf + BUF, 1, file->tpos - BUF - 1, fp); } int read_options(unsigned char *buf) { - int c, l=0; + int c, l = 0; - c=buf[0]; - while(c && c!=EOF) { - c&=255; - l+=c; - c=buf[l]; + c = buf[0]; + while (c && c != EOF) { + c &= 255; + l += c; + c = buf[l]; } return ++l; } @@ -847,32 +885,33 @@ int read_undef(unsigned char *buf, file65 *file) { int i; bufp = 0; - nlabels = buf[bufp] + 256*buf[bufp+1]; + nlabels = buf[bufp] + 256 * buf[bufp + 1]; bufp += 2; file->nundef = nlabels; if (nlabels == 0) { file->ud = NULL; - } else { - file->ud = malloc(nlabels*sizeof(undefs)); - if(!file->ud) { - fprintf(stderr,"Oops, no more memory\n"); - exit(1); + } else { + file->ud = malloc(nlabels * sizeof(undefs)); + if (!file->ud) { + fprintf(stderr, "Oops, no more memory\n"); + exit(1); } - i=0; - while(iud[i]; - current->name = (char*) buf+startp; - current->len = bufp-startp-1; - current->resolved = -1; -/*printf("read undef '%s'(%p), len=%d, ll=%d, l=%d, buf[l]=%d\n", - file->ud[i].name, file->ud[i].name, file->ud[i].len,ll,l,buf[l]);*/ - i++; + i = 0; + while (i < nlabels) { + // find length of label name + startp = bufp; + while (buf[bufp++]) + ; + // store label info + current = &file->ud[i]; + current->name = (char*) buf + startp; + current->len = bufp - startp - 1; + current->resolved = -1; + /*printf("read undef '%s'(%p), len=%d, ll=%d, l=%d, buf[l]=%d\n", + file->ud[i].name, file->ud[i].name, file->ud[i].len,ll,l,buf[l]);*/ + i++; } } return bufp; @@ -907,7 +946,6 @@ printf("resolved undef label %s to: resolved=%d, newidx=%d\n", current->name, cu return 0; } - int write_undef(FILE *f, file65 *fp) { int i; for (i = 0; i < fp->nundef; i++) { @@ -939,8 +977,8 @@ int check_undef(file65 *fp, char *defined[], int ndefined) { } } if (!found) { - fprintf(stderr, "Unresolved label '%s' from file '%s'\n", - current->name, fp->fname); + fprintf(stderr, "Unresolved label '%s' from file '%s'\n", + current->name, fp->fname); er = -1; } } @@ -948,67 +986,68 @@ int check_undef(file65 *fp, char *defined[], int ndefined) { return er; } - /***************************************************************************/ /* compute and return the length of the relocation table */ int len_reloc_seg(unsigned char *buf, int ri) { int type, seg; - while(buf[ri]) { - if((buf[ri] & 255) == 255) { - ri++; - } else { - ri++; - type = buf[ri] & 0xe0; - seg = buf[ri] & 0x07; -/*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",buf+ri-1, *(buf+ri-1), adr, type, seg);*/ - ri++; - switch(type) { - case 0x80: - break; - case 0x40: - ri++; - break; - case 0x20: - break; - } - if(seg==0) ri+=2; - } + while (buf[ri]) { + if ((buf[ri] & 255) == 255) { + ri++; + } else { + ri++; + type = buf[ri] & 0xe0; + seg = buf[ri] & 0x07; + /*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",buf+ri-1, *(buf+ri-1), adr, type, seg);*/ + ri++; + switch (type) { + case 0x80: + break; + case 0x40: + ri++; + break; + case 0x20: + break; + } + if (seg == 0) + ri += 2; + } } return ++ri; } #define reldiff(s) (((s)==2)?fp->tdiff:(((s)==3)?fp->ddiff:(((s)==4)?fp->bdiff:(((s)==5)?fp->zdiff:0)))) -unsigned char *reloc_globals(unsigned char *buf, file65 *fp) { +unsigned char* reloc_globals(unsigned char *buf, file65 *fp) { int n, old, new, seg; char *name; - n = buf[0] + 256*buf[1]; - buf +=2; + n = buf[0] + 256 * buf[1]; + buf += 2; - while(n) { - name = buf; - while(*(buf++)); - seg = *buf & 0x07; - old = buf[1] + 256*buf[2]; - new = old + reldiff(seg); - if (verbose > 1) { - printf("%s:%s: old=%04x, seg=%d, rel=%04x, new=%04x\n", - fp->fname, name, old, seg, reldiff(seg), new); - } - buf[1] = new & 255; - buf[2] = (new>>8) & 255; - buf +=3; - n--; + while (n) { + name = buf; + while (*(buf++)) + ; + seg = *buf & 0x07; + old = buf[1] + 256 * buf[2]; + new = old + reldiff(seg); + if (verbose > 1) { + printf("%s:%s: old=%04x, seg=%d, rel=%04x, new=%04x\n", fp->fname, + name, old, seg, reldiff(seg), new); + } + buf[1] = new & 255; + buf[2] = (new >> 8) & 255; + buf += 3; + n--; } return buf; } /***************************************************************************/ -file65 *load_file(char *fname) { +file65* load_file(char *fname) { file65 *file; struct stat fs; FILE *fp; @@ -1016,91 +1055,97 @@ file65 *load_file(char *fname) { int align; size_t n; - file=malloc(sizeof(file65)); - if(!file) { - fprintf(stderr,"Oops, not enough memory!\n"); - exit(1); + file = malloc(sizeof(file65)); + if (!file) { + fprintf(stderr, "Oops, not enough memory!\n"); + exit(1); } -/*printf("load_file(%s)\n",fname);*/ + /*printf("load_file(%s)\n",fname);*/ - file->fname=fname; - if(stat(fname, &fs) < 0) { - perror("while opening file: stat"); - exit(1); + file->fname = fname; + if (stat(fname, &fs) < 0) { + perror("while opening file: stat"); + exit(1); } - file->fsize=fs.st_size; - file->buf=malloc(file->fsize); - if(!file->buf) { - fprintf(stderr,"Oops, no more memory!\n"); - exit(1); + file->fsize = fs.st_size; + file->buf = malloc(file->fsize); + if (!file->buf) { + fprintf(stderr, "Oops, no more memory!\n"); + exit(1); } - fp = fopen(fname,"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]; - file->mode = mode; - if(mode & 0x2000) { - fprintf(stderr,"file65: %s: 32 bit size not supported\n", fname); - free(file->buf); free(file); file=NULL; - } else - if(mode & 0x4000) { - fprintf(stderr,"file65: %s: pagewise relocation not supported\n", - fname); - free(file->buf); free(file); file=NULL; - } else { + fp = fopen(fname, "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]; + file->mode = mode; + if (mode & 0x2000) { + fprintf(stderr, "file65: %s: 32 bit size not supported\n", + fname); + free(file->buf); + free(file); + file = NULL; + } else if (mode & 0x4000) { + fprintf(stderr, + "file65: %s: pagewise relocation not supported\n", + fname); + free(file->buf); + free(file); + file = NULL; + } else { - align = mode & 3; - switch(align) { - case 0: - align = 0; - break; - case 1: - // word align - align = 1; - break; - case 2: - // long align - align = 3; - break; - case 3: - // page align - align = 255; - break; - } - file->align = align; + align = mode & 3; + switch (align) { + case 0: + align = 0; + break; + case 1: + // word align + align = 1; + break; + case 2: + // long align + align = 3; + break; + case 3: + // page align + align = 255; + break; + } + file->align = align; - hlen = BUF+read_options(file->buf+BUF); - - file->tbase = file->buf[ 9]*256+file->buf[ 8]; - file->tlen = file->buf[11]*256+file->buf[10]; - file->talign= 0; - file->dbase = file->buf[13]*256+file->buf[12]; - file->dlen = file->buf[15]*256+file->buf[14]; - file->dalign= 0; - file->bbase = file->buf[17]*256+file->buf[16]; - file->blen = file->buf[19]*256+file->buf[18]; - file->balign= 0; - file->zbase = file->buf[21]*256+file->buf[20]; - file->zlen = file->buf[23]*256+file->buf[22]; + hlen = BUF + read_options(file->buf + BUF); - file->tpos = hlen; - file->dpos = hlen + file->tlen; - file->upos = file->dpos + file->dlen; - file->trpos= file->upos + read_undef(file->buf+file->upos, file); - file->drpos= len_reloc_seg(file->buf, file->trpos); - file->gpos = len_reloc_seg(file->buf, file->drpos); - } - } else { - fprintf(stderr,"Error: %s: not an o65 file\n", fname); - return NULL; - } + file->tbase = file->buf[9] * 256 + file->buf[8]; + file->tlen = file->buf[11] * 256 + file->buf[10]; + file->talign = 0; + file->dbase = file->buf[13] * 256 + file->buf[12]; + file->dlen = file->buf[15] * 256 + file->buf[14]; + file->dalign = 0; + file->bbase = file->buf[17] * 256 + file->buf[16]; + file->blen = file->buf[19] * 256 + file->buf[18]; + file->balign = 0; + file->zbase = file->buf[21] * 256 + file->buf[20]; + file->zlen = file->buf[23] * 256 + file->buf[22]; + + file->tpos = hlen; + file->dpos = hlen + file->tlen; + file->upos = file->dpos + file->dlen; + file->trpos = file->upos + + read_undef(file->buf + file->upos, file); + file->drpos = len_reloc_seg(file->buf, file->trpos); + file->gpos = len_reloc_seg(file->buf, file->drpos); + } + } else { + fprintf(stderr, "Error: %s: not an o65 file\n", fname); + return NULL; + } } else { - fprintf(stderr,"file65: %s: %s\n", fname, strerror(errno)); - return NULL; + fprintf(stderr, "file65: %s: %s\n", fname, strerror(errno)); + return NULL; } return file; } @@ -1110,20 +1155,19 @@ file65 *load_file(char *fname) { // global list of all global labels glob *gp = NULL; // number of global labels -int g=0; +int g = 0; // number of globals for which memory is already allocated -int gm=0; - +int gm = 0; int write_globals(FILE *fp) { int i; - fputc(g&255, fp); - fputc((g>>8)&255, fp); + fputc(g & 255, fp); + fputc((g >> 8) & 255, fp); - for(i=0;i>8)&255); + for (i = 0; i < g; i++) { + fprintf(fp, "%s%c%c%c%c", gp[i].name, 0, gp[i].seg, gp[i].val & 255, + (gp[i].val >> 8) & 255); } return 0; } @@ -1160,18 +1204,20 @@ int write_nglobals(FILE *fp, char **globdef, int nglobal) { } if (i >= g) { // not found - fprintf(stderr,"Warning: command line allowed global '%s' is not defined!\n", globdef[j]); + fprintf(stderr, + "Warning: command line allowed global '%s' is not defined!\n", + globdef[j]); } } // write out only defined globals - fputc(newnum&255, fp); - fputc((newnum>>8)&255, fp); + fputc(newnum & 255, fp); + fputc((newnum >> 8) & 255, fp); - for(i=0;i>8)&255); + fprintf(fp, "%s%c%c%c%c", gp[i].name, 0, gp[i].seg, gp[i].val & 255, + (gp[i].val >> 8) & 255); } } return 0; @@ -1182,58 +1228,61 @@ int read_globals(file65 *fp) { char *name; unsigned char *buf = fp->buf + fp->gpos; - n = buf[0] + 256*buf[1]; - buf +=2; + n = buf[0] + 256 * buf[1]; + buf += 2; - while(n) { -/*printf("reading %s, ", buf);*/ - name = (char*) buf; - l=0; - while(buf[l++]); - buf+=l; - ll=l-1; - seg = *buf; - old = buf[1] + 256*buf[2]; - new = old + reldiff(seg); -/*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ + while (n) { + /*printf("reading %s, ", buf);*/ + name = (char*) buf; + l = 0; + while (buf[l++]) + ; + buf += l; + ll = l - 1; + seg = *buf; + old = buf[1] + 256 * buf[2]; + new = old + reldiff(seg); + /*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ - /* multiply defined? */ - for(i=0;ifname, gp[i].file->fname); - gp[i].fl = 1; - break; - } - } - /* not already defined */ - if(i>=g) { - if(g>=gm) { - gp = realloc(gp, (gm=(gm?2*gm:40))*sizeof(glob)); - if(!gp) { - fprintf(stderr,"Oops, no more memory\n"); - exit(1); - } - } - if(g>=0x10000) { - fprintf(stderr,"Outch, maximum number of labels (65536) exceeded!\n"); - exit(3); - } - gp[g].name = name; - gp[g].len = ll; - gp[g].seg = seg; - gp[g].val = new; - gp[g].fl = 0; - gp[g].file = fp; + /* multiply defined? */ + for (i = 0; i < g; i++) { + if (ll == gp[i].len && !strcmp(name, gp[i].name)) { + fprintf(stderr, + "Warning: label '%s' multiply defined (%s and %s)\n", + name, fp->fname, gp[i].file->fname); + gp[i].fl = 1; + break; + } + } + /* not already defined */ + if (i >= g) { + if (g >= gm) { + gp = realloc(gp, (gm = (gm ? 2 * gm : 40)) * sizeof(glob)); + if (!gp) { + fprintf(stderr, "Oops, no more memory\n"); + exit(1); + } + } + if (g >= 0x10000) { + fprintf(stderr, + "Outch, maximum number of labels (65536) exceeded!\n"); + exit(3); + } + gp[g].name = name; + gp[g].len = ll; + gp[g].seg = seg; + gp[g].val = new; + gp[g].fl = 0; + gp[g].file = fp; #ifdef DEBUG printf("set global label '%s' (l=%d, seg=%d, val=%04x)\n", gp[g].name, gp[g].len, gp[g].seg, gp[g].val); #endif - g++; - } + g++; + } - buf +=3; - n--; + buf += 3; + n--; } return 0; } @@ -1253,24 +1302,24 @@ int find_global(unsigned char *name) { // searches for a global label in a file by name. // returns the value of a found global value int find_file_global(unsigned char *bp, file65 *fp, int *seg) { - int i,l; + int i, l; char *n; - int nl = bp[0]+256*bp[1]; + int nl = bp[0] + 256 * bp[1]; - l=fp->ud[nl].len; - n=fp->ud[nl].name; -/*printf("find_global(%s (len=%d))\n",n,l);*/ + l = fp->ud[nl].len; + n = fp->ud[nl].name; + /*printf("find_global(%s (len=%d))\n",n,l);*/ - for(i=0;i>8) & 255; -/*printf("return gp[%d]=%s (len=%d), val=%04x\n",i,gp[i].name,gp[i].len,gp[i].val);*/ - return gp[i].val; - } + for (i = 0; i < g; i++) { + if (gp[i].len == l && !strcmp(gp[i].name, n)) { + *seg = gp[i].seg; + bp[0] = i & 255; + bp[1] = (i >> 8) & 255; + /*printf("return gp[%d]=%s (len=%d), val=%04x\n",i,gp[i].name,gp[i].len,gp[i].val);*/ + return gp[i].val; + } } - fprintf(stderr,"Warning: undefined label '%s' in file %s\n", - n, fp->fname); + fprintf(stderr, "Warning: undefined label '%s' in file %s\n", n, fp->fname); return 0; } @@ -1285,10 +1334,10 @@ int reloc_seg(unsigned char *buf, int pos, int addr, int rdiff, int ri, int base; /* - pos = address of current position - ri = position of relocation table in *buf for reading the reloc entries - ro(p) = position of relocation table entry for writing the modified entries - */ + pos = address of current position + ri = position of relocation table in *buf for reading the reloc entries + ro(p) = position of relocation table entry for writing the modified entries + */ base = addr; addr--; ro = *rop; @@ -1299,152 +1348,150 @@ printf("reloc_seg: %s: addr=%04x, pos=%04x, lastaddr=%04x (%04x - %04x)\n", fp->fname, addr, pos, lastaddr, *lastaddrp, rdiff); #endif - while(buf[ri]) { - // still reloc entry - if((buf[ri] & 255) == 255) { - addr += 254; - ri++; - } else { - addr += buf[ri] & 255; - type = buf[ri+1] & 0xe0; - seg = buf[ri+1] & 0x07; + while (buf[ri]) { + // still reloc entry + if ((buf[ri] & 255) == 255) { + addr += 254; + ri++; + } else { + addr += buf[ri] & 255; + type = buf[ri + 1] & 0xe0; + seg = buf[ri + 1] & 0x07; #ifdef DEBUG printf("reloc entry @ ri=%04x, pos=%04x, type=%02x, seg=%d, offset=%d, reldiff=%04x\n", ri, pos, type, seg, addr-lastaddr, reldiff(seg)); #endif - switch(type) { - case 0x80: - // address (word) relocation - old = buf[addr-base+pos] + 256*buf[addr-base+pos+1]; - if(seg) { - diff = reldiff(seg); - ri++; // skip position byte - forwardpos(); // re-write position offset - obuf[ro++] = buf[ri++]; // relocation byte ($8x for segments text, data, bss, zp) - } else { - // undefined - undefs *u = &fp->ud[buf[ri+2]+256*buf[ri+3]]; + switch (type) { + case 0x80: + // address (word) relocation + old = buf[addr - base + pos] + 256 * buf[addr - base + pos + 1]; + if (seg) { + diff = reldiff(seg); + ri++; // skip position byte + forwardpos(); // re-write position offset + obuf[ro++] = buf[ri++]; // relocation byte ($8x for segments text, data, bss, zp) + } else { + // undefined + undefs *u = &fp->ud[buf[ri + 2] + 256 * buf[ri + 3]]; #ifdef DEBUG printf("found undef'd label %s, resolved=%d, newidx=%d, (ri=%d, ro=%d)\n", u->name, u->resolved, u->newidx, ri, ro); #endif - if (u->resolved == -1) { - // not resolved - diff = 0; - ri++; // skip position byte - forwardpos(); // re-write position offset - obuf[ro++] = buf[ri++]; // relocation byte ($8x for segments text, data, bss, zp) - obuf[ro++] = u->newidx & 0xff; // output label number lo/hi - obuf[ro++] = (u->newidx >> 8) & 0xff; - ri += 2; // acount for label number in input - } else { - // resolved from global list - glob *gl = &gp[u->resolved]; - diff = gl->val; - seg = gl->seg; - if (seg != 1) { - // not an absolute value - forwardpos(); // re-write position offset - obuf[ro++] = 0x80 | seg;// relocation byte for new segment - } else { - // absolute value - do not write a new relocation entry + if (u->resolved == -1) { + // not resolved + diff = 0; + ri++; // skip position byte + forwardpos(); // re-write position offset + obuf[ro++] = buf[ri++]; // relocation byte ($8x for segments text, data, bss, zp) + obuf[ro++] = u->newidx & 0xff;// output label number lo/hi + obuf[ro++] = (u->newidx >> 8) & 0xff; + ri += 2; // acount for label number in input + } else { + // resolved from global list + glob *gl = &gp[u->resolved]; + diff = gl->val; + seg = gl->seg; + if (seg != 1) { + // not an absolute value + forwardpos(); // re-write position offset + obuf[ro++] = 0x80 | seg;// relocation byte for new segment + } else { + // absolute value - do not write a new relocation entry + } + ri += 4;// account for position, segment byte, label number in reloc table + } } - ri += 4; // account for position, segment byte, label number in reloc table + new = old + diff; + /*printf("old=%04x, new=%04x\n",old,new);*/ + buf[addr - base + pos] = new & 255; + buf[addr - base + pos + 1] = (new >> 8) & 255; + break; + case 0x40: + // high byte relocation + if (seg) { + old = buf[addr - base + pos] * 256 + buf[ri + 2]; + diff = reldiff(seg); + forwardpos(); // re-write position offset + obuf[ro++] = buf[ri + 1];// relocation byte ($4x for segments text, data, bss, zp) + obuf[ro++] = (old + diff) & 255; + ri += 3; // skip position, segment, and low byte + } else { + undefs *u; + old = buf[addr - base + pos] * 256 + buf[ri + 4]; + // undefined + u = &fp->ud[buf[ri + 2] + 256 * buf[ri + 3]]; + if (u->resolved == -1) { + // not resolved + diff = 0; + forwardpos(); // re-write position offset + obuf[ro++] = buf[ri + 1];// relocation byte ($8x for segments text, data, bss, zp) + obuf[ro++] = u->newidx & 0xff;// output label number lo/hi + obuf[ro++] = (u->newidx >> 8) & 0xff; + obuf[ro++] = buf[ri + 4]; // low byte for relocation + } else { + // resolved from global list + glob *gl = &gp[u->resolved]; + diff = gl->val; + seg = gl->seg; + if (seg != 1) { + // not an absolute value + forwardpos(); // re-write position offset + obuf[ro++] = 0x40 | seg;// relocation byte for new segment + obuf[ro++] = (old + diff) & 0xff;// low byte for relocation + } else { + // absolute value - do not write a new relocation entry + } + } + ri += 5; // account for position, segment byte, label number in reloc table, low byte + } + new = old + diff; + buf[addr - base + pos] = (new >> 8) & 255; + break; + case 0x20: + // low byte relocation + old = buf[addr - base + pos]; + diff = 0; + if (seg) { + diff = reldiff(seg); + forwardpos(); + obuf[ro++] = buf[ri + 1];// relocation byte ($4x for segments text, data, bss, zp) + ri += 2; // account for position & segment + } else { + // undefined + undefs *u = &fp->ud[buf[ri + 2] + 256 * buf[ri + 3]]; + if (u->resolved == -1) { + // not resolved + diff = 0; + forwardpos(); // re-write position offset + obuf[ro++] = buf[ri + 1];// relocation byte ($8x for segments text, data, bss, zp) + obuf[ro++] = u->newidx & 0xff;// output label number lo/hi + obuf[ro++] = (u->newidx >> 8) & 0xff; + } else { + // resolved from global list + glob *gl = &gp[u->resolved]; + diff = gl->val; + seg = gl->seg; + if (seg != 1) { + // not an absolute value + forwardpos(); // re-write position offset + obuf[ro++] = 0x20 | seg;// relocation byte for new segment + } else { + // absolute value - do not write a new relocation entry + } + } + ri += 4;// account for position, segment byte, label number in reloc table + } + new = old + diff; + buf[addr - base + pos] = new & 255; + break; } } - new = old + diff; -/*printf("old=%04x, new=%04x\n",old,new);*/ - buf[addr-base+pos] = new & 255; - buf[addr-base+pos+1] = (new>>8)&255; - break; - case 0x40: - // high byte relocation - if(seg) { - old = buf[addr-base+pos]*256 + buf[ri+2]; - diff = reldiff(seg); - forwardpos(); // re-write position offset - obuf[ro++] = buf[ri+1]; // relocation byte ($4x for segments text, data, bss, zp) - obuf[ro++] = (old + diff) & 255; - ri += 3; // skip position, segment, and low byte - } else { - undefs *u; - old = buf[addr-base+pos]*256 + buf[ri+4]; - // undefined - u = &fp->ud[buf[ri+2]+256*buf[ri+3]]; - if (u->resolved == -1) { - // not resolved - diff = 0; - forwardpos(); // re-write position offset - obuf[ro++] = buf[ri+1]; // relocation byte ($8x for segments text, data, bss, zp) - obuf[ro++] = u->newidx & 0xff; // output label number lo/hi - obuf[ro++] = (u->newidx >> 8) & 0xff; - obuf[ro++] = buf[ri+4]; // low byte for relocation - } else { - // resolved from global list - glob *gl = &gp[u->resolved]; - diff = gl->val; - seg = gl->seg; - if (seg != 1) { - // not an absolute value - forwardpos(); // re-write position offset - obuf[ro++] = 0x40 | seg; // relocation byte for new segment - obuf[ro++] = (old + diff) & 0xff; // low byte for relocation - } else { - // absolute value - do not write a new relocation entry - } - } - ri += 5; // account for position, segment byte, label number in reloc table, low byte - } - new = old + diff; - buf[addr-base+pos] = (new>>8)&255; - break; - case 0x20: - // low byte relocation - old = buf[addr-base+pos]; - diff = 0; - if(seg) { - diff = reldiff(seg); - forwardpos(); - obuf[ro++] = buf[ri+1]; // relocation byte ($4x for segments text, data, bss, zp) - ri += 2; // account for position & segment - } else { - // undefined - undefs *u = &fp->ud[buf[ri+2]+256*buf[ri+3]]; - if (u->resolved == -1) { - // not resolved - diff = 0; - forwardpos(); // re-write position offset - obuf[ro++] = buf[ri+1]; // relocation byte ($8x for segments text, data, bss, zp) - obuf[ro++] = u->newidx & 0xff; // output label number lo/hi - obuf[ro++] = (u->newidx >> 8) & 0xff; - } else { - // resolved from global list - glob *gl = &gp[u->resolved]; - diff = gl->val; - seg = gl->seg; - if (seg != 1) { - // not an absolute value - forwardpos(); // re-write position offset - obuf[ro++] = 0x20 | seg; // relocation byte for new segment - } else { - // absolute value - do not write a new relocation entry - } - } - ri += 4;// account for position, segment byte, label number in reloc table - } - new = old + diff; - buf[addr-base+pos] = new & 255; - break; - } - } } *lastaddrp = lastaddr + rdiff; - *rop = ro; + *rop = ro; #ifdef DEBUG printf(" --> lastaddr=%04x (%04x - %04x), rop=%d\n", lastaddr, *lastaddrp, rdiff, ro); #endif return ++ri; } - - diff --git a/xa/misc/printcbm.c b/xa/misc/printcbm.c index e00124b..fdb9d45 100644 --- a/xa/misc/printcbm.c +++ b/xa/misc/printcbm.c @@ -1,7 +1,7 @@ /* printcbm -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * list CBM BASIC programs * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -54,8 +54,7 @@ void usage(FILE *fp) programname); } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { FILE *fp; int a, b, c; diff --git a/xa/misc/reloc65.c b/xa/misc/reloc65.c index 83dffa0..d3c3025 100644 --- a/xa/misc/reloc65.c +++ b/xa/misc/reloc65.c @@ -1,7 +1,7 @@ /* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * o65 file relocator * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -127,273 +127,309 @@ int main(int argc, char *argv[]) { char *arg; // temporary argument pointer if (argc <= 1) { - usage(stderr); - exit(1); + usage(stderr); + exit(1); } - if (strstr(argv[1], "--help") || strstr(argv[1], "-?") || strstr(argv[1], "-h")) { - usage(stdout); - exit(0); + if (strstr(argv[1], "--help") || strstr(argv[1], "-?") + || strstr(argv[1], "-h")) { + usage(stdout); + exit(0); } if (strstr(argv[1], "--version")) { - version(programname, progversion, author, copyright); - exit(0); + version(programname, progversion, author, copyright); + exit(0); } - while(i %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 + struct stat fs; + file.fname = argv[i]; + stat(argv[i], &fs); + file.fsize = fs.st_size; + file.buf = malloc(file.fsize); + if (!file.buf) { + fprintf(stderr, "Oops, no more memory! (%d)\n", file.fsize); + exit(1); } - } - file.buf[6] = mode & 0xff; - file.buf[7] = (mode >> 8) & 0xff; + 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 + } + } + file.buf[6] = mode & 0xff; + file.buf[7] = (mode >> 8) & 0xff; - hlen = BUF+read_options(file.buf+BUF); - - file.tbase = file.buf[ 9]*256+file.buf[ 8]; - file.tlen = file.buf[11]*256+file.buf[10]; - file.tdiff = tflag ? tbase - file.tbase : 0; + hlen = BUF + read_options(file.buf + BUF); - file.dbase = file.buf[13]*256+file.buf[12]; - file.dlen = file.buf[15]*256+file.buf[14]; - file.ddiff = dflag ? dbase - file.dbase : 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.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.bbase = file.buf[17]*256+file.buf[16]; - file.blen = file.buf[19]*256+file.buf[18]; - 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; - } - } + file.dbase = file.buf[13] * 256 + file.buf[12]; + file.dlen = file.buf[15] * 256 + file.buf[14]; + file.ddiff = dflag ? dbase - file.dbase : 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.zbase = file.buf[21]*256+file.buf[20]; - file.zlen = file.buf[23]*256+file.buf[22]; - file.zdiff = zflag ? zbase - file.zbase : 0; + file.bbase = file.buf[17] * 256 + file.buf[16]; + file.blen = file.buf[19] * 256 + file.buf[18]; + 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) { - printf("Relocating segments to:\n"); - printf("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.zbase = file.buf[21] * 256 + file.buf[20]; + file.zlen = file.buf[23] * 256 + file.buf[22]; + file.zdiff = zflag ? zbase - file.zbase : 0; - /* pointer of position in file */ - file.segt = file.buf + hlen; - file.segd = file.segt + file.tlen; - file.utab = file.segd + file.dlen; + if (verbose) { + printf("Relocating segments to:\n"); + printf( + "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); - file.rdtab = reloc_seg(file.segt, file.tlen, file.rttab, - &file, extract); - file.extab = reloc_seg(file.segd, file.dlen, file.rdtab, - &file, extract); + /* pointer of position in file */ + file.segt = file.buf + hlen; + file.segd = file.segt + file.tlen; + file.utab = file.segd + file.dlen; - 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) { - 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; - } + reloc_globals(file.extab, &file); - fp = fopen(outfile, "wb"); - if(fp) { - switch(extract) { - 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)); - } + if (tflag) { + 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 (fp) { + switch (extract) { + 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 { - 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++; + i++; } exit(0); } - int read_options(unsigned char *buf) { - int c, l=0; + int c, l = 0; - c=buf[0]; - while(c && c!=EOF) { - c&=255; - l+=c; - c=buf[l]; + c = buf[0]; + while (c && c != EOF) { + c &= 255; + l += c; + c = buf[l]; } return ++l; } @@ -401,90 +437,94 @@ int read_options(unsigned char *buf) { int read_undef(unsigned char *buf) { int n, l = 2; - n = buf[0] + 256*buf[1]; - while(n){ - n--; - while(buf[l] != 0) { + n = buf[0] + 256 * buf[1]; + while (n) { + n--; + while (buf[l] != 0) { + l++; + } l++; - } - l++; } return l; } #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, - file65 *fp, int undefwarn) { +unsigned char* reloc_seg(unsigned char *buf, int len, unsigned char *rtab, + file65 *fp, int undefwarn) { int adr = -1; int type, seg, old, new; -/*printf("tdiff=%04x, ddiff=%04x, bdiff=%04x, zdiff=%04x\n", - fp->tdiff, fp->ddiff, fp->bdiff, fp->zdiff);*/ - while(*rtab) { - if((*rtab & 255) == 255) { - adr += 254; - rtab++; - } else { - adr += *rtab & 255; - rtab++; - type = *rtab & 0xe0; - seg = *rtab & 0x07; -/*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",rtab-1, *(rtab-1), adr, type, seg);*/ - rtab++; - switch(type) { - case 0x80: /* WORD - two byte address */ - old = buf[adr] + 256*buf[adr+1]; - new = old + reldiff(seg); - buf[adr] = new & 255; - buf[adr+1] = (new>>8)&255; - break; - case 0x40: /* HIGH - high byte of an address */ - old = buf[adr]*256 + *rtab; - new = old + reldiff(seg); - buf[adr] = (new>>8)&255; - *rtab = new & 255; - rtab++; - break; - case 0x20: /* LOW - low byt of an address */ - old = buf[adr]; - new = old + reldiff(seg); - buf[adr] = new & 255; - break; - } - if(seg==0) { - /* undefined segment entry */ - if (undefwarn) { - fprintf(stderr,"reloc65: %s: Warning: undefined relocation table entry not handled!\n", fp->fname); + /*printf("tdiff=%04x, ddiff=%04x, bdiff=%04x, zdiff=%04x\n", + fp->tdiff, fp->ddiff, fp->bdiff, fp->zdiff);*/ + while (*rtab) { + if ((*rtab & 255) == 255) { + adr += 254; + rtab++; + } else { + adr += *rtab & 255; + rtab++; + type = *rtab & 0xe0; + seg = *rtab & 0x07; + /*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",rtab-1, *(rtab-1), adr, type, seg);*/ + rtab++; + switch (type) { + case 0x80: /* WORD - two byte address */ + old = buf[adr] + 256 * buf[adr + 1]; + new = old + reldiff(seg); + buf[adr] = new & 255; + buf[adr + 1] = (new >> 8) & 255; + break; + case 0x40: /* HIGH - high byte of an address */ + old = buf[adr] * 256 + *rtab; + new = old + reldiff(seg); + buf[adr] = (new >> 8) & 255; + *rtab = new & 255; + rtab++; + break; + case 0x20: /* LOW - low byt of an address */ + old = buf[adr]; + new = old + reldiff(seg); + buf[adr] = new & 255; + break; + } + if (seg == 0) { + /* undefined segment entry */ + if (undefwarn) { + fprintf(stderr, + "reloc65: %s: Warning: undefined relocation table entry not handled!\n", + fp->fname); + } + rtab += 2; + } } - rtab+=2; - } - } } - if(adr > len) { - fprintf(stderr,"reloc65: %s: Warning: relocation table entries past segment end!\n", - fp->fname); - fprintf(stderr, "reloc65: adr=%x len=%x\n", adr, len); + if (adr > len) { + fprintf(stderr, + "reloc65: %s: Warning: relocation table entries past segment end!\n", + fp->fname); + fprintf(stderr, "reloc65: adr=%x len=%x\n", adr, len); } 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; - n = buf[0] + 256*buf[1]; - buf +=2; + n = buf[0] + 256 * buf[1]; + buf += 2; - while(n) { -/*printf("relocating %s, ", buf);*/ - while(*(buf++)); - seg = *buf; - old = buf[1] + 256*buf[2]; - new = old + reldiff(seg); -/*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ - buf[1] = new & 255; - buf[2] = (new>>8) & 255; - buf +=3; - n--; + while (n) { + /*printf("relocating %s, ", buf);*/ + while (*(buf++)) + ; + seg = *buf; + old = buf[1] + 256 * buf[2]; + new = old + reldiff(seg); + /*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ + buf[1] = new & 255; + buf[2] = (new >> 8) & 255; + buf += 3; + n--; } return buf; } diff --git a/xa/misc/uncpk.c b/xa/misc/uncpk.c index 5f2cfb5..7759cc5 100644 --- a/xa/misc/uncpk.c +++ b/xa/misc/uncpk.c @@ -1,7 +1,7 @@ /* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * Pack/Unpack cpk archive files * - * Copyright (C) 1989-2002 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-2002 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -54,154 +54,162 @@ void usage(FILE *fp) int list=0,verbose=0,add=0,create=0; -int main(int argc, char *argv[]) -{ - int i,c,c2,fileok, nc; - size_t n,n2; - FILE *fp,*fpo=NULL; +int main(int argc, char *argv[]) { + int i, c, c2, fileok, nc; + size_t n, n2; + FILE *fp, *fpo = NULL; if (argc <= 1) { - usage(stderr); - exit(1); + usage(stderr); + exit(1); } if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) { - usage(stdout); - exit(0); + usage(stdout); + exit(0); } if (strstr(argv[1], "--version")) { - version(programname, progversion, author, copyright); - exit(0); + version(programname, progversion, author, copyright); + exit(0); } - if(strchr(argv[1],(int)'l')) { - list=1; + if (strchr(argv[1], (int) 'l')) { + list = 1; } - if(strchr(argv[1],(int)'v')) { - verbose=1; + if (strchr(argv[1], (int) 'v')) { + verbose = 1; } - if(strchr(argv[1],(int)'a')) { - add=1; + if (strchr(argv[1], (int) 'a')) { + add = 1; } - if(strchr(argv[1],(int)'c')) { - create=1; + if (strchr(argv[1], (int) 'c')) { + create = 1; } - if(add||create) { - if (argc <= 3) { - usage(stderr); - exit(1); - } - if(add) { - fpo=fopen(argv[2],"ab"); - } else - if(create) { - fpo=fopen(argv[2],"wb"); - } - if(fpo) { - if(!add) fputc(1,fpo); /* Version Byte */ - for(i=3;i=4 || c==0xf7) { - n2=min(255,n); - fprintf(fpo,"\xf7%c%c",(char)n2,(char)c); - n-=n2; - } else { - fputc(c,fpo); - n--; - } - } - c=c2; - } - fclose(fp); - fputc(0xf7,fpo); fputc(0,fpo); - } else { - fprintf(stderr,"Couldn't open file '%s' for reading!",argv[i]); - } - } - fclose(fpo); - } else { - fprintf(stderr,"Couldn't open file '%s' for writing!",argv[1]); - } - } else { - if (argc != 3) { - usage(stderr); - exit(1); - } - fp=fopen(argv[2],"rb"); - if(fp){ - if(fgetc(fp)==1){ - do{ - /* read name */ - i=0; - while((c=fgetc(fp))){ - if(c==EOF) break; - name[i++]=c; - } - name[i++]='\0'; - if(!c){ /* end of archive ? */ - while((s=strchr(name,'/'))) *s=':'; - - if(verbose+list) printf("%s\n",name); - - if(!list) { - fpo=fopen(name,"wb"); - if(!fpo) { - fprintf(stderr,"Couldn't open output file %s !\n",name); - } - } - fileok=0; - while((c=fgetc(fp))!=EOF){ - /* test if 'compressed' */ - if(c==0xf7){ - nc=fgetc(fp); - if(!nc) { - fileok=1; - break; - } - c=fgetc(fp); - if(fpo) { /* extract */ - if(nc!=EOF && c!=EOF) { - nc &= 255; - while(nc--) { - fputc(c,fpo); - } - } - } - } else { - if(fpo) { - fputc(c,fpo); - } - } - } - if(fpo) { - fclose(fpo); - fpo=NULL; - } - if(!fileok) { - fprintf(stderr,"Unexpected end of file!\n"); + if (add || create) { + if (argc <= 3) { + usage(stderr); + exit(1); + } + if (add) { + fpo = fopen(argv[2], "ab"); + } else if (create) { + fpo = fopen(argv[2], "wb"); + } + if (fpo) { + if (!add) + fputc(1, fpo); /* Version Byte */ + for (i = 3; i < argc; i++) { + if (verbose) + printf("%s\n", argv[i]); + fp = fopen(argv[i], "rb"); + if (fp) { + while ((s = strchr(argv[i], ':'))) + *s = '/'; + fprintf(fpo, "%s", argv[i]); + fputc(0, fpo); + c = fgetc(fp); + while (c != EOF) { + n = 1; + while ((c2 = fgetc(fp)) == c) { + n++; + } + while (n) { + if (n >= 4 || c == 0xf7) { + n2 = min(255, n); + fprintf(fpo, "\xf7%c%c", (char) n2, (char) c); + n -= n2; + } else { + fputc(c, fpo); + n--; + } + } + c = c2; + } + fclose(fp); + fputc(0xf7, fpo); + fputc(0, fpo); + } else { + fprintf(stderr, "Couldn't open file '%s' for reading!", + argv[i]); + } + } + fclose(fpo); + } else { + fprintf(stderr, "Couldn't open file '%s' for writing!", argv[1]); + } + } else { + if (argc != 3) { + usage(stderr); + exit(1); + } + fp = fopen(argv[2], "rb"); + if (fp) { + if (fgetc(fp) == 1) { + do { + /* read name */ + i = 0; + while ((c = fgetc(fp))) { + if (c == EOF) + break; + name[i++] = c; + } + name[i++] = '\0'; + if (!c) { /* end of archive ? */ + while ((s = strchr(name, '/'))) + *s = ':'; + + if (verbose + list) + printf("%s\n", name); + + if (!list) { + fpo = fopen(name, "wb"); + if (!fpo) { + fprintf(stderr, + "Couldn't open output file %s !\n", + name); + } + } + fileok = 0; + while ((c = fgetc(fp)) != EOF) { + /* test if 'compressed' */ + if (c == 0xf7) { + nc = fgetc(fp); + if (!nc) { + fileok = 1; + break; + } + c = fgetc(fp); + if (fpo) { /* extract */ + if (nc != EOF && c != EOF) { + nc &= 255; + while (nc--) { + fputc(c, fpo); + } + } + } + } else { + if (fpo) { + 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); } diff --git a/xa/src/xa.c b/xa/src/xa.c index 08b7517..3dc5daa 100644 --- a/xa/src/xa.c +++ b/xa/src/xa.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * maintained by Cameron Kaiser (ckaiser@floodgap.com) * * Main program @@ -64,11 +64,11 @@ int ncmos, cmosfl, w65816, n65816; /* compatibility flags */ -int masm = 0; /* MASM */ -int ca65 = 0; /* CA65 */ +int masm = 0; /* MASM */ +int ca65 = 0; /* CA65 */ int collab = 0; /* allow colon relative labels even without ca65 mode */ -int xa23 = 0; /* ^ and recursive comments, disable \ escape */ -int ctypes = 0; /* C compatibility, like "0xab" types */ +int xa23 = 0; /* ^ and recursive comments, disable \ escape */ +int ctypes = 0; /* C compatibility, like "0xab" types */ int nolink = 0; int romable = 0; int romaddr = 0; @@ -76,7 +76,7 @@ int noglob = 0; int showblk = 0; int crossref = 0; int mask = 0; -int undefok = 0; // -R only accepts -Llabels; with -U all undef'd labels are ok in -R mode +int undefok = 0;// -R only accepts -Llabels; with -U all undef'd labels are ok in -R mode char altppchar; /* local variables */ @@ -90,820 +90,851 @@ static int ner_max = 20; static int align = 1; static void printstat(void); -static void usage(int, FILE *); -static int setfext(char *, char *); +static void usage(int, FILE*); +static int setfext(char*, char*); static int x_init(void); static int pass1(void); static int pass2(void); static int puttmp(int); static int puttmpw(int); -static int puttmps(signed char *, int); +static int puttmps(signed char*, int); static void chrput(int); -static int xa_getline(char *); +static int xa_getline(char*); static void lineout(void); static long ga_p1(void); static long gm_p1(void); static int set_compat(char *compat_name); /* text */ -int memode,xmode; +int memode, xmode; int segment; -int tlen=0, tbase=0x1000; -int dlen=0, dbase=0x0400; -int blen=0, bbase=0x4000; -int zlen=0, zbase=4; -int fmode=0; -int relmode=0; +int tlen = 0, tbase = 0x1000; +int dlen = 0, dbase = 0x0400; +int blen = 0, bbase = 0x4000; +int zlen = 0, zbase = 4; +int fmode = 0; +int relmode = 0; -int pc[SEG_MAX]; /* segments */ +int pc[SEG_MAX]; /* segments */ -int main(int argc,char *argv[]) -{ - int er=1,i; - signed char *s=NULL; - char *tmpp; +int main(int argc, char *argv[]) { + int er = 1, i; + signed char *s = NULL; + char *tmpp; - char *listformat = NULL; + char *listformat = NULL; - int mifiles = 5; - int nifiles = 0; - int verbose = 0; - int no_link = 0; + int mifiles = 5; + int nifiles = 0; + int verbose = 0; + int no_link = 0; - char **ifiles; - char *printfile; /* print listing to this file */ - char *ofile; /* output file */ - char *efile; /* error listing goes there */ - char *lfile; /* labels go here */ - char *ifile; - - char old_e[MAXLINE]; - char old_l[MAXLINE]; - char old_o[MAXLINE]; + char **ifiles; + char *printfile; /* print listing to this file */ + char *ofile; /* output file */ + char *efile; /* error listing goes there */ + char *lfile; /* labels go here */ + char *ifile; - tim1=time(NULL); - - // note: unfortunately we do no full distinction between 65C02 and 65816. - // The conflict is in the column 7 and column f opcodes, where the 65C02 - // has the BBR/BBS/SMB/RMB opcodes, but the 65816 has its own. - // Also, we potentially could support the 65SC02, which is the 65C02, but - // without the conflicting BBR/BBS/SMB/RMB opcodes. - // This, however, is a TODO for a later version. - cmosfl=1; - //fmode = FM_CPU2_65C02; - w65816=0; /* default: 6502 only */ + char old_e[MAXLINE]; + char old_l[MAXLINE]; + char old_o[MAXLINE]; - ncmos=0; // counter for CMOS opcodes used - n65816=0; // counter for 65816-specific opcodes used + tim1 = time(NULL); - altppchar = '#' ; /* i.e., NO alternate char */ + // note: unfortunately we do no full distinction between 65C02 and 65816. + // The conflict is in the column 7 and column f opcodes, where the 65C02 + // has the BBR/BBS/SMB/RMB opcodes, but the 65816 has its own. + // Also, we potentially could support the 65SC02, which is the 65C02, but + // without the conflicting BBR/BBS/SMB/RMB opcodes. + // This, however, is a TODO for a later version. + cmosfl = 1; + //fmode = FM_CPU2_65C02; + w65816 = 0; /* default: 6502 only */ - if((tmpp = strrchr(argv[0],'/'))) { - tmpp++; - } else { - tmpp = argv[0]; - } - if( (!strcmp(tmpp,"xa65816")) - || (!strcmp(tmpp,"XA65816")) - || (!strcmp(tmpp,"xa816")) - || (!strcmp(tmpp,"XA816")) - ) { - w65816 = 1; /* allow 65816 per default */ - } + ncmos = 0; // counter for CMOS opcodes used + n65816 = 0; // counter for 65816-specific opcodes used - /* default output charset for strings in quotes */ - set_charset("ASCII"); + altppchar = '#'; /* i.e., NO alternate char */ - ifiles = malloc(mifiles*sizeof(char*)); - - afile = alloc_file(); - - if (argc <= 1) { - usage(w65816, stderr); - exit(1); - } - - if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) { - usage(w65816, stdout); - exit(0); - } - - if (strstr(argv[1], "--version")) { - version(programname, progversion, authors, copyright); - exit(0); - } - - ofile="a.o65"; - efile=NULL; - lfile=NULL; - printfile=NULL; - - if(pp_init()) { - logout("fatal: pp: no memory!"); - return 1; - } - if(b_init()) { - logout("fatal: b: no memory!"); - return 1; - } - if(l_init()) { - logout("fatal: l: no memory!"); - return 1; - } - - i=1; - while(i filename */ - ifiles[nifiles++] = argv[i]; - if(nifiles>=mifiles) { - mifiles += 5; - ifiles=realloc(ifiles, mifiles*sizeof(char*)); - if(!ifiles) { - fprintf(stderr, "Oops: couldn't alloc enough mem for filelist table..!\n"); - exit(1); - } - } - } - i++; - } - if(!nifiles) { - fprintf(stderr, "No input files given!\n"); - exit(0); - } - - if(verbose) fprintf(stderr, "%s\n",copyright); - - if (printfile!=NULL && !strcmp(printfile, "-")) { - printfile=NULL; - fplist = stdout; - } else { - fplist= printfile ? xfopen(printfile,"w") : NULL; - } - fplab= lfile ? xfopen(lfile,"w") : NULL; - fperr= efile ? xfopen(efile,"w") : NULL; - if(!strcmp(ofile,"-")) { - ofile=NULL; - fpout = stdout; - } else { - fpout= xfopen(ofile,"wb"); - } - if(!fpout) { - fprintf(stderr, "Couldn't open output file!\n"); - exit(1); - } - - if(verbose) fprintf(stderr, "%s\n",copyright); - - if(1 /*!m_init()*/) - { - if(1 /*!b_init()*/) - { - if(1 /*!l_init()*/) - { - /*if(!pp_init())*/ - { - if(!x_init()) - { - /* if(fperr) fprintf(fperr,"%s\n",copyright); */ - if(verbose) logout(ctime(&tim1)); - - list_setfile(fplist); - - /* Pass 1 */ - - pc[SEG_ABS]= 0; /* abs addressing */ - seg_start(fmode, tbase, dbase, bbase, zbase, 0, relmode); - - if(relmode) { - r_mode(RMODE_RELOC); - segment = SEG_TEXT; - } else { - /* prime old_segment in r_mode with SEG_TEXT */ - segment = SEG_ABS; - r_mode(RMODE_ABS); - } - - nolink = no_link; - - for (i=0; ifname)); - - if(!er) { - er=pass1(); - pp_close(); - } else { - sprintf(out, "Couldn't open source file '%s'!\n", ifile); - logout(out); - } - } - - if((er=b_depth())) { - sprintf(out,"Still %d blocks open at end of file!\n",er); - logout(out); - } - - if(tbase & (align-1)) { - sprintf(out,"Warning: text segment ($%04x) start address doesn't align to %d!\n", tbase, align); - logout(out); - } - if(dbase & (align-1)) { - sprintf(out,"Warning: data segment ($%04x) start address doesn't align to %d!\n", dbase, align); - logout(out); - } - if(bbase & (align-1)) { - sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align); - logout(out); - } - if (n65816>0) - fmode |= 0x8000; - switch(align) { - case 1: break; - case 2: fmode |= 1; break; - case 4: fmode |= 2; break; - case 256: fmode |=3; break; - } - - if((!er) && relmode) - h_write(fpout, fmode, tlen, dlen, blen, zlen, 0); - - - if(!er) - { - if(verbose) logout("xAss65: Pass 2:\n"); - - list_start(listformat); - - seg_pass2(); - - if(relmode) { - r_mode(RMODE_RELOC); - segment = SEG_TEXT; - } else { - /* prime old_segment in r_mode with SEG_TEXT */ - segment = SEG_ABS; - r_mode(RMODE_ABS); - } - er=pass2(); - - list_end(); - } - - if(fplab) printllist(fplab); - tim2=time(NULL); - if(verbose) printstat(); - - if((!er) && relmode) seg_end(fpout); /* write reloc/label info */ - - if(fplist && fplist!=stdout) fclose(fplist); - if(fperr) fclose(fperr); - if(fplab) fclose(fplab); - if(fpout && fpout!=stdout) fclose(fpout); - - } else { - logout("fatal: x: no memory!\n"); - } - pp_end(); -/* } else { - logout("fatal: pp: no memory!");*/ - } - } else { - logout("fatal: l: no memory!\n"); - } - } else { - logout("fatal: b: no memory!\n"); - } - /*m_exit();*/ - } else { - logout("Not enough memory available!\n"); - } - - if(ner || er) - { - if (ner_max > 0) { - fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0); + if ((tmpp = strrchr(argv[0], '/'))) { + tmpp++; } else { - /* ner_max==0, i.e. show all errors */ - fprintf(stderr, "End after %d error%c\n",ner,ner?'s':0); + tmpp = argv[0]; + } + if ((!strcmp(tmpp, "xa65816")) || (!strcmp(tmpp, "XA65816")) + || (!strcmp(tmpp, "xa816")) || (!strcmp(tmpp, "XA816"))) { + w65816 = 1; /* allow 65816 per default */ } - /*unlink();*/ - if(ofile) { - unlink(ofile); - } - } - free(ifiles); + /* default output charset for strings in quotes */ + set_charset("ASCII"); - return( (er || ner) ? 1 : 0 ); + ifiles = malloc(mifiles * sizeof(char*)); + + afile = alloc_file(); + + if (argc <= 1) { + usage(w65816, stderr); + exit(1); + } + + if (strstr(argv[1], "--help") || strstr(argv[1], "-?")) { + usage(w65816, stdout); + exit(0); + } + + if (strstr(argv[1], "--version")) { + version(programname, progversion, authors, copyright); + exit(0); + } + + ofile = "a.o65"; + efile = NULL; + lfile = NULL; + printfile = NULL; + + if (pp_init()) { + logout("fatal: pp: no memory!"); + return 1; + } + if (b_init()) { + logout("fatal: b: no memory!"); + return 1; + } + if (l_init()) { + logout("fatal: l: no memory!"); + return 1; + } + + i = 1; + while (i < argc) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'a': + if (ca65) { + collab = 0; /* paranoia */ + fprintf(stderr, "Warning: -a not needed with -XCA65\n"); + } else + collab = 1; + break; + case 'k': + mask = 1; + break; + case 'E': + ner_max = 0; + break; + case 'p': + /* intentionally not allowing an argument to follow with a + space to avoid - being seen as the alternate + preprocessor char! */ + if (argv[i][2] == '\0') { + fprintf(stderr, "-p requires a character argument\n"); + exit(1); + } + if (argv[i][2] == '#') + fprintf(stderr, + "using -p# is not necessary, '#' is the default\n"); + altppchar = argv[i][2]; + if (argv[i][3] != '\0') + fprintf(stderr, + "warning: extra characters to -p ignored\n"); + break; + case 'M': + fprintf(stderr, + "Warning: -M is deprecated (use -XMASM) and will be removed in a future version\n"); + masm = 1; /* MASM compatibility mode */ + break; + case 'X': /* compatibility across assemblers... */ + { + char *name = NULL; + if (argv[i][2] == 0) { + name = argv[++i]; + } else { + name = argv[i] + 2; + } + if (set_compat(name) < 0) { + fprintf(stderr, + "Compatibility set '%s' unknown - ignoring! (check case?)\n", + name); + } + if (collab && ca65) { + collab = 0; + fprintf(stderr, "Warning: -a not needed with -XCA65\n"); + } + } + break; + case 'O': /* output charset */ + { + char *name = NULL; + if (argv[i][2] == 0) { + if (i + 1 < argc) + name = argv[++i]; + else { + fprintf(stderr, "-O requires an argument\n"); + exit(1); + } + } else { + name = argv[i] + 2; + } + if (set_charset(name) < 0) { + fprintf(stderr, + "Output charset name '%s' unknown - ignoring! (check case?)\n", + name); + } + } + break; + case 'A': /* make text segment start so that text relocation + is not necessary when _file_ starts at adr */ + romable = 2; + if (argv[i][2] == 0) { + if (i + 1 < argc) + romaddr = atoi(argv[++i]); + else { + fprintf(stderr, "-A requires an argument\n"); + exit(1); + } + } else + romaddr = atoi(argv[i] + 2); + break; + case 'G': + noglob = 1; + break; + case 'L': /* define global label */ + if (argv[i][2]) + lg_set(argv[i] + 2); + break; + case 'r': + crossref = 1; + break; + case 'R': + relmode = 1; + break; + case 'U': + undefok = 1; + break; + case 'D': + s = (signed char*) strstr(argv[i] + 2, "="); + if (s) + *s = ' '; + pp_define(argv[i] + 2); + break; + case 'c': + no_link = 1; + fmode |= FM_OBJ; + break; + case 'v': + verbose = 1; + break; + case 'C': + cmosfl = 0; + fmode &= ~FM_CPU2; // fall back to standard 6502 + // breaks existing tests (compare with pre-assembled files) + //if (w65816) { + // fmode |= FM_CPU2_65816E; + //} + break; + case 'W': + w65816 = 0; + fmode &= ~FM_CPU; + fmode &= ~FM_CPU2; + // breaks existing tests (compare with pre-assembled files) + //if (cmosfl) { + // fmode |= FM_CPU2_65C02; + //} + break; + case 'w': + // note: we do not disable cmos here, as opcode tables note CMOS for + // opcodes common to both, CMOS and 65816 as well. + w65816 = 1; + fmode &= ~FM_CPU2; + // breaks existing tests (compare with pre-assembled files) + //fmode |= FM_CPU; // 65816 bit + //fmode |= FM_CPU2_65816E;// 6502 in 65816 emu, to manage opcode compatibility in ldo65 + break; + case 'B': + showblk = 1; + break; + case 'I': + if (argv[i][2] == 0) { + if (i + 1 < argc) + reg_include(argv[++i]); + else { + fprintf(stderr, "-I requires an argument\n"); + exit(1); + } + } else { + reg_include(argv[i] + 2); + } + break; + case 'P': + if (argv[i][2] == 0) { + printfile = argv[++i]; + } else { + printfile = argv[i] + 2; + } + break; + case 'F': + if (argv[i][2] == 0) { + listformat = argv[++i]; + } else { + listformat = argv[i] + 2; + } + break; + case 'o': + if (argv[i][2] == 0) { + if (i + 1 < argc) + ofile = argv[++i]; + else { + fprintf(stderr, "-o requires an argument\n"); + exit(1); + } + } else { + ofile = argv[i] + 2; + } + break; + case 'l': + if (argv[i][2] == 0) { + if (i + 1 < argc) + lfile = argv[++i]; + else { + fprintf(stderr, "-l requires an argument\n"); + exit(1); + } + } else { + lfile = argv[i] + 2; + } + break; + case 'e': + if (argv[i][2] == 0) { + if (i + 1 < argc) + efile = argv[++i]; + else { + fprintf(stderr, "-e requires an argument\n"); + exit(1); + } + } else { + efile = argv[i] + 2; + } + break; + case 'b': /* set segment base addresses */ + switch (argv[i][2]) { + case 't': + if (argv[i][3] == 0) + tbase = atoi(argv[++i]); + else + tbase = atoi(argv[i] + 3); + break; + case 'd': + if (argv[i][3] == 0) + dbase = atoi(argv[++i]); + else + dbase = atoi(argv[i] + 3); + break; + case 'b': + if (argv[i][3] == 0) + bbase = atoi(argv[++i]); + else + bbase = atoi(argv[i] + 3); + break; + case 'z': + if (argv[i][3] == 0) + zbase = atoi(argv[++i]); + else + zbase = atoi(argv[i] + 3); + break; + default: + fprintf(stderr, "unknown segment type '%c' - ignoring!\n", + argv[i][2]); + break; + } + break; + case 0: + fprintf(stderr, + "Single dash '-' on command line - ignoring!\n"); + break; + default: + fprintf(stderr, "Unknown option '%c' - ignoring!\n", + argv[i][1]); + break; + } + } else { /* no option -> filename */ + ifiles[nifiles++] = argv[i]; + if (nifiles >= mifiles) { + mifiles += 5; + ifiles = realloc(ifiles, mifiles * sizeof(char*)); + if (!ifiles) { + fprintf(stderr, + "Oops: couldn't alloc enough mem for filelist table..!\n"); + exit(1); + } + } + } + i++; + } + if (!nifiles) { + fprintf(stderr, "No input files given!\n"); + exit(0); + } + + if (verbose) + fprintf(stderr, "%s\n", copyright); + + if (printfile != NULL && !strcmp(printfile, "-")) { + printfile = NULL; + fplist = stdout; + } else { + fplist = printfile ? xfopen(printfile, "w") : NULL; + } + fplab = lfile ? xfopen(lfile, "w") : NULL; + fperr = efile ? xfopen(efile, "w") : NULL; + if (!strcmp(ofile, "-")) { + ofile = NULL; + fpout = stdout; + } else { + fpout = xfopen(ofile, "wb"); + } + if (!fpout) { + fprintf(stderr, "Couldn't open output file!\n"); + exit(1); + } + + if (verbose) + fprintf(stderr, "%s\n", copyright); + + if (1 /*!m_init()*/) { + if (1 /*!b_init()*/) { + if (1 /*!l_init()*/) { + /*if(!pp_init())*/ + { + if (!x_init()) { + /* if(fperr) fprintf(fperr,"%s\n",copyright); */ + if (verbose) + logout(ctime(&tim1)); + + list_setfile(fplist); + + /* Pass 1 */ + + pc[SEG_ABS] = 0; /* abs addressing */ + seg_start(fmode, tbase, dbase, bbase, zbase, 0, + relmode); + + if (relmode) { + r_mode(RMODE_RELOC); + segment = SEG_TEXT; + } else { + /* prime old_segment in r_mode with SEG_TEXT */ + segment = SEG_ABS; + r_mode(RMODE_ABS); + } + + nolink = no_link; + + for (i = 0; i < nifiles; i++) { + ifile = ifiles[i]; + + sprintf(out, "xAss65: Pass 1: %s\n", ifile); + if (verbose) + logout(out); + + er = pp_open(ifile); + puttmpw(0); + puttmp(T_FILE); + puttmp(0); + puttmp(0); + puttmps((signed char*) &ifile, + sizeof(filep->fname)); + + if (!er) { + er = pass1(); + pp_close(); + } else { + sprintf(out, + "Couldn't open source file '%s'!\n", + ifile); + logout(out); + } + } + + if ((er = b_depth())) { + sprintf(out, + "Still %d blocks open at end of file!\n", + er); + logout(out); + } + + if (tbase & (align - 1)) { + sprintf(out, + "Warning: text segment ($%04x) start address doesn't align to %d!\n", + tbase, align); + logout(out); + } + if (dbase & (align - 1)) { + sprintf(out, + "Warning: data segment ($%04x) start address doesn't align to %d!\n", + dbase, align); + logout(out); + } + if (bbase & (align - 1)) { + sprintf(out, + "Warning: bss segment ($%04x) start address doesn't align to %d!\n", + bbase, align); + logout(out); + } + if (n65816 > 0) + fmode |= 0x8000; + switch (align) { + case 1: + break; + case 2: + fmode |= 1; + break; + case 4: + fmode |= 2; + break; + case 256: + fmode |= 3; + break; + } + + if ((!er) && relmode) + h_write(fpout, fmode, tlen, dlen, blen, zlen, 0); + + if (!er) { + if (verbose) + logout("xAss65: Pass 2:\n"); + + list_start(listformat); + + seg_pass2(); + + if (relmode) { + r_mode(RMODE_RELOC); + segment = SEG_TEXT; + } else { + /* prime old_segment in r_mode with SEG_TEXT */ + segment = SEG_ABS; + r_mode(RMODE_ABS); + } + er = pass2(); + + list_end(); + } + + if (fplab) + printllist(fplab); + tim2 = time(NULL); + if (verbose) + printstat(); + + if ((!er) && relmode) + seg_end(fpout); /* write reloc/label info */ + + if (fplist && fplist != stdout) + fclose(fplist); + if (fperr) + fclose(fperr); + if (fplab) + fclose(fplab); + if (fpout && fpout != stdout) + fclose(fpout); + + } else { + logout("fatal: x: no memory!\n"); + } + pp_end(); + /* } else { + logout("fatal: pp: no memory!");*/ + } + } else { + logout("fatal: l: no memory!\n"); + } + } else { + logout("fatal: b: no memory!\n"); + } + /*m_exit();*/ + } else { + logout("Not enough memory available!\n"); + } + + if (ner || er) { + if (ner_max > 0) { + fprintf(stderr, "Break after %d error%c\n", ner, ner ? 's' : 0); + } else { + /* ner_max==0, i.e. show all errors */ + fprintf(stderr, "End after %d error%c\n", ner, ner ? 's' : 0); + } + /*unlink();*/ + if (ofile) { + unlink(ofile); + } + } + + free(ifiles); + + return ((er || ner) ? 1 : 0); } -static void printstat(void) -{ +static void printstat(void) { logout("Statistics:\n"); - sprintf(out," %8d of %8d label used\n",ga_lab(),gm_lab()); logout(out); - sprintf(out," %8ld of %8ld byte label-memory used\n",ga_labm(),gm_labm()); logout(out); - sprintf(out," %8d of %8d PP-defs used\n",ga_pp(),gm_pp()); logout(out); - sprintf(out," %8ld of %8ld byte PP-memory used\n",ga_ppm(),gm_ppm()); logout(out); - sprintf(out," %8ld of %8ld byte buffer memory used\n",ga_p1(),gm_p1()); logout(out); - sprintf(out," %8d blocks used\n",ga_blk()); logout(out); - sprintf(out," %8ld seconds used\n",(long)difftime(tim2,tim1)); logout(out); + sprintf(out, " %8d of %8d label used\n", ga_lab(), gm_lab()); + logout(out); + sprintf(out, " %8ld of %8ld byte label-memory used\n", ga_labm(), + gm_labm()); + logout(out); + sprintf(out, " %8d of %8d PP-defs used\n", ga_pp(), gm_pp()); + logout(out); + sprintf(out, " %8ld of %8ld byte PP-memory used\n", ga_ppm(), gm_ppm()); + logout(out); + sprintf(out, " %8ld of %8ld byte buffer memory used\n", ga_p1(), gm_p1()); + logout(out); + sprintf(out, " %8d blocks used\n", ga_blk()); + logout(out); + sprintf(out, " %8ld seconds used\n", (long) difftime(tim2, tim1)); + logout(out); } int h_length(void) { - return 26+o_length(); + return 26 + o_length(); } +static int setfext(char *s, char *ext) { + int j, i = (int) strlen(s); -static int setfext(char *s, char *ext) -{ - int j,i=(int)strlen(s); + if (i > MAXLINE - 5) + return (-1); - if(i>MAXLINE-5) - return(-1); - - for(j=i-1;j>=0;j--) - { - if(s[j]==DIRCHAR) - { - strcpy(s+i,ext); - break; - } - if(s[j]=='.') - { - strcpy(s+j,ext); - break; - } - } - if(!j) - strcpy(s+i,ext); + for (j = i - 1; j >= 0; j--) { + if (s[j] == DIRCHAR) { + strcpy(s + i, ext); + break; + } + if (s[j] == '.') { + strcpy(s + j, ext); + break; + } + } + if (!j) + strcpy(s + i, ext); - return(0); + return (0); } - -static long ga_p1(void) -{ - return(afile->mn.tmpz); +static long ga_p1(void) { + return (afile->mn.tmpz); } -static long gm_p1(void) -{ - return(TMPMEM); +static long gm_p1(void) { + return (TMPMEM); } -static int pass2(void) -{ - int c,er,l,ll,i,al; - Datei datei; - signed char *dataseg=NULL; - signed char *datap=NULL; +static int pass2(void) { + int c, er, l, ll, i, al; + Datei datei; + signed char *dataseg = NULL; + signed char *datap = NULL; - memode=0; - xmode=0; - if((dataseg=malloc(dlen))) { - if(!dataseg) { - fprintf(stderr, "Couldn't alloc dataseg memory...\n"); - exit(1); - } - datap=dataseg; - } - filep=&datei; - afile->mn.tmpe=0L; + memode = 0; + xmode = 0; + if ((dataseg = malloc(dlen))) { + if (!dataseg) { + fprintf(stderr, "Couldn't alloc dataseg memory...\n"); + exit(1); + } + datap = dataseg; + } + filep = &datei; + afile->mn.tmpe = 0L; - while((ner_max==0 || nermn.tmpemn.tmpz) - { - // get the length of the entry (now two byte - need to handle the sign) - l = 255 & afile->mn.tmp[afile->mn.tmpe++]; - l |= afile->mn.tmp[afile->mn.tmpe++] << 8; - ll=l; + while ((ner_max == 0 || ner < ner_max) && afile->mn.tmpe < afile->mn.tmpz) { + // get the length of the entry (now two byte - need to handle the sign) + l = 255 & afile->mn.tmp[afile->mn.tmpe++]; + l |= afile->mn.tmp[afile->mn.tmpe++] << 8; + ll = l; - //printf("%p: l=%d first=%02x\n", afile->mn.tmp+afile->mn.tmpe-1, l, 0xff & afile->mn.tmp[afile->mn.tmpe]); + //printf("%p: l=%d first=%02x\n", afile->mn.tmp+afile->mn.tmpe-1, l, 0xff & afile->mn.tmp[afile->mn.tmpe]); - if(!l) - { - if(afile->mn.tmp[afile->mn.tmpe]==T_LINE) - { - datei.fline=(afile->mn.tmp[afile->mn.tmpe+1]&255)+(afile->mn.tmp[afile->mn.tmpe+2]<<8); - afile->mn.tmpe+=3; - list_line(datei.fline); /* set line number of next listing output */ - } else - if(afile->mn.tmp[afile->mn.tmpe]==T_FILE) - { - // copy the current line number from the current file descriptor - datei.fline=(afile->mn.tmp[afile->mn.tmpe+1]&255)+(afile->mn.tmp[afile->mn.tmpe+2]<<8); - // copy the pointer to the file name in the current file descriptor - // Note: the filename in the current file descriptor is separately malloc'd and - // thus save to store the pointer - memcpy(&datei.fname, afile->mn.tmp+afile->mn.tmpe+3, sizeof(datei.fname)); - afile->mn.tmpe+=3+sizeof(datei.fname); + if (!l) { + if (afile->mn.tmp[afile->mn.tmpe] == T_LINE) { + datei.fline = (afile->mn.tmp[afile->mn.tmpe + 1] & 255) + + (afile->mn.tmp[afile->mn.tmpe + 2] << 8); + afile->mn.tmpe += 3; + list_line(datei.fline); /* set line number of next listing output */ + } else if (afile->mn.tmp[afile->mn.tmpe] == T_FILE) { + // copy the current line number from the current file descriptor + datei.fline = (afile->mn.tmp[afile->mn.tmpe + 1] & 255) + + (afile->mn.tmp[afile->mn.tmpe + 2] << 8); + // copy the pointer to the file name in the current file descriptor + // Note: the filename in the current file descriptor is separately malloc'd and + // thus save to store the pointer + memcpy(&datei.fname, afile->mn.tmp + afile->mn.tmpe + 3, + sizeof(datei.fname)); + afile->mn.tmpe += 3 + sizeof(datei.fname); - list_filename(datei.fname); /* set file name of next listing output */ - } - } else - { -/* do not attempt address mode optimization on pass 2 */ - - /* t_p2_l() includes the listing call to do_listing() */ - er=t_p2_l(afile->mn.tmp+afile->mn.tmpe,&ll,&al); - if(er==E_NOLINE) - { - } else - if(er==E_OK) - { - if(segmentmn.tmp[afile->mn.tmpe+i]); - } else if (segment==SEG_DATA && datap) { - memcpy(datap,afile->mn.tmp+afile->mn.tmpe,ll); - datap+=ll; - } - } else - if(er==E_DSB) - { - c=afile->mn.tmp[afile->mn.tmpe]; - if(segmentmn.tmp[afile->mn.tmpe]);*/ - for(i=0;imn.tmpe; -/* - fprintf(stderr, "ok, ready to insert\n"); - for (i=0; imn.tmp[afile->mn.tmpe+i]); + list_filename(datei.fname); /* set file name of next listing output */ } -*/ - - offset = afile->mn.tmp[i] + - (afile->mn.tmp[i+1] << 8) + - (afile->mn.tmp[i+2] << 16); - fstart = afile->mn.tmp[i+3] + 1 + - (afile->mn.tmp[i+4] << 8); - /* usually redundant but here for single-char names - that get interpreted as chars */ - flen = afile->mn.tmp[i+5]; - if (flen > 1) fstart++; - /* now fstart points either to string past quote and - length mark, OR, single char byte */ -/* -fprintf(stderr, "offset = %i length = %i fstart = %i flen = %i charo = %c\n", - offset, ll, fstart, flen, afile->mn.tmp[afile->mn.tmpe+fstart]); -*/ - /* there is a race condition here where altering the - file between validation in t_p2 (xat.c) and - here will cause problems. I'm not going to - worry about this right now. */ - - for(j=0; jmn.tmp[i+fstart+j]; - } - binfnam[flen] = '\0'; -/* - fprintf(stderr, "fnam = %s\n", binfnam); -*/ - /* primitive insurance */ - if (!(foo = fopen(binfnam, "rb"))) { - errout(E_FNF); - ner++; - } else { - fseek(foo, offset, SEEK_SET); - for(j=0; jmn.tmpe+=abs(l); - } - if(relmode) { - if((ll=fwrite(dataseg, 1, dlen, fpout))mn.tmp + afile->mn.tmpe, &ll, &al); + if (er == E_NOLINE) { + } else if (er == E_OK) { + if (segment < SEG_DATA) { + for (i = 0; i < ll; i++) + chrput(afile->mn.tmp[afile->mn.tmpe + i]); + } else if (segment == SEG_DATA && datap) { + memcpy(datap, afile->mn.tmp + afile->mn.tmpe, ll); + datap += ll; + } + } else if (er == E_DSB) { + c = afile->mn.tmp[afile->mn.tmpe]; + if (segment < SEG_DATA) { + /*printf("E_DSB, ll=%d, l=%d, c=%c\n",ll,l,afile->mn.tmp[afile->mn.tmpe]);*/ + for (i = 0; i < ll; i++) + chrput(c); + } else if (segment == SEG_DATA && datap) { + memset(datap, c, ll); + datap += ll; + } + } else if (er == E_BIN) { + int i; + int j; + int flen; + int offset; + int fstart; + FILE *foo; + char binfnam[256]; -static int pass1(void) -{ - signed char o[2*MAXLINE]; /* doubled for token listing */ - int l,er,al; + i = afile->mn.tmpe; + /* + fprintf(stderr, "ok, ready to insert\n"); + for (i=0; imn.tmp[afile->mn.tmpe+i]); + } + */ - memode=0; - xmode=0; - tlen=0; - ner=0; + offset = afile->mn.tmp[i] + (afile->mn.tmp[i + 1] << 8) + + (afile->mn.tmp[i + 2] << 16); + fstart = afile->mn.tmp[i + 3] + 1 + (afile->mn.tmp[i + 4] << 8); + /* usually redundant but here for single-char names + that get interpreted as chars */ + flen = afile->mn.tmp[i + 5]; + if (flen > 1) + fstart++; + /* now fstart points either to string past quote and + length mark, OR, single char byte */ + /* + fprintf(stderr, "offset = %i length = %i fstart = %i flen = %i charo = %c\n", + offset, ll, fstart, flen, afile->mn.tmp[afile->mn.tmpe+fstart]); + */ + /* there is a race condition here where altering the + file between validation in t_p2 (xat.c) and + here will cause problems. I'm not going to + worry about this right now. */ -/*FIXIT*/ - while(!(er=xa_getline(s))) - { - er=t_p1((signed char*)s,o,&l,&al); - switch(segment) { - case SEG_ABS: - case SEG_TEXT: tlen += al; break; - case SEG_DATA: dlen += al; break; - case SEG_BSS : blen += al; break; - case SEG_ZERO: zlen += al; break; - } - - //printf(": er= %d, l=%d\n",er,l); - - if(l) - { - if(er) - { - if(er==E_OKDEF) - { - if(!(er=puttmpw(l))) - er=puttmps(o,l); - } else - if(er==E_NOLINE) - er=E_OK; - } else - { - if(!(er=puttmpw(-l))) - er=puttmps(o,l); - } - } - if(er) - { - lineout(); - errout(er); - } - -/* printf("tmpz =%d\n",afile->mn.tmpz); -*/ - } - - if(er!=E_EOF) { - errout(er); + for (j = 0; j < flen; j++) { + binfnam[j] = afile->mn.tmp[i + fstart + j]; + } + binfnam[flen] = '\0'; + /* + fprintf(stderr, "fnam = %s\n", binfnam); + */ + /* primitive insurance */ + if (!(foo = fopen(binfnam, "rb"))) { + errout(E_FNF); + ner++; + } else { + fseek(foo, offset, SEEK_SET); + for (j = 0; j < ll; j++) { + /* damn you Andre ;-) */ + i = fgetc(foo); + if (segment < SEG_DATA) { + chrput(i); + } + if (segment == SEG_DATA && datap) { + memset(datap++, i, 1); + } + } + fclose(foo); + } + } else { + errout(er); + } + } + afile->mn.tmpe += abs(l); + } + if (relmode) { + if ((ll = fwrite(dataseg, 1, dlen, fpout)) < dlen) { + fprintf(stderr, "Problems writing %d bytes, return gives %d\n", + dlen, ll); + } } - + return (ner); +} -/* { int i; printf("Pass 1 \n"); - for(i=0;imn.tmpz;i++) - fprintf(stderr, " %02x",255 & afile->mn.tmp[i]); - getchar();} -*/ - return(ner); +static int pass1(void) { + signed char o[2 * MAXLINE]; /* doubled for token listing */ + int l, er, al; + + memode = 0; + xmode = 0; + tlen = 0; + ner = 0; + + /*FIXIT*/ + while (!(er = xa_getline(s))) { + er = t_p1((signed char*) s, o, &l, &al); + switch (segment) { + case SEG_ABS: + case SEG_TEXT: + tlen += al; + break; + case SEG_DATA: + dlen += al; + break; + case SEG_BSS: + blen += al; + break; + case SEG_ZERO: + zlen += al; + break; + } + + //printf(": er= %d, l=%d\n",er,l); + + if (l) { + if (er) { + if (er == E_OKDEF) { + if (!(er = puttmpw(l))) + er = puttmps(o, l); + } else if (er == E_NOLINE) + er = E_OK; + } else { + if (!(er = puttmpw(-l))) + er = puttmps(o, l); + } + } + if (er) { + lineout(); + errout(er); + } + + /* printf("tmpz =%d\n",afile->mn.tmpz); + */ + } + + if (er != E_EOF) { + errout(er); + } + + /* { int i; printf("Pass 1 \n"); + for(i=0;imn.tmpz;i++) + fprintf(stderr, " %02x",255 & afile->mn.tmp[i]); + getchar();} + */ + return (ner); } static void usage(int default816, FILE *fp) @@ -964,7 +995,7 @@ static void usage(int default816, FILE *fp) static char *ertxt[] = { "Syntax", // E_SYNTAX =-1 "Label already defined", // E_LABDEF =-2 - "Label not defined", // E_NODEF =-3 + "Label not defined", // E_NODEF =-3 "Label table full", // E_LABFULL =-4 "Label expected", // E_LABEXP =-5 "Out of memory", // E_NOMEM =-6 @@ -1046,10 +1077,9 @@ static char *ertxt[] = { }; static int gl; -static int gf; +static int gf; -static int x_init(void) -{ +static int x_init(void) { return 0; #if 0 int er=0; @@ -1061,234 +1091,209 @@ static int x_init(void) #endif } -static int puttmp(int c) -{ - int er=E_NOMEM; +static int puttmp(int c) { + int er = E_NOMEM; - //printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz); - - if(afile->mn.tmpzmn.tmp[afile->mn.tmpz++]=c; - er=E_OK; - } - return(er); + //printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz); + + if (afile->mn.tmpz < TMPMEM) { + afile->mn.tmp[afile->mn.tmpz++] = c; + er = E_OK; + } + return (er); } -static int puttmpw(int c) -{ - int er=E_NOMEM; +static int puttmpw(int c) { + int er = E_NOMEM; - //printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz); - - if(afile->mn.tmpzmn.tmp[afile->mn.tmpz++]= c & 0xff; - afile->mn.tmp[afile->mn.tmpz++]= (c >> 8) & 0xff; - er=E_OK; - } - return(er); + //printf("puttmp: %02x -> %p \n",0xff & c, afile->mn.tmp+afile->mn.tmpz); + + if (afile->mn.tmpz < TMPMEM - 1) { + afile->mn.tmp[afile->mn.tmpz++] = c & 0xff; + afile->mn.tmp[afile->mn.tmpz++] = (c >> 8) & 0xff; + er = E_OK; + } + return (er); } -static int puttmps(signed char *s, int l) -{ - int i=0,er=E_NOMEM; - - // printf("puttmps %d bytes from %p to %p:", l, s, afile->mn.tmp+afile->mn.tmpz); - - if(afile->mn.tmpz+lmn.tmp[afile->mn.tmpz++]=s[i++]; - } +static int puttmps(signed char *s, int l) { + int i = 0, er = E_NOMEM; - er=E_OK; - } - // printf("\n"); - return(er); + // printf("puttmps %d bytes from %p to %p:", l, s, afile->mn.tmp+afile->mn.tmpz); + + if (afile->mn.tmpz + l < TMPMEM) { + while (i < l) { + //printf(" %02x", 0xff & s[i]); + afile->mn.tmp[afile->mn.tmpz++] = s[i++]; + } + + er = E_OK; + } + // printf("\n"); + return (er); } static char l[MAXLINE]; -static int xa_getline(char *s) -{ - static int ec; +static int xa_getline(char *s) { + static int ec; - static int i,c; - int hkfl,j,comcom; + static int i, c; + int hkfl, j, comcom; - j=hkfl=comcom=0; - ec=E_OK; + j = hkfl = comcom = 0; + ec = E_OK; - if(!gl) - { - do - { - ec=pgetline(l); - i=0; - while(l[i]==' ') - i++; - while(l[i]!='\0' && isdigit(l[i])) - i++; - gf=1; + if (!gl) { + do { + ec = pgetline(l); + i = 0; + while (l[i] == ' ') + i++; + while (l[i] != '\0' && isdigit(l[i])) + i++; + gf = 1; - if(ec==E_NEWLINE) - { - puttmpw(0); - puttmp(T_LINE); - puttmpw(filep->fline); - ec=E_OK; + if (ec == E_NEWLINE) { + puttmpw(0); + puttmp(T_LINE); + puttmpw(filep->fline); + ec = E_OK; - } - else - if(ec==E_NEWFILE) - { - puttmpw(0); - puttmp(T_FILE); - puttmpw(filep->fline); - puttmps((signed char*)&(filep->fname), sizeof(filep->fname)); - ec=E_OK; - } - } while(!ec && l[i]=='\0'); - } + } else if (ec == E_NEWFILE) { + puttmpw(0); + puttmp(T_FILE); + puttmpw(filep->fline); + puttmps((signed char*) &(filep->fname), sizeof(filep->fname)); + ec = E_OK; + } + } while (!ec && l[i] == '\0'); + } - gl=0; - if(!ec || ec==E_EOF) - { - int startofline = 1; - do { - c=s[j]=l[i++]; + gl = 0; + if (!ec || ec == E_EOF) { + int startofline = 1; + do { + c = s[j] = l[i++]; - if (!(hkfl&2) && c=='\"') - hkfl^=1; - if (!comcom && !(hkfl&1) && c=='\'') - hkfl^=2; - if (c==';' && !hkfl) { - comcom = 1; - } - if (c=='\0') { - // end of line - break; /* hkfl = comcom = 0 */ - } - if (c==':' && !hkfl) { - /* if the next char is a "=" - so that we have a ":=" - and we - we have ca65 compatibility, we ignore the colon */ - // also check for ":+" and ":-" - + if (!(hkfl & 2) && c == '\"') + hkfl ^= 1; + if (!comcom && !(hkfl & 1) && c == '\'') + hkfl ^= 2; + if (c == ';' && !hkfl) { + comcom = 1; + } + if (c == '\0') { + // end of line + break; /* hkfl = comcom = 0 */ + } + if (c == ':' && !hkfl) { + /* if the next char is a "=" - so that we have a ":=" - and we + we have ca65 compatibility, we ignore the colon */ + // also check for ":+" and ":-" //#error gotta get collab into this test - //if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !ca65 || comcom) { - if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !(ca65 || collab) || comcom) { - /* but otherwise we check if it is in a comment and we have - MASM or CA65 compatibility, then we ignore the colon as well */ - if(!comcom || !(masm || ca65 || collab)) { - /* we found a colon, so we keep the current line in memory - but return the part before the colon, and next time the part - after the colon, so we can parse C64 BASIC text assembler... */ - gl=1; - break; + //if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !ca65 || comcom) { + if (((!startofline) && l[i] != '=' && l[i] != '+' && l[i] != '-') + || !(ca65 || collab) || comcom) { + /* but otherwise we check if it is in a comment and we have + MASM or CA65 compatibility, then we ignore the colon as well */ + if (!comcom || !(masm || ca65 || collab)) { + /* we found a colon, so we keep the current line in memory + but return the part before the colon, and next time the part + after the colon, so we can parse C64 BASIC text assembler... */ + gl = 1; + break; + } } } - } - if (!isspace(c)) { - startofline = 0; - } - j++; - } while (c!='\0' && jalign)?a:align; + align = (a > align) ? a : align; } -static void lineout(void) -{ - if(gf) - { - logout(filep->flinep); - logout("\n"); - gf=0; - } -} - -void errout(int er) -{ - if (er<=-ANZERR || er>-1) { - if(er>=-(ANZERR+ANZWARN) && er <= -ANZERR) { - sprintf(out,"%s:line %d: %04x: Warning - %s\n", - filep->fname, filep->fline, pc[segment], ertxt[(-er)-1]); - } else { - /* sprintf(out,"%s:Zeile %d: %04x:Unbekannter Fehler Nr.: %d\n",*/ - sprintf(out,"%s:line %d: %04x: Unknown error # %d\n", - filep->fname,filep->fline,pc[segment],er); - ner++; +static void lineout(void) { + if (gf) { + logout(filep->flinep); + logout("\n"); + gf = 0; } - } else { - if (er==E_NODEF) - sprintf(out,"%s:line %d: %04x:Label '%s' not defined\n", - filep->fname,filep->fline,pc[segment],lz); - else - sprintf(out,"%s:line %d: %04x:%s error\n", - filep->fname,filep->fline,pc[segment],ertxt[(-er)-1]); - - ner++; - } - logout(out); } -static void chrput(int c) -{ - /* printf(" %02x",c&255);*/ +void errout(int er) { + if (er <= -ANZERR || er > -1) { + if (er >= -(ANZERR + ANZWARN) && er <= -ANZERR) { + sprintf(out, "%s:line %d: %04x: Warning - %s\n", filep->fname, + filep->fline, pc[segment], ertxt[(-er) - 1]); + } else { + /* sprintf(out,"%s:Zeile %d: %04x:Unbekannter Fehler Nr.: %d\n",*/ + sprintf(out, "%s:line %d: %04x: Unknown error # %d\n", filep->fname, + filep->fline, pc[segment], er); + ner++; + } + } else { + if (er == E_NODEF) + sprintf(out, "%s:line %d: %04x:Label '%s' not defined\n", + filep->fname, filep->fline, pc[segment], lz); + else + sprintf(out, "%s:line %d: %04x:%s error\n", filep->fname, + filep->fline, pc[segment], ertxt[(-er) - 1]); - putc( c&0x00ff,fpout); + ner++; + } + logout(out); } -void logout(char *s) -{ - fprintf(stderr, "%s",s); - if(fperr) - fprintf(fperr,"%s",s); +static void chrput(int c) { + /* printf(" %02x",c&255);*/ + + putc(c & 0x00ff, fpout); +} + +void logout(char *s) { + fprintf(stderr, "%s", s); + if (fperr) + fprintf(fperr, "%s", s); } /*****************************************************************/ typedef struct { - char *name; - int *flag; + char *name; + int *flag; } compat_set; -static compat_set compat_sets[] = { - { "MASM", &masm }, - { "CA65", &ca65 }, - { "C", &ctypes }, - { "XA23", &xa23 }, - { NULL, NULL } -}; +static compat_set compat_sets[] = { { "MASM", &masm }, { "CA65", &ca65 }, { "C", + &ctypes }, { "XA23", &xa23 }, { NULL, NULL } }; int set_compat(char *compat_name) { - int i = 0; - while (compat_sets[i].name != NULL) { - if (strcmp(compat_sets[i].name, compat_name) == 0) { + int i = 0; + while (compat_sets[i].name != NULL) { + if (strcmp(compat_sets[i].name, compat_name) == 0) { /* set appropriate compatibility flag */ (*compat_sets[i].flag) = 1; /* warn on old versions of xa */ - if (xa23) fprintf(stderr, - "Warning: -XXA23 is explicitly deprecated\n"); + if (xa23) + fprintf(stderr, "Warning: -XXA23 is explicitly deprecated\n"); - return 0; - } - i++; - } - return -1; + return 0; + } + i++; + } + return -1; } - diff --git a/xa/src/xa.h b/xa/src/xa.h index 76c48e5..d9bfe81 100644 --- a/xa/src/xa.h +++ b/xa/src/xa.h @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -41,7 +41,7 @@ extern int dlen, dbase; extern int zlen, zbase; extern int romable, romaddr; -extern int memode,xmode; +extern int memode, xmode; extern int segment; extern int pc[SEG_MAX]; diff --git a/xa/src/xaa.c b/xa/src/xaa.c index 85577f9..c93b5e1 100644 --- a/xa/src/xaa.c +++ b/xa/src/xaa.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * Preprocessing arithmetic module * @@ -30,84 +30,80 @@ #include "xaa.h" #include "xat.h" -static int pr[]= { P_START,P_ADD,P_ADD,P_MULT,P_MULT,P_SHIFT,P_SHIFT,P_CMP, - P_CMP,P_EQU,P_CMP,P_CMP,P_EQU,P_AND,P_XOR,P_OR, - P_LAND,P_LOR,P_EQU,P_START }; +static int pr[] = { P_START, P_ADD, P_ADD, P_MULT, P_MULT, P_SHIFT, P_SHIFT, + P_CMP, + P_CMP, P_EQU, P_CMP, P_CMP, P_EQU, P_AND, P_XOR, P_OR, + P_LAND, P_LOR, P_EQU, P_START }; -static int pp,pcc; +static int pp, pcc; static int fundef; -static int ag_term(signed char*,int,int*,int*,int*); -static int get_op(signed char*,int*); -static int do_op(int*,int,int); +static int ag_term(signed char*, int, int*, int*, int*); +static int get_op(signed char*, int*); +static int do_op(int*, int, int); /* s = string, v = variable */ -int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f) -{ - int er=E_OK; - int afl = 0, bfl; +int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f) { + int er = E_OK; + int afl = 0, bfl; - *pfl = 0; - fundef = f; + *pfl = 0; + fundef = f; - pp=0; - pcc=xpc; + pp = 0; + pcc = xpc; - if(s[0]=='<') - { - pp++; - er=ag_term(s,P_START,v,&afl, label); - bfl = afl & (A_MASK>>8); - if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_LOW>>8)) ) { -/*fprintf(stderr,"low byte relocation for a high byte - won't work!\n");*/ - errout(W_LOWACC); - } - if(afl) *pfl=A_LOW | ((afl<<8) & A_FMASK); - *v = *v & 255; - } else - if(s[pp]=='>') - { - pp++; - er=ag_term(s,P_START,v,&afl, label); - bfl = afl & (A_MASK>>8); - if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_HIGH>>8)) ) { -/*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); - *v=(*v>>8)&255; - } - else - if(s[pp]!=T_END) { - er=ag_term(s,P_START,v,&afl, label); - bfl = afl & (A_MASK>>8); - if(bfl && (bfl != (A_ADR>>8)) ) { -/*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/ - errout(W_ADDRACC); - } - if(afl) *pfl = A_ADR | ((afl<<8) & A_FMASK); - } else { - er = E_SYNTAX; - } + if (s[0] == '<') { + pp++; + er = ag_term(s, P_START, v, &afl, label); + bfl = afl & (A_MASK >> 8); + if (bfl && (bfl != (A_ADR >> 8)) && (bfl != (A_LOW >> 8))) { + /*fprintf(stderr,"low byte relocation for a high byte - won't work!\n");*/ + errout(W_LOWACC); + } + if (afl) + *pfl = A_LOW | ((afl << 8) & A_FMASK); + *v = *v & 255; + } else if (s[pp] == '>') { + pp++; + er = ag_term(s, P_START, v, &afl, label); + bfl = afl & (A_MASK >> 8); + if (bfl && (bfl != (A_ADR >> 8)) && (bfl != (A_HIGH >> 8))) { + /*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); + *v = (*v >> 8) & 255; + } else if (s[pp] != T_END) { + er = ag_term(s, P_START, v, &afl, label); + bfl = afl & (A_MASK >> 8); + if (bfl && (bfl != (A_ADR >> 8))) { + /*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/ + errout(W_ADDRACC); + } + if (afl) + *pfl = A_ADR | ((afl << 8) & A_FMASK); + } 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); - return(er); + return (er); } -static int ag_term(signed char *s, int p, int *v, int *nafl, int *label) -{ - int er=E_OK,o,w,mf=1,afl; +static int ag_term(signed char *s, int p, int *v, int *nafl, int *label) { + 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]); - while(s[pp]=='-') - { - pp++; - mf=-mf; - } + while (s[pp] == '-') { + pp++; + mf = -mf; + } #if(0) /* NYI: this is hacked into .assert for now */ 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); } else #endif - if(s[pp]=='(') - { - pp++; - if(!(er=ag_term(s,P_START,v,&afl,label))) - { - if(s[pp]!=')') - er=E_SYNTAX; - else - pp++; - } - } else - if(s[pp]==T_LABEL) - { - er=l_get(cval(s+pp+1),v, &afl); + if (s[pp] == '(') { + pp++; + if (!(er = ag_term(s, P_START, v, &afl, label))) { + if (s[pp] != ')') + er = E_SYNTAX; + else + pp++; + } + } 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", - er, segment, afl, nolink, fundef); -*/ - if(er==E_NODEF && segment != SEG_ABS && fundef ) { - if( nolink || ((afl==SEG_UNDEF) || (afl==SEG_UNDEFZP))) { - er = E_OK; - *v = 0; - if(afl!=SEG_UNDEFZP) { - afl = SEG_UNDEF; - } - *label = cval(s+pp+1); - } - } - pp+=3; - } - else - if(s[pp]==T_VALUE || s[pp] == T_CAST) - { - while (s[pp] == T_CAST) { - pp+=2; - } - *v=lval(s+pp+1); - pp+=5; -/* -printf("value: v=%04x\n",*v); -*/ - } - else - if(s[pp]==T_POINTER) - { - afl = s[pp+1]; - *v=cval(s+pp+2); - pp+=6; -/* -printf("pointer: v=%04x, afl=%04x\n",*v,afl); -*/ - } - else - if(s[pp]=='*') - { - *v=pcc; - pp++; - afl = segment; - } - else { - er=E_SYNTAX; + /* + printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n", + er, segment, afl, nolink, fundef); + */ + if (er == E_NODEF && segment != SEG_ABS && fundef) { + if (nolink || ((afl == SEG_UNDEF) || (afl == SEG_UNDEFZP))) { + er = E_OK; + *v = 0; + if (afl != SEG_UNDEFZP) { + afl = SEG_UNDEF; + } + *label = cval(s + pp + 1); + } + } + pp += 3; + } else if (s[pp] == T_VALUE || s[pp] == T_CAST) { + while (s[pp] == T_CAST) { + pp += 2; + } + *v = lval(s + pp + 1); + pp += 5; + /* + printf("value: v=%04x\n",*v); + */ + } else if (s[pp] == T_POINTER) { + afl = s[pp + 1]; + *v = cval(s + pp + 2); + pp += 6; + /* + printf("pointer: v=%04x, afl=%04x\n",*v,afl); + */ + } 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]); - er=get_op(s,&o); + er = get_op(s, &o); - if(!er && pr[o]>p) - { - pp+=1; - if(!(er=ag_term(s,pr[o],&w, nafl, label))) - { - if(afl || *nafl) { /* check pointer arithmetic */ - if((afl == *nafl) && (afl!=SEG_UNDEFZP) && (afl!=SEG_UNDEF) && o==2) { - afl = 0; /* subtract two pointers */ - } else - if(((afl && !*nafl) || (*nafl && !afl)) && o==1) { - afl=(afl | *nafl); /* add constant to pointer */ - } else - if((afl && !*nafl) && o==2) { - afl=(afl | *nafl); /* subtract constant from pointer */ - } else { - if((!afl && *nafl) && o==2) { - /* subtract pointer from constant */ - errout(W_SUBTRACT); + if (!er && pr[o] > p) { + pp += 1; + if (!(er = ag_term(s, pr[o], &w, nafl, label))) { + if (afl || *nafl) { /* check pointer arithmetic */ + if ((afl == *nafl) && (afl != SEG_UNDEFZP) + && (afl != SEG_UNDEF) && o == 2) { + afl = 0; /* subtract two pointers */ + } else if (((afl && !*nafl) || (*nafl && !afl)) && o == 1) { + afl = (afl | *nafl); /* add constant to pointer */ + } else if ((afl && !*nafl) && o == 2) { + afl = (afl | *nafl); /* subtract constant from pointer */ + } else { + if ((!afl && *nafl) && o == 2) { + /* subtract pointer from constant */ + errout(W_SUBTRACT); + } + /* allow math in the same segment */ + 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 */ - 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); - } - } 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]); + } else { + break; + } } - printf("\n"); -*/ - er=E_SYNTAX; - } else { - er=E_OK; - } - - return(er); -} - -static int do_op(int *w,int w2,int o) -{ - int er=E_OK; - switch (o) { - case 1: - *w +=w2; - break; - case 2: - *w -=w2; - break; - case 3: - *w *=w2; - break; - case 4: - if (w2!=0) - *w /=w2; - else - er =E_DIV; - break; - case 5: - *w >>=w2; - break; - case 6: - *w <<=w2; - break; - case 7: - *w = *ww2; - break; - case 9: - *w = *w==w2; - break; - case 10: - *w = *w<=w2; - break; - case 11: - *w = *w>=w2; - break; - case 12: - *w = *w!=w2; - break; - case 13: - *w &=w2; - 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); + *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"); + */ + er = E_SYNTAX; + } else { + er = E_OK; + } + + return (er); +} + +static int do_op(int *w, int w2, int o) { + int er = E_OK; + switch (o) { + case 1: + *w += w2; + break; + case 2: + *w -= w2; + break; + case 3: + *w *= w2; + break; + case 4: + if (w2 != 0) + *w /= w2; + else + er = E_DIV; + break; + case 5: + *w >>= w2; + break; + case 6: + *w <<= w2; + break; + case 7: + *w = *w < w2; + break; + case 8: + *w = *w > w2; + break; + case 9: + *w = *w == w2; + break; + case 10: + *w = *w <= w2; + break; + case 11: + *w = *w >= w2; + break; + case 12: + *w = *w != w2; + break; + case 13: + *w &= w2; + 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); } diff --git a/xa/src/xacharset.c b/xa/src/xacharset.c index 4f74b48..fd504e7 100644 --- a/xa/src/xacharset.c +++ b/xa/src/xacharset.c @@ -20,7 +20,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include @@ -58,11 +57,11 @@ static signed char convert_char_petscii(signed char c) { static signed char convert_char_petscreen(signed char c) { int i; - i = (int)convert_char_petscii(c); + i = (int) convert_char_petscii(c); #ifdef SIGH fprintf(stderr, "input: %i output: %i\n", c, i); #endif - if (i< 0) + if (i < 0) i += 0x80; i ^= 0xe0; #ifdef SIGH @@ -74,36 +73,36 @@ fprintf(stderr, "(1)input: %i output: %i\n", c, i); fprintf(stderr, "(2)input: %i output: %i\n", c, i); #endif if (i < 0x80) - return (signed char)i; + return (signed char) i; i += 0x40; i &= 0xff; #ifdef SIGH fprintf(stderr, "(3)input: %i output: %i\n", c, i); #endif if (i < 0x80) - return (signed char)i; + return (signed char) i; i ^= 0xa0; #ifdef SIGH fprintf(stderr, "(4)input: %i output: %i\n", c, i); #endif - return (signed char)i; + return (signed char) i; } static signed char convert_char_high(signed char c) { return (c | 0x80); } - -typedef struct { + +typedef struct { char *name; signed char (*func)(signed char); } charset; static charset charsets[] = { - { "ASCII", convert_char_ascii }, - { "PETSCII", convert_char_petscii }, - { "PETSCREEN", convert_char_petscreen }, - { "HIGH", convert_char_high }, - { NULL, NULL } + { "ASCII", convert_char_ascii }, + { "PETSCII", convert_char_petscii }, + { "PETSCREEN", convert_char_petscreen }, + { "HIGH", convert_char_high }, + { NULL, NULL } }; int set_charset(char *charset_name) { @@ -122,4 +121,3 @@ signed char convert_char(signed char c) { return convert_func(c); } - diff --git a/xa/src/xah.h b/xa/src/xah.h index 1d3321e..913c9fa 100644 --- a/xa/src/xah.h +++ b/xa/src/xah.h @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * Maintained by Cameron Kaiser * * 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) */ typedef enum { - STD = 0, - CHEAP = 1, - UNNAMED = 2, - UNNAMED_DEF = 3 + STD = 0, CHEAP = 1, UNNAMED = 2, UNNAMED_DEF = 3 } xalabel_t; typedef struct LabOcc { @@ -58,14 +55,14 @@ typedef struct { int origblk; // only for fl=3 int val; int len; - int fl; /* 0 = label value not valid/known, - * 1 = label value known - * 2 = label value not known, external global label (imported on link) - * 3 = label value not known, temporarily on external global label list (for -U) - */ - int afl; /* 0 = no address (no relocation), 1 = address label */ + int fl; /* 0 = label value not valid/known, + * 1 = label value known + * 2 = label value not known, external global label (imported on link) + * 3 = label value not known, temporarily on external global label list (for -U) + */ + int afl; /* 0 = no address (no relocation), 1 = address label */ 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; struct LabOcc *occlist; // within a block, make a linked list for the unnamed label counting @@ -83,7 +80,6 @@ typedef struct { int nextindex; } List; - #define MEMLEN (4 + TMPMEM + MAXPP + LABMEM + \ (long)(sizeof (Labtab) * ANZLAB) + \ (long)(sizeof (List) * ANZDEF)) @@ -91,9 +87,9 @@ typedef struct { #define DIRCHAR '/' #define DIRCSTRING "/" /* for Atari: -#define DIRCHAR '\\' -#define DIRCSTRING "\\" -*/ + #define DIRCHAR '\\' + #define DIRCSTRING "\\" + */ #define BUFSIZE 4096 /* File-Puffegroesse (wg Festplatte) */ @@ -219,7 +215,7 @@ typedef struct { #define SEG_UNDEFZP 7 /* is being mapped to UNDEF */ typedef struct Fopt { - signed char *text; /* text after pass1 */ + signed char *text; /* text after pass1 */ int len; } Fopt; diff --git a/xa/src/xah2.h b/xa/src/xah2.h index 2b64cc3..992009b 100644 --- a/xa/src/xah2.h +++ b/xa/src/xah2.h @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -20,7 +20,7 @@ #define __XA65_XAH2_H__ typedef struct { - char *fname; /* fname[MAXLINE]; */ + char *fname; /* fname[MAXLINE]; */ int fline; int bdepth; FILE *filep; diff --git a/xa/src/xal.c b/xa/src/xal.c index 4965f7c..fbed9ae 100644 --- a/xa/src/xal.c +++ b/xa/src/xal.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * Label management module (also see xau.c) * @@ -40,15 +40,15 @@ /* exported globals */ -char *lz; +char *lz; /* local prototypes */ -static int b_fget(int*,int); -static int b_ltest(int,int); +static int b_fget(int*, int); +static int b_ltest(int, int); static int b_get(int*); static int b_test(int); -static int ll_def(char *s, int *n, int b, xalabel_t ltype); +static int ll_def(char *s, int *n, int b, xalabel_t ltype); static int b_link(int); static int b_new(void); @@ -58,70 +58,63 @@ static int cll_get(); static void cll_clear(); static int cll_getcur(); - static Labtab *ltp; -int l_init(void) -{ +int l_init(void) { cll_init(); //unn_init(); return 0; } -int ga_lab(void) -{ - return(afile->la.lti); +int ga_lab(void) { + return (afile->la.lti); } -int gm_lab(void) -{ - return(ANZLAB); +int gm_lab(void) { + return (ANZLAB); } -long gm_labm(void) -{ - return((long)LABMEM); +long gm_labm(void) { + return ((long) LABMEM); } -long ga_labm(void) -{ - return(0 /*lni*/); +long ga_labm(void) { + return (0 /*lni*/); } void printllist(fp) -FILE *fp; -{ - int i; - LabOcc *p; - char *fname = NULL; + FILE *fp; { + int i; + LabOcc *p; + char *fname = NULL; - for(i=0;ila.lti;i++) - { - ltp=afile->la.lt+i; - fprintf(fp,"%s, 0x%04x, %d, 0x%04x\n",ltp->n,ltp->val,ltp->blk, - ltp->afl); - p = ltp->occlist; - if(p) { - while(p) { - if(fname != p->fname) { - if(p!=ltp->occlist) fprintf(fp,"\n"); - fprintf(fp," %s",p->fname); - fname=p->fname; - } - fprintf(fp," %d", p->line); - p=p->next; - } - fprintf(fp,"\n"); - } - fname=NULL; - } + for (i = 0; i < afile->la.lti; i++) { + ltp = afile->la.lt + i; + fprintf(fp, "%s, 0x%04x, %d, 0x%04x\n", ltp->n, ltp->val, ltp->blk, + ltp->afl); + p = ltp->occlist; + if (p) { + while (p) { + if (fname != p->fname) { + if (p != ltp->occlist) + fprintf(fp, "\n"); + fprintf(fp, " %s", p->fname); + fname = p->fname; + } + fprintf(fp, " %d", p->line); + p = p->next; + } + fprintf(fp, "\n"); + } + fname = NULL; + } } /********************************************************************************** * cheap local labels */ -static int cll_current = 0; /* the current cheap local labels block */ +static int cll_current = 0; /* the current cheap local labels block */ /** * init the cheap local labels @@ -156,18 +149,18 @@ int cll_getcur() { /** * define a global label (from the "-L" command line parameter) */ -int lg_set(char *s ) { +int lg_set(char *s) { int n, er; - er = ll_search(s,&n, STD); + er = ll_search(s, &n, STD); - if(er==E_OK) { - fprintf(stderr,"Warning: global label doubly defined!\n"); + if (er == E_OK) { + fprintf(stderr, "Warning: global label doubly defined!\n"); } else { - if(!(er=ll_def(s,&n,0, STD))) { - return lg_import(n); - } - } + if (!(er = ll_def(s, &n, 0, STD))) { + return lg_import(n); + } + } return er; } @@ -177,11 +170,11 @@ int lg_set(char *s ) { * or at non-alphanumeric/_ char */ int lg_import(int n) { - int er=E_OK; + int er = E_OK; - ltp=afile->la.lt+n; - ltp->fl=2; - ltp->afl=SEG_UNDEF; + ltp = afile->la.lt + n; + ltp->fl = 2; + ltp->afl = SEG_UNDEF; return er; } @@ -190,267 +183,243 @@ int lg_import(int n) { * re-define a previously undef'd label as globally undefined * (for -U option) */ -int lg_toglobal(char *s ) { +int lg_toglobal(char *s) { int n, er; //printf("lg_toglobal(%s)\n", s); - er = ll_search(s,&n, STD); + er = ll_search(s, &n, STD); - if(er==E_OK && ltp->fl != 3) { + if (er == E_OK && ltp->fl != 3) { // fonnd, but not yet set as global undef'd label - ltp=afile->la.lt+n; - ltp->fl=3; - ltp->afl=SEG_UNDEF; - ltp->origblk=ltp->blk; - ltp->blk=0; - } + ltp = afile->la.lt + n; + ltp->fl = 3; + ltp->afl = SEG_UNDEF; + ltp->origblk = ltp->blk; + ltp->blk = 0; + } return er; } - /** * define a global zeropage label (from the .importzp pseudo opcode)) * "s" is a pointer to the first label character, end is at \0 * or at non-alphanumeric/_ char */ int lg_importzp(int n) { - int er=E_OK; + int er = E_OK; - ltp=afile->la.lt+n; - ltp->fl=2; - ltp->afl=SEG_UNDEFZP; + ltp = afile->la.lt + n; + ltp->fl = 2; + ltp->afl = SEG_UNDEFZP; return er; } /**********************************************************************************/ - -int l_def(char *s, int *l, int *x, int *f) -{ - int n,er,b,i=0; - xalabel_t cll_fl; - - *f=0; /* flag (given as param) that the label is to be re-defined and the - "label defined error" is to be skipped */ - b=0; /* block level on block stack, resp. block number */ - n=0; /* flag, when set, b is absolute block number and not being translated */ - cll_fl=STD; /* when 0, clear the cheap local label block */ - if(s[0]==':') { - // ca65 unnamed label - i++; - //n++; /* block number b is absolute */ - //b=unn_get(); /* current (possibly newly allocated) unnamed label block */ - cll_fl = UNNAMED; // keep the cheap local label block - } else - if(s[0]=='-') - { - *f+=1; /* label is being redefined */ - i++; - } else - if(s[0]=='@') - { - i++; - n++; /* block number b is absolute */ - b=cll_get(); /* current (possibly newly allocated) cheap label block */ - cll_fl=CHEAP; /* do not clear the cll block again... */ - } else - if(s[0]=='+') - { - i++; - n++; /* block number b is absolute */ - b=0; /* global block number */ - } - while(s[i]=='&') - { - if (n) b=0; /* reset block number */ - n=0; /* block number is relative */ - i++; - b++; /* one (more) level up the block stack */ - } - if(!n) { - /* translate from block stack level to absolute block number */ - b_fget(&b,b); - } +int l_def(char *s, int *l, int *x, int *f) { + int n, er, b, i = 0; + xalabel_t cll_fl; - if(cll_fl == STD) { - /* clear cheap local labels */ - cll_clear(); - } + *f = 0; /* flag (given as param) that the label is to be re-defined and the + "label defined error" is to be skipped */ + b = 0; /* block level on block stack, resp. block number */ + n = 0; /* flag, when set, b is absolute block number and not being translated */ + cll_fl = STD; /* when 0, clear the cheap local label block */ - if((!isalpha(s[i])) && (s[i]!='_') && !((ca65 || collab) && ((cll_fl == UNNAMED) || isdigit(s[i])) ) ) { - //printf("SYNTAX ca65=%d collab=%d cll_fl=%d, i=%d, s[i]=%02x (%c)\n", ca65, collab, cll_fl, i, s[i], s[i]); - er=E_SYNTAX; - } else - { - er = E_NODEF; - if (cll_fl != UNNAMED) { - er=ll_search(s+i,&n, cll_fl); - } - - if(er==E_OK) - { - //printf("l_def OK: cll_fl=%d, i=%d, s=%s\n", cll_fl, i, s); - /* we actually found an existing label in the same scope */ - ltp=afile->la.lt+n; - - if(*f) - { - /* redefinition of label */ - *l=ltp->len+i; - } else - if(ltp->fl == 0) - { - /* label has not been defined yet, (e.g. pass1 forward ref), so we try to set it. */ - *l=ltp->len+i; - if(b_ltest(ltp->blk,b)) - er=E_LABDEF; - else - ltp->blk=b; + if (s[0] == ':') { + // ca65 unnamed label + i++; + //n++; /* block number b is absolute */ + //b=unn_get(); /* current (possibly newly allocated) unnamed label block */ + cll_fl = UNNAMED; // keep the cheap local label block + } else if (s[0] == '-') { + *f += 1; /* label is being redefined */ + i++; + } else if (s[0] == '@') { + i++; + n++; /* block number b is absolute */ + b = cll_get(); /* current (possibly newly allocated) cheap label block */ + cll_fl = CHEAP; /* do not clear the cll block again... */ + } else if (s[0] == '+') { + i++; + n++; /* block number b is absolute */ + b = 0; /* global block number */ + } + while (s[i] == '&') { + if (n) + b = 0; /* reset block number */ + n = 0; /* block number is relative */ + i++; + b++; /* one (more) level up the block stack */ + } + if (!n) { + /* translate from block stack level to absolute block number */ + b_fget(&b, b); + } - } else - if(ltp->fl == 3) - { - /* label has been defined as -U undef'd label so far - we need to check */ - *l=ltp->len+i; - if(b_ltest(ltp->origblk,b)) - er=E_LABDEF; - else - ltp->blk=b; + if (cll_fl == STD) { + /* clear cheap local labels */ + cll_clear(); + } - } else - er=E_LABDEF; - } else - if(er==E_NODEF) - { + if ((!isalpha(s[i])) && (s[i] != '_') + && !((ca65 || collab) && ((cll_fl == UNNAMED) || isdigit(s[i])))) { + //printf("SYNTAX ca65=%d collab=%d cll_fl=%d, i=%d, s[i]=%02x (%c)\n", ca65, collab, cll_fl, i, s[i], s[i]); + er = E_SYNTAX; + } else { + er = E_NODEF; + if (cll_fl != UNNAMED) { + er = ll_search(s + i, &n, cll_fl); + } - if(!(er=ll_def(s+i,&n,b, cll_fl) )) /* store the label in the table of labels */ - { - ltp=afile->la.lt+n; - *l=ltp->len+i; - ltp->fl=0; - ltp->is_cll=cll_fl; - } - //printf("l_def NODEF: n=%d, s=%s\n", n, ltp->n); - } + if (er == E_OK) { + //printf("l_def OK: cll_fl=%d, i=%d, s=%s\n", cll_fl, i, s); + /* we actually found an existing label in the same scope */ + ltp = afile->la.lt + n; - *x=n; - } - return(er); + if (*f) { + /* redefinition of label */ + *l = ltp->len + i; + } else if (ltp->fl == 0) { + /* label has not been defined yet, (e.g. pass1 forward ref), so we try to set it. */ + *l = ltp->len + i; + if (b_ltest(ltp->blk, b)) + er = E_LABDEF; + else + ltp->blk = b; + + } else if (ltp->fl == 3) { + /* label has been defined as -U undef'd label so far - we need to check */ + *l = ltp->len + i; + if (b_ltest(ltp->origblk, b)) + er = E_LABDEF; + else + ltp->blk = b; + + } else + er = E_LABDEF; + } else if (er == E_NODEF) { + + if (!(er = ll_def(s + i, &n, b, cll_fl))) /* store the label in the table of labels */ + { + ltp = afile->la.lt + n; + *l = ltp->len + i; + ltp->fl = 0; + ltp->is_cll = cll_fl; + } + //printf("l_def NODEF: n=%d, s=%s\n", n, ltp->n); + } + + *x = n; + } + return (er); } -int l_search(char *s, int *l, int *x, int *v, int *afl) -{ - int n,er,b; - xalabel_t cll_fl; +int l_search(char *s, int *l, int *x, int *v, int *afl) { + int n, er, b; + xalabel_t cll_fl; - *afl=0; + *afl = 0; - /* check cheap local label */ - cll_fl=STD; - if (s[0]=='@') { - cll_fl=CHEAP; - s++; - } else - if (s[0]==':') { - cll_fl = UNNAMED_DEF; - s++; - } - - er = E_NODEF; - if (cll_fl != UNNAMED_DEF) { - er=ll_search(s,&n, cll_fl); - } + /* check cheap local label */ + cll_fl = STD; + if (s[0] == '@') { + cll_fl = CHEAP; + s++; + } else if (s[0] == ':') { + cll_fl = UNNAMED_DEF; + s++; + } + + er = E_NODEF; + if (cll_fl != UNNAMED_DEF) { + er = ll_search(s, &n, cll_fl); + } //printf("l_search: lab=%s(afl=%d, er=%d, cll_fl=%d, cll_cur=%d)\n",s,*afl,er, cll_fl, cll_getcur()); - if(er==E_OK) - { - ltp=afile->la.lt+n; - *l=ltp->len + ((cll_fl == STD) ? 0 : 1); - if(ltp->fl == 1) - { - l_get(n,v,afl);/* *v=lt[n].val;*/ - *x=n; - } else - { - er=E_NODEF; - lz=ltp->n; - *x=n; - } - } - else - { - if(cll_fl == CHEAP) { - b=cll_get(); - } else - if(cll_fl == UNNAMED_DEF) { - b_get(&b); // b=unn_get(); - } else { - b_get(&b); - } - - er=ll_def(s,x,b, cll_fl); /* ll_def(...,*v); */ + if (er == E_OK) { + ltp = afile->la.lt + n; + *l = ltp->len + ((cll_fl == STD) ? 0 : 1); + if (ltp->fl == 1) { + l_get(n, v, afl);/* *v=lt[n].val;*/ + *x = n; + } else { + er = E_NODEF; + lz = ltp->n; + *x = n; + } + } else { + if (cll_fl == CHEAP) { + b = cll_get(); + } else if (cll_fl == UNNAMED_DEF) { + b_get(&b); // b=unn_get(); + } else { + b_get(&b); + } - ltp=afile->la.lt+(*x); - ltp->is_cll = cll_fl; + er = ll_def(s, x, b, cll_fl); /* ll_def(...,*v); */ - *l=ltp->len + ((cll_fl == STD) ? 0 : 1); - //*l=ltp->len + cll_fl; + ltp = afile->la.lt + (*x); + ltp->is_cll = cll_fl; - if(!er) - { - er=E_NODEF; - lz=ltp->n; - } - } - return(er); + *l = ltp->len + ((cll_fl == STD) ? 0 : 1); + //*l=ltp->len + cll_fl; + + if (!er) { + er = E_NODEF; + lz = ltp->n; + } + } + return (er); } -int l_vget(int n, int *v, char **s) -{ - ltp=afile->la.lt+n; - (*v)=ltp->val; - *s=ltp->n; - return 0; +int l_vget(int n, int *v, char **s) { + ltp = afile->la.lt + n; + (*v) = ltp->val; + *s = ltp->n; + return 0; } void l_addocc(int n, int *v, int *afl) { - LabOcc *p, *pp; + LabOcc *p, *pp; - (void)v; /* quench warning */ - (void)afl; /* quench warning */ - ltp = afile->la.lt+n; - pp=NULL; - p = ltp->occlist; - while(p) { - if (p->line == filep->fline && p->fname == filep->fname) return; - pp = p; - p = p->next; - } - p = malloc(sizeof(LabOcc)); - if(!p) { - fprintf(stderr,"Oops, out of memory!\n"); - exit(1); - } - p->next = NULL; - p->line = filep->fline; - p->fname = filep->fname; - if(pp) { - pp->next = p; - } else { - ltp->occlist = p; - } + (void) v; /* quench warning */ + (void) afl; /* quench warning */ + ltp = afile->la.lt + n; + pp = NULL; + p = ltp->occlist; + while (p) { + if (p->line == filep->fline && p->fname == filep->fname) + return; + pp = p; + p = p->next; + } + p = malloc(sizeof(LabOcc)); + if (!p) { + fprintf(stderr, "Oops, out of memory!\n"); + exit(1); + } + p->next = NULL; + p->line = filep->fline; + p->fname = filep->fname; + if (pp) { + pp->next = p; + } else { + ltp->occlist = p; + } } /* for the list functionality */ -char *l_get_name(int n, xalabel_t *is_cll) { - if (n > afile->la.ltm) { - fprintf(stderr, "Corrupted structures! n=%d, but max=%d\n", n, afile->la.ltm); - exit(1); - } - ltp=afile->la.lt+n; - *is_cll = ltp->is_cll; - return ltp->n; +char* l_get_name(int n, xalabel_t *is_cll) { + if (n > afile->la.ltm) { + fprintf(stderr, "Corrupted structures! n=%d, but max=%d\n", n, + afile->la.ltm); + exit(1); + } + ltp = afile->la.lt + n; + *is_cll = ltp->is_cll; + return ltp->n; } // works on the static(!) ltp "label table pointer" @@ -465,164 +434,159 @@ static int resolve_unnamed() { nextp = -1; if (c == '+') { nextp = ltp->blknext; - } else - if (c == '-') { + } else if (c == '-') { nextp = ltp->blkprev; } //printf("::: nextp=%d\n", nextp); if (nextp == -1) { return -1; // E_NODEF } - ltp = afile->la.lt+nextp; + ltp = afile->la.lt + nextp; //printf("::: leads to: %s, nextp=%d\n", ltp->n, nextp); if (ltp->is_cll == UNNAMED) { namep++; } - } + } return nextp; } /* for the listing, esp. html links; returns a pointer to a static buffer, available till next call */ -char *l_get_unique_name(int n) { - static char buf[MAXLINE]; - ltp=afile->la.lt+n; - - if (ltp->is_cll == CHEAP || ltp->is_cll == STD) { - sprintf(buf, "%d%c%s", ltp->blk, - (ltp->is_cll == CHEAP) ? 'C' : '_', - ltp->n); - } else - if (ltp->is_cll == UNNAMED) { - // definition of unnamed label - name is NULL - // so use the actual index - sprintf(buf, "%dU%d", ltp->blk, n); - } else - if (ltp->is_cll == UNNAMED_DEF) { - // we actually need to find the correct label from the "+" and "-" - // in the name - int tmp = resolve_unnamed(); - if (tmp >= 0) { - sprintf(buf, "%dU%d", ltp->blk, tmp); +char* l_get_unique_name(int n) { + static char buf[MAXLINE]; + ltp = afile->la.lt + n; + + if (ltp->is_cll == CHEAP || ltp->is_cll == STD) { + sprintf(buf, "%d%c%s", ltp->blk, (ltp->is_cll == CHEAP) ? 'C' : '_', + ltp->n); + } else if (ltp->is_cll == UNNAMED) { + // definition of unnamed label - name is NULL + // so use the actual index + sprintf(buf, "%dU%d", ltp->blk, n); + } else if (ltp->is_cll == UNNAMED_DEF) { + // we actually need to find the correct label from the "+" and "-" + // in the name + int tmp = resolve_unnamed(); + if (tmp >= 0) { + sprintf(buf, "%dU%d", ltp->blk, tmp); + } else { + sprintf(buf, "__%d", tmp); + } } else { - sprintf(buf, "__%d", tmp); + buf[0] = 0; // no value } - } else { - buf[0] = 0; // no value - } - return buf; + return buf; } -int l_get(int n, int *v, int *afl) -{ - if(crossref) l_addocc(n,v,afl); +int l_get(int n, int *v, int *afl) { + if (crossref) + l_addocc(n, v, afl); - ltp = afile->la.lt+n; + ltp = afile->la.lt + n; - if (ltp->is_cll == UNNAMED_DEF) { - int tmp = resolve_unnamed(); - if (tmp == -1) return E_NODEF; - // now ltp is set to the actual label - } - (*v)=ltp->val; - lz=ltp->n; - *afl = ltp->afl; -/*printf("l_get('%s'(%d), v=$%04x, afl=%d, fl=%d\n",ltp->n, n, *v, *afl, ltp->fl);*/ - return( (ltp->fl==1) ? E_OK : E_NODEF); + if (ltp->is_cll == UNNAMED_DEF) { + int tmp = resolve_unnamed(); + if (tmp == -1) + return E_NODEF; + // now ltp is set to the actual label + } + (*v) = ltp->val; + lz = ltp->n; + *afl = ltp->afl; + /*printf("l_get('%s'(%d), v=$%04x, afl=%d, fl=%d\n",ltp->n, n, *v, *afl, ltp->fl);*/ + return ((ltp->fl == 1) ? E_OK : E_NODEF); } -void l_set(int n, int v, int afl) -{ - ltp=afile->la.lt+n; - ltp->val = v; - ltp->fl = 1; - ltp->afl = afl; +void l_set(int n, int v, int afl) { + ltp = afile->la.lt + n; + ltp->val = v; + ltp->fl = 1; + ltp->afl = afl; //printf("l_set('%s'(%d), v=$%04x, afl=%d\n",ltp->n, n, v, afl); } -static void ll_exblk(int a, int b) -{ - int i; - for (i=0;ila.lti;i++) - { - ltp=afile->la.lt+i; - if((!ltp->fl) && (ltp->blk==a)) - ltp->blk=b; - } +static void ll_exblk(int a, int b) { + int i; + for (i = 0; i < afile->la.lti; i++) { + ltp = afile->la.lt + i; + if ((!ltp->fl) && (ltp->blk == a)) + ltp->blk = b; + } } -/* defines next label, returns new label number in out param n */ -static int ll_def(char *s, int *n, int b, xalabel_t ltype) -{ - int j=0,er=E_NOMEM,hash; - char *s2 = NULL; +/* defines next label, returns new label number in out param n */ +static int ll_def(char *s, int *n, int b, xalabel_t ltype) { + int j = 0, er = E_NOMEM, hash; + char *s2 = NULL; //printf("ll_def: s=%s, ltype=%d, no_name=%d\n",s, ltype, no_name); - // label table for the file ... - if(!afile->la.lt) { - // ... does not exist yet, so malloc it - afile->la.lti = 0; - afile->la.ltm = 1000; - afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab)); - } - if(afile->la.lti>=afile->la.ltm) { - // ... or is at its capacity limit, so realloc it - afile->la.ltm *= 1.5; - afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab)); - } - if(!afile->la.lt) { - fprintf(stderr, "Oops: no memory!\n"); - exit(1); - } + // label table for the file ... + if (!afile->la.lt) { + // ... does not exist yet, so malloc it + afile->la.lti = 0; + afile->la.ltm = 1000; + afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab)); + } + if (afile->la.lti >= afile->la.ltm) { + // ... or is at its capacity limit, so realloc it + afile->la.ltm *= 1.5; + afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab)); + } + if (!afile->la.lt) { + fprintf(stderr, "Oops: no memory!\n"); + exit(1); + } - // current pointer in label table - ltp = afile->la.lt + afile->la.lti; + // current pointer in label table + ltp = afile->la.lt + afile->la.lti; - if (ltype != UNNAMED) { - // alloc space and copy over name + if (ltype != UNNAMED) { + // alloc space and copy over name if (ltype == UNNAMED_DEF) { // unnamed lables are like ":--" or ":+" with variable length - while((s[j]!='\0') && (s[j]=='+' || s[j]=='-')) j++; + while ((s[j] != '\0') && (s[j] == '+' || s[j] == '-')) + j++; } else { // standard (and cheap) labels are normal text - while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++; + while ((s[j] != '\0') && (isalnum(s[j]) || (s[j] == '_'))) + j++; } - s2 = malloc(j+1); - if(!s2) { - fprintf(stderr,"Oops: no memory!\n"); - exit(1); - } - strncpy(s2,s,j); - s2[j]=0; - } + s2 = malloc(j + 1); + if (!s2) { + fprintf(stderr, "Oops: no memory!\n"); + exit(1); + } + strncpy(s2, s, j); + s2[j] = 0; + } - // init new entry in label table - er=E_OK; - ltp->len=j; // length of label - ltp->n = s2; // name of label (char*) - ltp->blk=b; // block number - ltp->fl=0; - ltp->afl=0; - ltp->is_cll=ltype; // STD, CHEAP, or UNNAMED label - ltp->occlist=NULL; - hash=hashcode(s,j); // compute hashcode - ltp->nextindex=afile->la.hashindex[hash]; // and link in before last entry with same hashcode - afile->la.hashindex[hash]=afile->la.lti; // set as start of list for that hashcode + // init new entry in label table + er = E_OK; + ltp->len = j; // length of label + ltp->n = s2; // name of label (char*) + ltp->blk = b; // block number + ltp->fl = 0; + ltp->afl = 0; + ltp->is_cll = ltype; // STD, CHEAP, or UNNAMED label + ltp->occlist = NULL; + hash = hashcode(s, j); // compute hashcode + ltp->nextindex = afile->la.hashindex[hash]; // and link in before last entry with same hashcode + afile->la.hashindex[hash] = afile->la.lti;// set as start of list for that hashcode // TODO: does not work across files! ltp->blknext = -1; // no next block - ltp->blkprev = b_link( afile->la.lti ); // previous block, linked within block + ltp->blkprev = b_link(afile->la.lti);// previous block, linked within block if (ltp->blkprev != -1) { ltp = afile->la.lt + ltp->blkprev; ltp->blknext = afile->la.lti; } - *n=afile->la.lti; // return the list index for that file in the out parameter n - afile->la.lti++; // increase last index in lable table + *n = afile->la.lti; // return the list index for that file in the out parameter n + afile->la.lti++; // increase last index in lable table - return(er); + return (er); } /** @@ -634,54 +598,53 @@ static int ll_def(char *s, int *n, int b, xalabel_t ltype) * * Do not define the label (as is done in l_search()!) */ -int ll_search(char *s, int *n, xalabel_t cll_fl) /* search Label in Tabelle ,nr->n */ +int ll_search(char *s, int *n, xalabel_t cll_fl) /* search Label in Tabelle ,nr->n */ { - int i,j=0,k,er=E_NODEF,hash; + int i, j = 0, k, er = E_NODEF, hash; - while(s[j] && (isalnum(s[j])||(s[j]=='_'))) j++; + while (s[j] && (isalnum(s[j]) || (s[j] == '_'))) + j++; - hash=hashcode(s,j); - i=afile->la.hashindex[hash]; + hash = hashcode(s, j); + i = afile->la.hashindex[hash]; - if(i>=afile->la.ltm) return E_NODEF; + if (i >= afile->la.ltm) + return E_NODEF; - do - { - ltp=afile->la.lt+i; - - if(j==ltp->len) - { - for (k=0;(kn[k]==s[k]);k++); + do { + ltp = afile->la.lt + i; - if ( (j == k) && cll_fl == CHEAP) { - if (ltp->blk == cll_getcur()) { - er=E_OK; - break; - } - } else - if (cll_fl == UNNAMED) { - // TODO - } else { + if (j == ltp->len) { + for (k = 0; (k < j) && (ltp->n[k] == s[k]); k++) + ; + + if ((j == k) && cll_fl == CHEAP) { + if (ltp->blk == cll_getcur()) { + er = E_OK; + break; + } + } else if (cll_fl == UNNAMED) { + // TODO + } else { //printf("ll_search:match labels %s with %p (%s) from block %d, block check is %d\n", s, ltp, ltp->n, ltp->blk, b_test(ltp->blk)); - /* check if the found label is in any of the blocks in the - current block stack */ - if((j==k)&&(!b_test(ltp->blk))) - { - /* ok, label found and it is reachable (its block nr is in the current block stack */ - er=E_OK; - break; - } - } - } + /* check if the found label is in any of the blocks in the + current block stack */ + if ((j == k) && (!b_test(ltp->blk))) { + /* ok, label found and it is reachable (its block nr is in the current block stack */ + er = E_OK; + break; + } + } + } - if(!i) - break; + if (!i) + break; - i=ltp->nextindex; - - }while(1); - - *n=i; + i = ltp->nextindex; + + } while (1); + + *n = i; #if 0 if(er!=E_OK && er!=E_NODEF) { @@ -691,73 +654,69 @@ int ll_search(char *s, int *n, xalabel_t cll_fl) /* search Label in Tab #endif //printf("l_search(%s) returns er=%d, n=%d\n", s, er, *n); - return(er); + return (er); } -int ll_pdef(char *t) -{ +int ll_pdef(char *t) { int n; - - if(ll_search(t,&n, STD)==E_OK) - { - ltp=afile->la.lt+n; - if(ltp->fl) - return(E_OK); + + if (ll_search(t, &n, STD) == E_OK) { + ltp = afile->la.lt + n; + if (ltp->fl) + return (E_OK); } - return(E_NODEF); + return (E_NODEF); } /* * Write out the list of global labels in an o65 file */ -int l_write(FILE *fp) -{ - int i, afl, n=0; +int l_write(FILE *fp) { + int i, afl, n = 0; - if(noglob) { - fputc(0, fp); - fputc(0, fp); - return 0; - } - // calculate number of global labels - for (i=0;ila.lti;i++) { - ltp=afile->la.lt+i; - if((!ltp->blk) && (ltp->fl==1)) { - n++; + if (noglob) { + fputc(0, fp); + fputc(0, fp); + return 0; } - } - // write number of globals to file - fputc(n&255, fp); - fputc((n>>8)&255, fp); - // iterate over labels and write out label - for (i=0;ila.lti;i++) - { - ltp=afile->la.lt+i; - if((!ltp->blk) && (ltp->fl==1)) { - // write global name - fprintf(fp, "%s",ltp->n); - fputc(0,fp); + // calculate number of global labels + for (i = 0; i < afile->la.lti; i++) { + ltp = afile->la.lt + i; + if ((!ltp->blk) && (ltp->fl == 1)) { + n++; + } + } + // write number of globals to file + fputc(n & 255, fp); + fputc((n >> 8) & 255, fp); + // iterate over labels and write out label + for (i = 0; i < afile->la.lti; i++) { + ltp = afile->la.lt + i; + if ((!ltp->blk) && (ltp->fl == 1)) { + // write global name + fprintf(fp, "%s", ltp->n); + fputc(0, fp); - // segment byte - afl = ltp->afl; - // hack to switch undef and abs flag from internal to file format - // if asolute of undefined (< SEG_TEXT, i.e. 0 or 1) - // then invert bit 0 (0 = absolute) - if( (afl & (A_FMASK>>8)) < SEG_TEXT) { - afl^=1; - } - // remove residue flags, only write out real segment number - // according to o65 file format definition - afl = afl & (A_FMASK >> 8); - fputc(afl,fp); + // segment byte + afl = ltp->afl; + // hack to switch undef and abs flag from internal to file format + // if asolute of undefined (< SEG_TEXT, i.e. 0 or 1) + // then invert bit 0 (0 = absolute) + if ((afl & (A_FMASK >> 8)) < SEG_TEXT) { + afl ^= 1; + } + // remove residue flags, only write out real segment number + // according to o65 file format definition + afl = afl & (A_FMASK >> 8); + fputc(afl, fp); - // value - fputc(ltp->val&255, fp); - fputc((ltp->val>>8)&255, fp); - } - } - /*fputc(0,fp);*/ - return 0; + // value + fputc(ltp->val & 255, fp); + fputc((ltp->val >> 8) & 255, fp); + } + } + /*fputc(0,fp);*/ + return 0; } /******************************************************************************************* @@ -773,129 +732,115 @@ int l_write(FILE *fp) * Methods exist to open new blocks, close a block, and do some checks, e.g. whether * a specific block number is contained in the current block stack. */ -static int bt[MAXBLK]; /* block stack */ -static int labind; /* last allocated label, -1 none yet alloc'd - used for linking to find unnamed labels */ -static int bi; /* length of the block stack (minus 1, i.e. bi[bi] has the innermost block) */ -static int blk; /* current block number for allocation */ +static int bt[MAXBLK]; /* block stack */ +static int labind; /* last allocated label, -1 none yet alloc'd - used for linking to find unnamed labels */ +static int bi; /* length of the block stack (minus 1, i.e. bi[bi] has the innermost block) */ +static int blk; /* current block number for allocation */ -int b_init(void) -{ - blk =0; - bi =0; - bt[bi]=blk; - labind=-1; +int b_init(void) { + blk = 0; + bi = 0; + bt[bi] = blk; + labind = -1; - return(E_OK); -} + return (E_OK); +} -int b_new(void) -{ +int b_new(void) { return ++blk; } -int b_depth(void) -{ - return bi; +int b_depth(void) { + return bi; } -int ga_blk(void) -{ - return(blk); +int ga_blk(void) { + return (blk); } /** * open a new block scope */ -int b_open(void) -{ - int er=E_BLKOVR; +int b_open(void) { + int er = E_BLKOVR; - if(bi=0) - *n=bt[bi-i]; - else - *n=0; - return(E_OK); +static int b_fget(int *n, int i) { + if ((bi - i) >= 0) + *n = bt[bi - i]; + else + *n = 0; + return (E_OK); } /** * tests whether the given block number n is in the current stack of * current block numbers bt[] */ -static int b_test(int n) -{ - int i=bi; +static int b_test(int n) { + int i = bi; - while( i>=0 && n!=bt[i] ) - i--; + while (i >= 0 && n != bt[i]) + i--; - return( i+1 ? E_OK : E_NOBLK ); + return (i + 1 ? E_OK : E_NOBLK); } /** * tests whether the given block number "a" is in the */ -static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(a)] */ +static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(a)] */ { - int i=0,er=E_OK; + int i = 0, er = E_OK; - if(a!=b) - { - er=E_OK; + if (a != b) { + er = E_OK; - while(i<=bi && b!=bt[i]) - { - if(bt[i]==a) - { - er=E_NOBLK; - break; - } - i++; - } - } - return(er); + while (i <= bi && b != bt[i]) { + if (bt[i] == a) { + er = E_NOBLK; + break; + } + i++; + } + } + return (er); } int b_link(int newlab) { diff --git a/xa/src/xal.h b/xa/src/xal.h index 7522210..273fed3 100644 --- a/xa/src/xal.h +++ b/xa/src/xal.h @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -27,18 +27,17 @@ */ extern char *lz; - int l_init(void); int ga_lab(void); int gm_lab(void); long gm_labm(void); long ga_labm(void); -int lg_set(char *); +int lg_set(char*); int lg_import(int); int lg_importzp(int); // 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_depth(void); @@ -46,7 +45,7 @@ int b_depth(void); void printllist(FILE *fp); 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); void l_set(int n, int v, int afl); char* l_get_name(int n, xalabel_t *is_cll); diff --git a/xa/src/xalisting.c b/xa/src/xalisting.c index 92b6d55..cfc9443 100644 --- a/xa/src/xalisting.c +++ b/xa/src/xalisting.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * maintained by Cameron Kaiser * * Assembler listing @@ -31,7 +31,6 @@ #include "xal.h" #include "xat.h" - /*********************************************************************************************/ /* this is the listing code * @@ -41,9 +40,9 @@ */ static FILE *listfp = NULL; -static int list_lineno = 1; /* current line number */ -static int list_last_lineno = 0; /* current line number */ -static char *list_filenamep = NULL; /* current file name pointer */ +static int list_lineno = 1; /* current line number */ +static int list_last_lineno = 0; /* current line number */ +static char *list_filenamep = NULL; /* current file name pointer */ static int list_numbytes = 8; @@ -63,38 +62,36 @@ static int list_nibble_f(char *buf, int outnib, signed char format); // formatter typedef struct { - void (*start_listing)(char *name); - void (*start_line)(); - 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 (*end_label)(char *buf); - void (*end_line)(); - void (*end_listing)(); - 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 + void (*start_listing)(char *name); + void (*start_line)(); + 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 (*end_label)(char *buf); + void (*end_line)(); + void (*end_listing)(); + 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 } formatter_t; -static char *def_escape(char *toescape) { +static char* def_escape(char *toescape) { return toescape; } -static char *def_escape_char(char toescape) { +static char* def_escape_char(char toescape) { static char buf[2]; buf[0] = toescape; buf[1] = 0; return buf; } -static formatter_t def_format = { - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - def_escape, def_escape_char -}; +static formatter_t def_format = { +NULL, NULL, NULL, NULL, +NULL, NULL, NULL, def_escape, def_escape_char }; static void html_start_listing(char *name) { // really short version for now - fprintf(listfp, "%s
\n", 
-		(name == NULL) ? "(null)" : name);
+	fprintf(listfp, "%s
\n",
+			(name == NULL) ? "(null)" : name);
 }
 
 static int html_set_anchor(char *buf, char *name) {
@@ -116,26 +113,24 @@ static void html_end_listing() {
 	fprintf(listfp, "
\n"); } -static char *html_escape(char *toescape) { +static char* html_escape(char *toescape) { static char buf[MAXLINE]; - + char *p = toescape; char *q = buf; while (*p != 0) { if (*p == '<') { strcpy(q, "<"); - q+=4; + q += 4; p++; - } else - if (*p == '&') { + } else if (*p == '&') { strcpy(q, "&"); - q+=5; + q += 5; p++; - } else - if (*p == '>') { + } else if (*p == '>') { strcpy(q, ">"); - q+=4; + q += 4; p++; } else { *q = *p; @@ -147,25 +142,18 @@ static char *html_escape(char *toescape) { return buf; } -static char *html_escape_char(char toescape) { +static char* html_escape_char(char toescape) { static char buf[2]; - + buf[0] = toescape; buf[1] = 0; return html_escape(buf); } -static formatter_t html_format = { - html_start_listing, - NULL, - html_set_anchor, - html_start_label, - html_end_label, - NULL, - html_end_listing, - html_escape, html_escape_char -}; +static formatter_t html_format = { html_start_listing, +NULL, html_set_anchor, html_start_label, html_end_label, +NULL, html_end_listing, html_escape, html_escape_char }; static formatter_t *formatp = &def_format; @@ -185,13 +173,15 @@ void list_start(const char *formatname) { } 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() { 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 */ 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_lineno = 1; list_last_lineno = 0; @@ -226,7 +217,7 @@ void list_setfile(FILE *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; char c; @@ -238,13 +229,25 @@ char *list_preamble(char *buf, int lineno, int seg, int pc) { c = '?'; /* preamble ':'
' ' */ - switch(seg) { - case SEG_ABS: c='A'; break; - case SEG_TEXT: c='T'; 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; + switch (seg) { + case SEG_ABS: + c = 'A'; + break; + case SEG_TEXT: + c = 'T'; + 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, ':'); @@ -254,7 +257,6 @@ char *list_preamble(char *buf, int lineno, int seg, int pc) { return buf; } - /** * listing/listing_len give the buffer address and length respectively that contains * 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 */ -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; char outline[MAXLINE]; char *buf = outline; 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) */ - if (listfp == NULL) return; - + if (listfp == NULL) + return; /*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? */ - if (list_lineno > list_last_lineno+1) { + if (list_lineno > list_last_lineno + 1) { /* yes */ /*fprintf(listfp, "line=%d, last=%d\n", list_lineno, list_last_lineno);*/ 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; // 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); @@ -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 "..." */ n_hexb = bincode_len; if (list_numbytes != 0 && n_hexb >= list_numbytes) { - n_hexb = list_numbytes-1; + n_hexb = list_numbytes - 1; overflow = 1; } for (i = 0; i < n_hexb; i++) { buf = buf + list_byte(buf, bincode[i]); buf = buf + list_sp(buf); - if ( (i%16) == 15) { + if ((i % 16) == 15) { // make a break buf[0] = 0; fprintf(listfp, "%s\n", outline); - if (formatp->end_line != NULL) formatp->end_line(); - if (formatp->start_line != NULL) formatp->start_line(); + if (formatp->end_line != NULL) + formatp->end_line(); + if (formatp->start_line != NULL) + formatp->start_line(); buf = outline; 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 buf[0] = 0; fprintf(listfp, "%s\n", outline); - if (formatp->end_line != NULL) formatp->end_line(); - if (formatp->start_line != NULL) formatp->start_line(); + if (formatp->end_line != NULL) + formatp->end_line(); + if (formatp->start_line != NULL) + formatp->start_line(); buf = outline; buf = list_preamble(buf, list_lineno, lst_seg, lst_pc); i = 0; - } + } i = num_last_line - i; 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 buf[0] = 0; - + 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) { @@ -386,43 +396,43 @@ int list_tokens(char *buf, signed char *input, int len) { int tabval, operator; signed char format; - if (inp >= len) return 0; + if (inp >= len) + return 0; tmp = input[inp] & 255; tabval = 0; if (tmp == (T_DEFINE & 255)) { while (inp < len && tmp == (T_DEFINE & 255)) { - tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255); -/*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/ - name=l_get_name(tmp, &is_cll); + tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255); + /*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/ + name = l_get_name(tmp, &is_cll); // duplicate anchor names? 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) { - outp += list_char(buf+outp, '@'); - } else - if (is_cll == UNNAMED_DEF || is_cll == UNNAMED) { - outp += list_char(buf+outp, ':'); + outp += list_char(buf + outp, '@'); + } else if (is_cll == UNNAMED_DEF || is_cll == UNNAMED) { + outp += list_char(buf + outp, ':'); } if (is_cll != UNNAMED) { - tmp = list_string(buf+outp, name); + tmp = list_string(buf + outp, name); tabval += tmp + 1 + is_cll; outp += tmp; } - outp += list_char(buf+outp, ' '); + outp += list_char(buf + outp, ' '); inp += 3; tmp = input[inp] & 255; } if (tabval < 10) { - outp += list_nchar(buf+outp, ' ', 10-tabval); + outp += list_nchar(buf + outp, ' ', 10 - tabval); } } else { 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 */ /*printf("tmp=%d, kt[tmp]=%p\n", tmp, kt[tmp]);*/ if (kt[tmp] != NULL) { - outp += list_string(buf+outp, kt[tmp]); + outp += list_string(buf + outp, kt[tmp]); } outp += list_sp(buf + outp); inp += 1; @@ -453,60 +463,65 @@ int list_tokens(char *buf, signed char *input, int len) { operator = 0; while (inp < len) { - switch(input[inp]) { + switch (input[inp]) { case T_CAST: - outp += list_string(buf+outp, formatp->escape_char(input[inp+1])); - inp+=2; + outp += list_string(buf + outp, + formatp->escape_char(input[inp + 1])); + inp += 2; break; case T_VALUE: /*outp += list_char(buf+outp, 'V');*/ /* 24 bit value */ - tmp = ((input[inp+3]&255)<<16) | ((input[inp+2]&255)<<8) | (input[inp+1]&255); - format = input[inp+4]; - outp += list_value(buf+outp, tmp, format); + tmp = ((input[inp + 3] & 255) << 16) | ((input[inp + 2] & 255) << 8) + | (input[inp + 1] & 255); + format = input[inp + 4]; + outp += list_value(buf + outp, tmp, format); inp += 5; - operator = 1; /* check if arithmetic operator follows */ + operator = 1; /* check if arithmetic operator follows */ break; case T_LABEL: /*outp += list_char(buf+outp, 'L');*/ /* 16 bit label number */ - tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255); - name=l_get_name(tmp, &is_cll); + tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255); + name = l_get_name(tmp, &is_cll); // duplicate label name 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) { - outp += list_char(buf+outp, '@'); - } else - if (is_cll == UNNAMED || is_cll == UNNAMED_DEF) { - outp += list_char(buf+outp, ':'); + outp += list_char(buf + outp, '@'); + } else if (is_cll == UNNAMED || is_cll == UNNAMED_DEF) { + outp += list_char(buf + outp, ':'); } if (is_cll != UNNAMED) { - outp += list_string(buf+outp, name == NULL ? "" : name); + outp += list_string(buf + outp, name == 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; - operator = 1; /* check if arithmetic operator follows */ + operator = 1; /* check if arithmetic operator follows */ break; case T_OP: /* label arithmetic operation; inp[3] is operation like '=' or '+' */ - tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255); - name=l_get_name(tmp, &is_cll); - if (input[inp+3] == '=') { + tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255); + name = l_get_name(tmp, &is_cll); + if (input[inp + 3] == '=') { // label definition 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, '@'); - outp += list_string(buf+outp, name); - outp += list_char(buf+outp, input[inp+3]); + if (is_cll) + outp += list_char(buf + outp, '@'); + outp += list_string(buf + outp, name); + outp += list_char(buf + outp, input[inp + 3]); inp += 4; - + break; case T_END: /* end of operation */ @@ -516,67 +531,71 @@ int list_tokens(char *buf, signed char *input, int len) { break; case T_COMMENT: 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); - outp += list_char(buf+outp, ';'); - outp += list_string(buf+outp, (char*)input+inp+3); + tmp = ((input[inp + 2] & 255) << 8) | (input[inp + 1] & 255); + outp += list_char(buf + outp, ';'); + outp += list_string(buf + outp, (char*) input + inp + 3); inp += tmp + 3; break; case T_LINE: case T_FILE: /* 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; case T_POINTER: /* what is this? It's actually resolved during token conversion */ - tmp = ((input[inp+5]&255)<<8) | (input[inp+4]&255); - name=l_get_name(tmp, &is_cll); + tmp = ((input[inp + 5] & 255) << 8) | (input[inp + 4] & 255); + name = l_get_name(tmp, &is_cll); 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, '@'); - outp += list_string(buf+outp, name); + if (is_cll) + 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_char(buf+outp, '#'); - tmp = ((input[inp+3]&255)<<8) | (input[inp+2]&255); - outp += list_value(buf+outp, tmp); - */ + outp += list_byte(buf+outp, input[inp+1]); + outp += list_char(buf+outp, '#'); + tmp = ((input[inp+3]&255)<<8) | (input[inp+2]&255); + outp += list_value(buf+outp, tmp); + */ inp += 6; - operator = 1; /* check if arithmetic operator follows */ + operator = 1; /* check if arithmetic operator follows */ break; case '"': { int i, len; // string display inp++; - outp += list_char(buf+outp, '"'); + outp += list_char(buf + outp, '"'); len = input[inp] & 0xff; for (i = 0; i < len; i++) { inp++; - outp += list_char(buf+outp, input[inp]); + outp += list_char(buf + outp, input[inp]); } inp++; - outp += list_char(buf+outp, '"'); + outp += list_char(buf + outp, '"'); break; } case '*': { // If '*' appears as operand, it is the PC. We need to switch to operator then inp++; - outp += list_char(buf+outp, '*'); + outp += list_char(buf + outp, '*'); operator = 1; break; } default: c = input[inp]; if (c > 31) { - outp += list_string(buf+outp, formatp->escape_char(input[inp])); + outp += list_string(buf + outp, + formatp->escape_char(input[inp])); } else { - outp += list_char(buf+outp, '\''); - outp += list_byte(buf+outp, input[inp]); + outp += list_char(buf + outp, '\''); + outp += list_byte(buf + outp, input[inp]); } inp += 1; break; @@ -585,7 +604,7 @@ int list_tokens(char *buf, signed char *input, int len) { if (operator && inp < len) { signed char op = input[inp]; 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; operator = 0; } @@ -594,8 +613,7 @@ int list_tokens(char *buf, signed char *input, int len) { // another operator is expected after the bracket } } -end: - return outp; + end: return outp; } int list_string(char *buf, char *string) { @@ -621,54 +639,51 @@ int list_value(char *buf, int val, signed char format) { switch (format) { case '$': p += list_char(buf + p, '$'); - if (val & (255<<16)) { - p += list_byte(buf+p, val>>16); - p += list_word(buf+p, val); - } else - if (val & (255<<8)) { - p += list_word(buf+p, val); + if (val & (255 << 16)) { + p += list_byte(buf + p, val >> 16); + p += list_word(buf + p, val); + } else if (val & (255 << 8)) { + p += list_word(buf + p, val); } else { - p += list_byte(buf+p, val); + p += list_byte(buf + p, val); } break; case '%': p += list_char(buf + p, '%'); - if (val & (255<<16)) { - p += list_byte_f(buf+p, val>>16,'%'); - p += list_word_f(buf+p, val,'%'); - } else - if (val & (255<<8)) { - p += list_word_f(buf+p, val,'%'); + if (val & (255 << 16)) { + p += list_byte_f(buf + p, val >> 16, '%'); + p += list_word_f(buf + p, val, '%'); + } else if (val & (255 << 8)) { + p += list_word_f(buf + p, val, '%'); } else { - p += list_byte_f(buf+p, val,'%'); + p += list_byte_f(buf + p, val, '%'); } break; case '&': - snprintf(valbuf, 32, "%o",val); - p+= list_char(buf+p, '&'); - p+= list_string(buf+p, valbuf); + snprintf(valbuf, 32, "%o", val); + p += list_char(buf + p, '&'); + p += list_string(buf + p, valbuf); break; case 'd': - snprintf(valbuf, 32, "%d",val); - p+= list_string(buf+p, valbuf); + snprintf(valbuf, 32, "%d", val); + p += list_string(buf + p, valbuf); break; case '\'': case '"': - p+= list_char(buf+p, format); - p+= list_char(buf+p, val); - p+= list_char(buf+p, format); + p += list_char(buf + p, format); + p += list_char(buf + p, val); + p += list_char(buf + p, format); break; default: /* hex format as fallback */ p += list_char(buf + p, '$'); - if (val & (255<<16)) { - p += list_byte(buf+p, val>>16); - p += list_word(buf+p, val); - } else - if (val & (255<<8)) { - p += list_word(buf+p, val); + if (val & (255 << 16)) { + p += list_byte(buf + p, val >> 16); + p += list_word(buf + p, val); + } else if (val & (255 << 8)) { + p += list_word(buf + p, val); } else { - p += list_byte(buf+p, val); + p += list_byte(buf + p, val); } 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 i; for (i = 0; i < n; i++) { - buf[i]=c; + buf[i] = c; } 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 p = 0; - p+= list_byte_f(buf+p, outword >> 8, format); - p+= list_byte_f(buf+p, outword, format); + p += list_byte_f(buf + p, outword >> 8, format); + p += list_byte_f(buf + p, outword, format); 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 p = 0; - p+= list_nibble_f(buf+p, (outbyte >> 4), format); - p+= list_nibble_f(buf+p, outbyte, format); + p += list_nibble_f(buf + p, (outbyte >> 4), format); + p += list_nibble_f(buf + p, outbyte, format); return p; } int list_nibble_f(char *buf, int outnib, signed char format) { int p = 0; outnib = outnib & 0xf; - switch(format) { + switch (format) { case '$': if (outnib < 10) { - buf[p]='0'+outnib; + buf[p] = '0' + outnib; } else { - buf[p]='a'-10+outnib; + buf[p] = 'a' - 10 + outnib; } p++; break; case '%': - buf[p++] = (outnib&8)?'1':'0'; - buf[p++] = (outnib&4)?'1':'0'; - buf[p++] = (outnib&2)?'1':'0'; - buf[p++] = (outnib&1)?'1':'0'; + buf[p++] = (outnib & 8) ? '1' : '0'; + buf[p++] = (outnib & 4) ? '1' : '0'; + buf[p++] = (outnib & 2) ? '1' : '0'; + buf[p++] = (outnib & 1) ? '1' : '0'; break; default: /* hex as default */ if (outnib < 10) { - buf[p]='0'+outnib; + buf[p] = '0' + outnib; } else { - buf[p]='a'-10+outnib; + buf[p] = 'a' - 10 + outnib; } p++; break; @@ -746,5 +761,3 @@ int list_nibble_f(char *buf, int outnib, signed char format) { return p; } - - diff --git a/xa/src/xalisting.h b/xa/src/xalisting.h index 8505047..e2f1bd9 100644 --- a/xa/src/xalisting.h +++ b/xa/src/xalisting.h @@ -25,10 +25,11 @@ void list_end(); void list_flush(); // debug helper 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 */ // 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__ */ diff --git a/xa/src/xam.c b/xa/src/xam.c index 968c8bb..cb53872 100644 --- a/xa/src/xam.c +++ b/xa/src/xam.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * Memory manager/malloc() stub module * @@ -27,105 +27,99 @@ static int ninc = 0; static char **nip = NULL; - + void reg_include(char *path) { char **nip2; - if(path && *path) { - nip2 = realloc(nip,sizeof(char*)*(ninc+1)); - if(nip2) { - nip = nip2; - nip[ninc++] = path; - } else { - fprintf(stderr,"Warning: couldn' alloc mem (reg_include)\n"); - } + if (path && *path) { + nip2 = realloc(nip, sizeof(char*) * (ninc + 1)); + if (nip2) { + nip = nip2; + nip[ninc++] = path; + } else { + 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; - char c,*cp,n[MAXLINE],path[MAXLINE]; + char c, *cp, n[MAXLINE], path[MAXLINE]; char xname[MAXLINE], n2[MAXLINE]; - int i,l=(int)strlen(fn); + int i, l = (int) strlen(fn); - if(l>=MAXLINE) { - fprintf(stderr,"filename '%s' too long!\n",fn); - return NULL; + if (l >= MAXLINE) { + fprintf(stderr, "filename '%s' too long!\n", fn); + return NULL; } // copy to xname by replacing windows backslashes with the proper DIRCHAR - for(i=0;ifo.mlist<=afile->fo.nlist) { - afile->fo.mlist +=5; - afile->fo.olist = realloc(afile->fo.olist, afile->fo.mlist*sizeof(Fopt)); - if(!afile->fo.olist) { - fprintf(stderr, "Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n", - (unsigned long)( - afile->fo.mlist*sizeof(Fopt))); - exit(1); - } + /*printf("set_fopt(%s, l=%d\n",buf,l);*/ + while (afile->fo.mlist <= afile->fo.nlist) { + afile->fo.mlist += 5; + afile->fo.olist = realloc(afile->fo.olist, + afile->fo.mlist * sizeof(Fopt)); + if (!afile->fo.olist) { + fprintf(stderr, + "Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n", + (unsigned long) (afile->fo.mlist * sizeof(Fopt))); + exit(1); + } } - afile->fo.olist[afile->fo.nlist].text=malloc(l); - if(!afile->fo.olist[afile->fo.nlist].text) { - fprintf(stderr, "Fatal: Couldn't alloc memory (%d bytes) for fopt!\n",l); - exit(1); + afile->fo.olist[afile->fo.nlist].text = malloc(l); + if (!afile->fo.olist[afile->fo.nlist].text) { + fprintf(stderr, "Fatal: Couldn't alloc memory (%d bytes) for fopt!\n", + l); + exit(1); } memcpy(afile->fo.olist[afile->fo.nlist].text, buf, l); 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 */ void o_write(FILE *fp) { - int i,j,l,afl; + int i, j, l, afl; signed char *t; - for(i=0;ifo.nlist;i++) { - l=afile->fo.olist[i].len; - t=afile->fo.olist[i].text; -/* do not optimize */ - t_p2_l(t, &l, &afl); - - if(l>254) { - errout(E_OPTLEN); - } else { - fputc((l+1)&0xff,fp); - } - for(j=0;jfo.nlist; i++) { + l = afile->fo.olist[i].len; + t = afile->fo.olist[i].text; + /* do not optimize */ + t_p2_l(t, &l, &afl); - for(i=0;ifo.nlist;i++) { - free(afile->fo.olist[i].text); + 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++) { + free(afile->fo.olist[i].text); } free(afile->fo.olist); afile->fo.olist = NULL; @@ -93,9 +95,9 @@ void o_write(FILE *fp) { size_t o_length(void) { int i; size_t n = 0; - for(i=0;ifo.nlist;i++) { -/*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; + 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);*/ + n += afile->fo.olist[i].len + 1; } return ++n; } diff --git a/xa/src/xap.c b/xa/src/xap.c index 9cce78e..29a7621 100644 --- a/xa/src/xap.c +++ b/xa/src/xap.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * Maintained by Cameron Kaiser * * File handling and preprocessor (also see xaa.c) module @@ -46,16 +46,16 @@ char s[MAXLINE]; Datei *filep; -static int tcompare(char*,char**,int); -static int pp_replace(char*,char*,int,int); +static int tcompare(char*, char**, int); +static int pp_replace(char*, char*, int, int); static int searchdef(char*); -static int fgetline(char*,int len, int *rlen, FILE*); +static int fgetline(char*, int len, int *rlen, FILE*); /*static int icl_open(char*);*/ -static int pp_ifdef(char*),pp_ifndef(char*); -static int pp_else(char*),pp_endif(char*); -static int pp_echo(char*),pp_if(char*),pp_print(char*),pp_prdef(char*); -static int pp_ifldef(char*),pp_iflused(char*); +static int pp_ifdef(char*), pp_ifndef(char*); +static int pp_else(char*), pp_endif(char*); +static int pp_echo(char*), pp_if(char*), pp_print(char*), pp_prdef(char*); +static int pp_ifldef(char*), pp_iflused(char*); static int pp_undef(char*); static int pp_error(char*); @@ -65,344 +65,316 @@ static int pp_error(char*); static int quotebs = 0; static int inquote = 0; -static char *cmd[]={ -"echo","include","define","undef","printdef","print","error", /* VALBEF */ - "ifdef","ifndef","else","endif", - "ifldef","iflused","if" }; /* ANZBEF */ - -static int (*func[])(char*) = { pp_echo,icl_open,pp_define,pp_undef, - pp_prdef,pp_print,pp_error,pp_ifdef,pp_ifndef, - pp_else,pp_endif, - pp_ifldef,pp_iflused,pp_if }; +static char *cmd[] = { "echo", "include", "define", "undef", "printdef", + "print", "error", /* VALBEF */ + "ifdef", "ifndef", "else", "endif", "ifldef", "iflused", "if" }; /* ANZBEF */ -static char *mem; -static unsigned long memfre; -static int nlf; -static int nff; -static int hashindex[256]; +static int (*func[])(char*) = {pp_echo,icl_open,pp_define,pp_undef, + pp_prdef,pp_print,pp_error,pp_ifdef,pp_ifndef, + pp_else,pp_endif, + pp_ifldef,pp_iflused,pp_if }; -static List *liste; -static unsigned int rlist; -static int fsp; -static int loopfl; -static Datei flist[MAXFILE+1]; -static char in_line[MAXLINE]; +static char *mem; +static unsigned long memfre; +static int nlf; +static int nff; +static int hashindex[256]; -int pp_comand(char *t) -{ - int i,l,er=1; +static List *liste; +static unsigned int rlist; +static int fsp; +static int loopfl; +static Datei flist[MAXFILE + 1]; +static char in_line[MAXLINE]; - i=tcompare(t,cmd,ANZBEF); +int pp_comand(char *t) { + int i, l, er = 1; - if(i>=0) - { - if(loopfl && (i= 0) { + if (loopfl && (i < VALBEF)) + er = 0; + else { + l = (int) strlen(cmd[i]); + while (isspace(t[l])) + l++; + + er = (*func[i])(t + l); + } + } + return (er); } -int pp_ifdef(char *t) -{ -/* int x; - printf("t=%s\n",t); - x=searchdef(t); - printf("searchdef(t)=%d\n",x); -*/ - loopfl=(loopfl<<1)+( searchdef(t) ? 0 : 1 ); - return(0); +int pp_ifdef(char *t) { + /* int x; + printf("t=%s\n",t); + x=searchdef(t); + printf("searchdef(t)=%d\n",x); + */ + loopfl = (loopfl << 1) + (searchdef(t) ? 0 : 1); + return (0); } -int pp_ifndef(char *t) -{ - loopfl=(loopfl<<1)+( searchdef(t) ? 1 : 0 ); - return(0); +int pp_ifndef(char *t) { + loopfl = (loopfl << 1) + (searchdef(t) ? 1 : 0); + return (0); } -int pp_ifldef(char *t) -{ - loopfl=(loopfl<<1)+( ll_pdef(t) ? 1 : 0 ); - return(0); +int pp_ifldef(char *t) { + loopfl = (loopfl << 1) + (ll_pdef(t) ? 1 : 0); + return (0); } -int pp_iflused(char *t) -{ +int pp_iflused(char *t) { int n; - loopfl=(loopfl<<1)+( ll_search(t,&n,STD) ? 1 : 0 ); - return(0); + loopfl = (loopfl << 1) + (ll_search(t, &n, STD) ? 1 : 0); + return (0); } -int pp_echo(char *t) -{ - int er; - - if((er=pp_replace(s,t,-1,rlist))) - errout(er); - else - { - logout(s); - logout("\n"); - } - return(0); +int pp_echo(char *t) { + int er; + + if ((er = pp_replace(s, t, -1, rlist))) + errout(er); + else { + logout(s); + logout("\n"); + } + return (0); } -int pp_print(char *t) -{ - int f,a,er; - - logout(t); - if((er=pp_replace(s,t,-1,rlist))) - { - logout("\n"); - errout(er); - } - else - { - logout("="); - logout(s); - logout("="); - er=b_term(s,&a,&f,pc[segment]); - if(er) - { - logout("\n"); - errout(er); - } - else - { sprintf(s,"%d\n",a); logout(s); } - } - - return(0); +int pp_print(char *t) { + int f, a, er; + + logout(t); + if ((er = pp_replace(s, t, -1, rlist))) { + logout("\n"); + errout(er); + } else { + logout("="); + logout(s); + logout("="); + er = b_term(s, &a, &f, pc[segment]); + if (er) { + logout("\n"); + errout(er); + } else { + sprintf(s, "%d\n", a); + logout(s); + } + } + + return (0); } -int pp_error(char *t) -{ +int pp_error(char *t) { /* the offending line is printed for us */ return E_UERROR; } -int pp_if(char *t) -{ - int a,f,l,er; +int pp_if(char *t) { + int a, f, l, er; -/* XXX: #if XYZ, if XYZ is not defined, XYZ gets treated as a label. */ + /* XXX: #if XYZ, if XYZ is not defined, XYZ gets treated as a label. */ - if((er=pp_replace(s,t,-1,rlist))) { - errout(er); - } else - { - dsb_len = 1; - f=b_term(s,&a,&l,pc[segment]); - dsb_len = 0; + if ((er = pp_replace(s, t, -1, rlist))) { + errout(er); + } else { + dsb_len = 1; + f = b_term(s, &a, &l, pc[segment]); + dsb_len = 0; - if((!loopfl) && f) { - errout(f); - } else - loopfl=(loopfl<<1)+( a ? 0 : 1 ); - } - return(0); + if ((!loopfl) && f) { + errout(f); + } else + loopfl = (loopfl << 1) + (a ? 0 : 1); + } + return (0); } -int pp_else(char *t) -{ - (void)t; /* quench warning */ - loopfl ^=1; - return(0); +int pp_else(char *t) { + (void) t; /* quench warning */ + loopfl ^= 1; + return (0); } -int pp_endif(char *t) -{ - (void)t; /* quench warning */ - loopfl=loopfl>>1; - return(0); +int pp_endif(char *t) { + (void) t; /* quench warning */ + loopfl = loopfl >> 1; + return (0); } - /* stub for handling CPP directives */ int pp_cpp(char *t) { char name[MAXLINE]; - if(sscanf(t, " %d \"%s\"", &filep->fline, name) == 2) { + if (sscanf(t, " %d \"%s\"", &filep->fline, name) == 2) { /* massage it into our parameters and drop last quote */ char *u; filep->fline--; - if((u = (char *)strrchr(name, '"'))) + if ((u = (char*) strrchr(name, '"'))) *u = '\0'; free(filep->fname); filep->fname = strdup(name); - if(!filep->fname) { - fprintf(stderr,"Oops, no more memory!\n"); + if (!filep->fname) { + fprintf(stderr, "Oops, no more memory!\n"); exit(1); } return (0); } else { - return(E_SYNTAX); + return (E_SYNTAX); } } /* pp_undef is a great hack to get it working fast... */ int pp_undef(char *t) { - int i; - if((i=searchdef(t))) { - i+=rlist; - liste[i].s_len=0; - } - return 0; + int i; + if ((i = searchdef(t))) { + i += rlist; + liste[i].s_len = 0; + } + return 0; } -int pp_prdef(char *t) -{ - char *x; - int i,j; +int pp_prdef(char *t) { + char *x; + int i, j; - if((i=searchdef(t))) - { - i+=rlist; - x=liste[i].search; - sprintf(s,"\n%s",x); - if(liste[i].p_anz) - { - sprintf(s+strlen(s),"("); - for(j=0;j=ANZDEF || memfre= ANZDEF || memfre < MAXLINE * 2) + return (E_NOMEM); + /* + printf("define:mem=%04lx\n",mem); + getchar(); + */ + rl = rlist++; - t=h; + liste[rl].search = mem; + for (i = 0; (t[i] != ' ') && (t[i] != '\0') && (t[i] != '('); i++) + *mem++ = t[i]; + *mem++ = '\0'; + memfre -= i + 1; + liste[rl].s_len = i; + liste[rl].p_anz = 0; - liste[rl].replace=mem; - (void)strcpy(mem,t); - mem+=strlen(t)+1; + /* printf("define:%s\nlen1=%d\n",liste[rl].search,liste[rl].s_len); + getchar(); + */ + + if (t[i] == '(') { + while (t[i] != ')' && t[i] != '\0') { + i++; + liste[rl].p_anz++; + // skip whitespace before parameter name + while (isspace(t[i])) + i++; + // find length + for (j = 0; + (!isspace(t[i + j])) && t[i + j] != ')' && t[i + j] != ',' + && t[i + j] != '\0'; j++) + ; + if (j < memfre) { + strncpy(mem, t + i, j); + mem += j; + *mem++ = '\0'; + memfre -= j + 1; + } + i += j; + // skip trailing whitespace after parameter name + while (isspace(t[i])) + i++; + } + if (t[i] == ')') + i++; + } + while (t[i] == ' ') + i++; + t += i; + + er = pp_replace(h, t, -1, rlist); + + t = h; + + liste[rl].replace = mem; + (void) strcpy(mem, t); + mem += strlen(t) + 1; #if 0 /* debug */ { char *ss; if(liste[rl].p_anz) @@ -424,54 +396,50 @@ int pp_define(char *k) } } #endif - if(!er) - { - hash=hashcode(liste[rl].search,liste[rl].s_len); - liste[rl].nextindex=hashindex[hash]; - hashindex[hash]=rl; - } else - rlist=rl; - - return(er); + if (!er) { + hash = hashcode(liste[rl].search, liste[rl].s_len); + liste[rl].nextindex = hashindex[hash]; + hashindex[hash] = rl; + } else + rlist = rl; + + return (er); } -int tcompare(char s[],char *v[], int n) -{ - int i,j,l; - static char t[MAXLINE]; +int tcompare(char s[], char *v[], int n) { + int i, j, l; + static char t[MAXLINE]; - for(i=0; s[i]!='\0'; i++) - t[i]=tolower(s[i]); - t[i]='\0'; + for (i = 0; s[i] != '\0'; i++) + t[i] = tolower(s[i]); + t[i] = '\0'; - for(i=0;ii=%d, len=%d\n", n, liste[n].search,i, liste[n].s_len); #endif - return i == liste[n].s_len; + return i == liste[n].s_len; } /** @@ -487,11 +455,11 @@ static int check_name(char *t, int n) { * blist -> * */ -static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int *l, int blist) -{ +static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, + int *l, int blist) { int er = E_OK; int i, d; - char c; + char c; // save mem, to restore it when we don't need the pseudo replacements anymore // Note: in a real version, that should probably be a parameter, and not fiddling @@ -502,130 +470,118 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int printf("replace part: n=%d, sl=%d, rec=%d, %s\n", n, sl, recursive, t); #endif - // yes, mark replacement string - char *rs=liste[n].replace; - - // does it have parameters? + // yes, mark replacement string + char *rs = liste[n].replace; - - if(liste[n].p_anz) - { - // yes, we have parameters, so we need to pp_replace them - // as well. - char fti[MAXLINE],fto[MAXLINE]; + // does it have parameters? - // copy replacement into temp buffer - (void)strcpy(fti,liste[n].replace); + if (liste[n].p_anz) { + // yes, we have parameters, so we need to pp_replace them + // as well. + char fti[MAXLINE], fto[MAXLINE]; - // boundary checks ... - if(blist+liste[n].p_anz>=ANZDEF || memfre= ANZDEF || memfre < MAXLINE * 2) + er = E_NOMEM; + else { + // ... passed + // y points to the char behind the input name (i.e. the '(') + char *y = t + sl; + // x points into the pp definition, with the parameter definition names + // following the definition name, separated by \0. Starts here behind the + // name - i.e. now points to the name of the first parameter + char *x = liste[n].search + sl + 1; + // does the input actually have a '(' as parameter marker? + if (*y != '(') { + // no. Should probably get an own error (E_PARAMETER_EXPECTED) + er = E_SYNTAX; + } else { + // mx now points to next free memory (mem current pointer in text table) + char *mx = mem - 1; + // walk through the pp parameters + // by creating "fake" preprocessor definitions at the end + // of the current definition list, i.e. in liste[] after index + // rlist. + for (i = 0; i < liste[n].p_anz; i++) { + char c; + int hkfl = 0; // quote flag + int klfl = 0; // brackets counter + + // create new replacement entry + liste[blist + i].search = x; + liste[blist + i].s_len = (int) strlen(x); + liste[blist + i].p_anz = 0; + liste[blist + i].replace = mx + 1; + // move x over to the next parameter name + x += strlen(x) + 1; + // points to first char of the parameter name in the input + // copy over first char into text memory (note that the position + // is already stored in liste[].replace above) + c = *(++mx) = *(++y); + // copy over the other characters + while (c != '\0' + && ((hkfl != 0 || klfl != 0) + || (c != ',' && c != ')'))) { + if (c == '\"') + hkfl = hkfl ^ 1; + if (!hkfl) { + if (c == '(') + klfl++; + if (c == ')') + klfl--; + } + c = *(++mx) = *(++y); } + // zero-terminate stored string + *mx = '\0'; + // if i is for the last parameter, then check if the + // last copied char was ')', otherwise it should be ',' + // as separator for the next parameter + if (c != ((i == liste[n].p_anz - 1) ? ')' : ',')) { + er = E_ANZPAR; + // note: this break only exits the innermost loop! + break; + } + } + // at this point we have "augmented" the pp definitions + // with a list of new definitions for the macro parameters + // so that when pp_replace'ing them recursively the macro parameters + // will automatically be replaced. + + // if we ran into an error, report so + if (er != E_OK) { + return (er); + } + + // let mx point to first free (and not last non-free) byte + mx++; + + // before we use the parameter replacements, we need to + // recursively evaluate and replace them as well. - // let mx point to first free (and not last non-free) byte - mx++; - - // before we use the parameter replacements, we need to - // recursively evaluate and replace them as well. - #ifdef DEBUG_RECMAC printf("replace (er=%d):\n", er); printf("%s=%s\n",liste[n].search,liste[n].replace); #endif - // loop over all arguments - for(i=0;i b=%d\n", recursive, blist, blist+liste[n].p_anz); printf(" from: %s\n", fti); #endif - er=pp_replace(fto,fti,recursive ? 0 : blist,blist+liste[n].p_anz); + er = pp_replace(fto, fti, recursive ? 0 : blist, + blist + liste[n].p_anz); #ifdef DEBUG_RECMAC printf(" to: %s\n", fto); #endif - } -/* if(flag) printf("sl=%d,",sl);*/ - sl=(int)((long)y+1L-(long)t); -/* if(flag) printf("sl=%d\n",sl);*/ - rs=fto; + } + /* if(flag) printf("sl=%d,",sl);*/ + sl = (int) ((long) y + 1L - (long) t); + /* if(flag) printf("sl=%d\n",sl);*/ + rs = fto; #ifdef DEBUG_RECMAC printf("->%s\n",fto); #endif - } - } - if(er) { - mem = saved_mem; - return(er); - } - } // end if(liste[n].p_anz), i.e. if it has parameters + } + } + if (er) { + mem = saved_mem; + return (er); + } + } // end if(liste[n].p_anz), i.e. if it has parameters - d=(int)strlen(rs)-sl; + d = (int) strlen(rs) - sl; - if(strlen(to)+d>=MAXLINE) { - mem = saved_mem; - return(E_NOMEM); - } + if (strlen(to) + d >= MAXLINE) { + mem = saved_mem; + return (E_NOMEM); + } -/* - if(d<0) - { - y=t+sl+d; - x=t+sl; - while(*y++=*x++); - } - if(d>0) - { - for(ll=strlen(t);ll>=sl;ll--) - t[ll+d]=t[ll]; - } -*/ - if(d) { - // d can be positive or negative, so strcpy cannot be used, use memmove instead - (void)memmove(t+sl+d,t+sl, strlen(t) - sl + 1); - } + /* + if(d<0) + { + y=t+sl+d; + x=t+sl; + while(*y++=*x++); + } + if(d>0) + { + for(ll=strlen(t);ll>=sl;ll--) + t[ll+d]=t[ll]; + } + */ + if (d) { + // d can be positive or negative, so strcpy cannot be used, use memmove instead + (void) memmove(t + sl + d, t + sl, strlen(t) - sl + 1); + } - i=0; - while((c=rs[i])) { - t[i++]=c; - } - // other change from recursive. there sl is missing from add - //*l=(recursive ? 0 : sl) + d;/*=0;*/ - *l=sl + d;/*=0;*/ + i = 0; + while ((c = rs[i])) { + t[i++] = c; + } + // other change from recursive. there sl is missing from add + //*l=(recursive ? 0 : sl) + d;/*=0;*/ + *l = sl + d;/*=0;*/ mem = saved_mem; @@ -753,478 +710,465 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int * parameters * */ -int pp_replace(char *to, char *ti, int a,int b) -{ - char *t=to; - int l,n,sl,er=E_OK; - int ld; // length of name/token to analyse -/* - int flag=!strncmp(ti,"TOUT",4); - if(flag) printf("flag=%d\n",flag); -*/ - // t points to to, so copy input to output 1:1 - // then below work on the copy in-place - (void)strcpy(t,ti); +int pp_replace(char *to, char *ti, int a, int b) { + char *t = to; + int l, n, sl, er = E_OK; + int ld; // length of name/token to analyse + /* + int flag=!strncmp(ti,"TOUT",4); + if(flag) printf("flag=%d\n",flag); + */ + // t points to to, so copy input to output 1:1 + // then below work on the copy in-place + (void) strcpy(t, ti); - // if there are replacements in the list of replacements - if(rlist) - { - // loop over the whole input - while(t[0]!='\0' && t[0] != ';') - { - // skip over the whitespace - // comment handling is NASTY NASTY NASTY - // but I currently don't see another way, as comments and colons - // can (and do) appear in preprocessor replacements - char quotefl = 0; - char commentfl = 0; - while((t[0] != 0) && (quotefl || commentfl || ((!isalpha(t[0]) && t[0]!='_')))) { - if (t[0]=='\0') { - break; /*return(E_OK);*/ - } else - { - if (t[0] == ';' && !quotefl) { - commentfl = 1; - } - if (t[0] == ':' && !quotefl && !ca65 && !masm) { - // note that both ca65 and masm allow colons in comments - // so in these cases we cannot reset the comment handling here - commentfl = 0; - } - if (quotefl) { - // ignore other quotes within a quote - if (t[0] == quotefl) { - quotefl = 0; + // if there are replacements in the list of replacements + if (rlist) { + // loop over the whole input + while (t[0] != '\0' && t[0] != ';') { + // skip over the whitespace + // comment handling is NASTY NASTY NASTY + // but I currently don't see another way, as comments and colons + // can (and do) appear in preprocessor replacements + char quotefl = 0; + char commentfl = 0; + while ((t[0] != 0) + && (quotefl || commentfl + || ((!isalpha(t[0]) && t[0] != '_')))) { + if (t[0] == '\0') { + break; /*return(E_OK);*/ + } else { + if (t[0] == ';' && !quotefl) { + commentfl = 1; + } + if (t[0] == ':' && !quotefl && !ca65 && !masm) { + // note that both ca65 and masm allow colons in comments + // so in these cases we cannot reset the comment handling here + commentfl = 0; + } + if (quotefl) { + // ignore other quotes within a quote + if (t[0] == quotefl) { + quotefl = 0; + } + } else if (t[0] == '"' || t[0] == '\'') { + quotefl = t[0]; + } + t++; + ti++; + } } - } else - if (t[0] == '"' || t[0] == '\'') { - quotefl = t[0]; - } - t++; - ti++; - } - } - - // determine the length of the name - for(l=0;isalnum(t[l])||t[l]=='_';l++); - // store in ld - ld=l; + + // determine the length of the name + for (l = 0; isalnum(t[l]) || t[l] == '_'; l++) + ; + // store in ld + ld = l; #ifdef DEBUG_RECMAC printf("l=%d,a=%d,b=%d, t=%s\n",l,a, b ,t); #endif - - // the following if() is executed when being called from an - // 'external' context, i.e. not from a recursion - if(a<0) - { - // when called from an external context, not by recursion - // compute hashcode for the name for the search index entry (liste[n]) - n=hashindex[hashcode(t,l)]; - - // loop over all entries in linked list for hash code (think: hash collisions) - do // while(1); - { - // length of name of pp definition - sl=liste[n].s_len; + // the following if() is executed when being called from an + // 'external' context, i.e. not from a recursion + if (a < 0) { + // when called from an external context, not by recursion + + // compute hashcode for the name for the search index entry (liste[n]) + n = hashindex[hashcode(t, l)]; + + // loop over all entries in linked list for hash code (think: hash collisions) + do// while(1); + { + // length of name of pp definition + sl = liste[n].s_len; #ifdef DEBUG_RECMAC printf("macro entry: name=%s, sl=%d, p_anz=%d\n", liste[n].search, sl, liste[n].p_anz); #endif - // does pp definition match what we have found? - if(sl && (sl==l) && check_name(t, n)) - { - er = pp_replace_part(to, t, n, sl, 0, &l, b); - if (er != E_OK) { - return er; + // does pp definition match what we have found? + if (sl && (sl == l) && check_name(t, n)) { + er = pp_replace_part(to, t, n, sl, 0, &l, b); + if (er != E_OK) { + return er; + } + break; + } + if (!n) + break; + + // next index in linked list for given hash code + n = liste[n].nextindex; + + } while (1); + } else { + // called when in recursive call + // loop over all the replacement entries from the given b down to 0 + // that allows to replace the parameters first (as they were added at + // the end of the list) + for (n = b - 1; n >= a; n--) { + sl = liste[n].s_len; + + if (sl && (sl == l) && check_name(t, n)) { + er = pp_replace_part(to, t, n, sl, 1, &l, b); + break; + } + } } - break; - } - if(!n) - break; - - // next index in linked list for given hash code - n=liste[n].nextindex; - - } while(1); - } else - { - // called when in recursive call - // loop over all the replacement entries from the given b down to 0 - // that allows to replace the parameters first (as they were added at - // the end of the list) - for(n=b-1;n>=a;n--) - { - sl=liste[n].s_len; - - if(sl && (sl==l) && check_name(t, n)) - { - er = pp_replace_part(to, t, n, sl, 1, &l, b); - break; - } - } - } - // advance input by length of name - ti+=ld; - // advance output by l - t+=l; - } /* end while(t[0] != 0) */ - } /* end if(rlist) */ - return(E_OK); + // advance input by length of name + ti += ld; + // advance output by l + t += l; + } /* end while(t[0] != 0) */ + } /* end if(rlist) */ + return (E_OK); } -int pp_init(void) -{ - int er; +int pp_init(void) { + int er; - for(er=0;er<256;er++) - hashindex[er]=0; - - fsp=0; + for (er = 0; er < 256; er++) + hashindex[er] = 0; - er=0; - mem=malloc(MAXPP); - if(!mem) er=E_NOMEM; + fsp = 0; - memfre=MAXPP; - rlist=0; - nlf=1; - nff=1; - if(!er) { - liste=malloc((long)ANZDEF*sizeof(List)); - if(!liste) er=E_NOMEM; - if(!er && !xa23) { - er = pp_define("XA_MAJOR " progmajor); - if (!er) er = pp_define("XA_MINOR " progminor); - if (!er) er = pp_define("XA_PATCH " progpatch); + er = 0; + mem = malloc(MAXPP); + if (!mem) + er = E_NOMEM; + + memfre = MAXPP; + rlist = 0; + nlf = 1; + nff = 1; + if (!er) { + liste = malloc((long) ANZDEF * sizeof(List)); + if (!liste) + er = E_NOMEM; + if (!er && !xa23) { + er = pp_define("XA_MAJOR " progmajor); + if (!er) + er = pp_define("XA_MINOR " progminor); + if (!er) + er = pp_define("XA_PATCH " progpatch); + } } - } - return(er); + return (er); } -int pp_open(char *name) -{ - FILE *fp; - int l; +int pp_open(char *name) { + FILE *fp; + int l; - fp=xfopen(name,"r"); + fp = xfopen(name, "r"); - l = strlen(name); + l = strlen(name); - /* we have to alloc it dynamically to make the name survive another - pp_open - it's used in the cross-reference list */ - flist[0].fname = malloc(l+1); - if(!flist[0].fname) { - fprintf(stderr,"Oops, no more memory!\n"); - exit(1); - } - (void)strncpy(flist[0].fname,name,l+1); - flist[0].fline=0; - flist[0].bdepth=b_depth(); - flist[0].filep=fp; - flist[0].flinep=NULL; + /* we have to alloc it dynamically to make the name survive another + pp_open - it's used in the cross-reference list */ + flist[0].fname = malloc(l + 1); + if (!flist[0].fname) { + fprintf(stderr, "Oops, no more memory!\n"); + exit(1); + } + (void) strncpy(flist[0].fname, name, l + 1); + flist[0].fline = 0; + flist[0].bdepth = b_depth(); + flist[0].filep = fp; + flist[0].flinep = NULL; - return (fp == NULL); + return (fp == NULL); } -void pp_close(void) -{ - if(flist[fsp].bdepth != b_depth()) { - fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n", - flist[fsp].fname, flist[fsp].bdepth, b_depth()); - } - fclose(flist[fsp].filep); +void pp_close(void) { + if (flist[fsp].bdepth != b_depth()) { + fprintf(stderr, + "Blocks not consistent in file %s: start depth=%d, end depth=%d\n", + flist[fsp].fname, flist[fsp].bdepth, b_depth()); + } + fclose(flist[fsp].filep); } -void pp_end(void) { } +void pp_end(void) { +} -Datei *pp_getidat(void) { +Datei* pp_getidat(void) { return &flist[fsp]; } -int icl_close(int *c) -{ - *c='\n'; - if(!fsp) - return(E_EOF); - - if(flist[fsp].bdepth != b_depth()) { - fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n", - flist[fsp].fname, flist[fsp].bdepth, b_depth()); - } +int icl_close(int *c) { + *c = '\n'; + if (!fsp) + return (E_EOF); - fclose(flist[fsp--].filep); - nff=1; - - return(E_OK); -} - -int icl_open(char *tt) -{ - FILE *fp2; - char *namep; - int len,j,i=0; - - pp_replace(s,tt,-1,rlist); - - if(fsp>=MAXFILE) - return(-1); - - if(s[i]=='<' || s[i]=='"') - i++; - - for(j=i;s[j];j++) - if(s[j]=='>' || s[j]=='"') - s[j]='\0'; - - fp2=xfopen(s+i,"r"); - - if(!fp2) - return(E_FNF); - - setvbuf(fp2,NULL,_IOFBF,BUFSIZE); - - fsp++; - - namep = s+i; - len = strlen(namep); - - /* we have to alloc it dynamically to make the name survive another - pp_open - it's used in the cross-reference list */ - flist[fsp].fname = malloc(len+1); - if(!flist[fsp].fname) { - fprintf(stderr,"Oops, no more memory!\n"); - exit(1); - } - strncpy(flist[fsp].fname,namep, len+1); - flist[fsp].fline=0; - flist[fsp].bdepth=b_depth(); - flist[fsp].flinep=NULL; - flist[fsp].filep=fp2; - nff=1; - - return(0); -} - - -int pgetline(char *t) -{ - int c,er=E_OK; - int rlen, tlen; - char *p = 0; - char *q = 0; - - loopfl =0; /* set if additional fetch needed */ - - filep =flist+fsp; - - do { - int is_continuation = 0; - tlen = 0; // start of current line in in_line[] - do { - c=fgetline(in_line + tlen, MAXLINE - tlen, &rlen, flist[fsp].filep); - //fprintf(stderr, "fgetline -> c=%02x, rlen->%d, t->%s\n", c, rlen, in_line+tlen); - - /* check for continuation lines */ - is_continuation = ((c == '\n') && (rlen > 0) && (in_line[tlen + rlen - 1]=='\\')); - if (is_continuation) { - // cut off the continuation character - rlen--; - in_line[tlen + rlen] = 0; - } - - tlen += rlen; - } while (is_continuation); - - if(in_line[0]=='#' || in_line[0] == altppchar) - { - if (in_line[1]==' ') { /* cpp comment -- pp_comand doesn't - handle this right */ - er=pp_cpp(in_line+1); - } else { - if((er=pp_comand(in_line+1))) - { - if(er!=1) - { - logout(in_line); - logout("\n"); - } - } - } - } else { - er=1; - } - - if(c==EOF) { - if (loopfl && fsp) { - char bletch[MAXLINE]; - sprintf(bletch, - "at end of included file %s:\n", flist[fsp].fname); - logout(bletch); - errout(W_OPENPP); - } - er=icl_close(&c); + if (flist[fsp].bdepth != b_depth()) { + fprintf(stderr, + "Blocks not consistent in file %s: start depth=%d, end depth=%d\n", + flist[fsp].fname, flist[fsp].bdepth, b_depth()); } - } while(!er || (loopfl && er!=E_EOF)); + fclose(flist[fsp--].filep); + nff = 1; + + return (E_OK); +} + +int icl_open(char *tt) { + FILE *fp2; + char *namep; + int len, j, i = 0; + + pp_replace(s, tt, -1, rlist); + + if (fsp >= MAXFILE) + return (-1); + + if (s[i] == '<' || s[i] == '"') + i++; + + for (j = i; s[j]; j++) + if (s[j] == '>' || s[j] == '"') + s[j] = '\0'; + + fp2 = xfopen(s + i, "r"); + + if (!fp2) + return (E_FNF); + + setvbuf(fp2, NULL, _IOFBF, BUFSIZE); + + fsp++; + + namep = s + i; + len = strlen(namep); + + /* we have to alloc it dynamically to make the name survive another + pp_open - it's used in the cross-reference list */ + flist[fsp].fname = malloc(len + 1); + if (!flist[fsp].fname) { + fprintf(stderr, "Oops, no more memory!\n"); + exit(1); + } + strncpy(flist[fsp].fname, namep, len + 1); + flist[fsp].fline = 0; + flist[fsp].bdepth = b_depth(); + flist[fsp].flinep = NULL; + flist[fsp].filep = fp2; + nff = 1; + + return (0); +} + +int pgetline(char *t) { + int c, er = E_OK; + int rlen, tlen; + char *p = 0; + char *q = 0; + + loopfl = 0; /* set if additional fetch needed */ + + filep = flist + fsp; + + do { + int is_continuation = 0; + tlen = 0; // start of current line in in_line[] + do { + c = fgetline(in_line + tlen, MAXLINE - tlen, &rlen, + flist[fsp].filep); + //fprintf(stderr, "fgetline -> c=%02x, rlen->%d, t->%s\n", c, rlen, in_line+tlen); + + /* check for continuation lines */ + is_continuation = ((c == '\n') && (rlen > 0) + && (in_line[tlen + rlen - 1] == '\\')); + if (is_continuation) { + // cut off the continuation character + rlen--; + in_line[tlen + rlen] = 0; + } + + tlen += rlen; + } while (is_continuation); + + if (in_line[0] == '#' || in_line[0] == altppchar) { + if (in_line[1] == ' ') { /* cpp comment -- pp_comand doesn't + handle this right */ + er = pp_cpp(in_line + 1); + } else { + if ((er = pp_comand(in_line + 1))) { + if (er != 1) { + logout(in_line); + logout("\n"); + } + } + } + } else { + er = 1; + } + + if (c == EOF) { + if (loopfl && fsp) { + char bletch[MAXLINE]; + sprintf(bletch, "at end of included file %s:\n", + flist[fsp].fname); + logout(bletch); + errout(W_OPENPP); + } + er = icl_close(&c); + } + + } while (!er || (loopfl && er != E_EOF)); if (loopfl) { errout(E_OPENPP); } + if (!er || loopfl) { + in_line[0] = '\0'; + } - if(!er || loopfl) { - in_line[0]='\0'; - } + er = (er == 1) ? E_OK : er; - er= (er==1) ? E_OK : er ; - - if(!er) { + if (!er) { #ifdef DEBUG_REPLACE // printf("<<<: %s\n", in_line); #endif - er=pp_replace(t,in_line,-1,rlist); + er = pp_replace(t, in_line, -1, rlist); #ifdef DEBUG_REPLACE printf(">>>: %s\n", t); #endif - } + } - if(!er && nff) - er=E_NEWFILE; - if(!er && nlf) - er=E_NEWLINE; - nlf=nff=0; + if (!er && nff) + er = E_NEWFILE; + if (!er && nlf) + er = E_NEWLINE; + nlf = nff = 0; - filep=flist+fsp; - filep->flinep=in_line; - - //fprintf(stderr, "pgetline -> er=%d, t=%s\n", er, t); - return(er); + filep = flist + fsp; + filep->flinep = in_line; + + //fprintf(stderr, "pgetline -> er=%d, t=%s\n", er, t); + return (er); } - /*************************************************************************/ /* smart getc that can skip C comment blocks */ -int rgetc(FILE *fp) -{ - int incomment; - int c; - static int d; - static int d_isvalid = 0; - static int last = 0; +int rgetc(FILE *fp) { + int incomment; + int c; + static int d; + static int d_isvalid = 0; + static int last = 0; - incomment=0; + incomment = 0; - do - { - restart: + do { + restart: - /* we had a look-ahead to see if two-char sequence was received? */ - if (d_isvalid) { - c = d; - d_isvalid = 0; - } else { - c = getc(fp); - } - while(c==13) { - c = getc(fp); - }; /* remove ^M for unices */ - - /* a newlinebreaks any quote */ - if (c == '\n') { - inquote = 0; - - flist[fsp].fline++; - nlf=1; - } - - /* check for start of comment anyway, to allow for nested comments */ - /* only allow this with 2.3 compatibility */ - if(!inquote && c=='/' && (xa23 || !incomment)) - { - d = getc(fp); - - // C++ double slash comment - if (d == '/') { - do { - c = getc(fp); - } while (c != '\n' && c != EOF); - if (c == '\n') { - flist[fsp].fline++; - nlf=1; - } - } else - if (d == '*') { - /* start block comment */ - incomment++; - /* convene normal processing */ - goto restart; + /* we had a look-ahead to see if two-char sequence was received? */ + if (d_isvalid) { + c = d; + d_isvalid = 0; } else { - d_isvalid = 1; + c = getc(fp); } - } + while (c == 13) { + c = getc(fp); + }; /* remove ^M for unices */ + /* a newlinebreaks any quote */ + if (c == '\n') { + inquote = 0; - /* here we are in a dilemma. If we interpret quotes in comments, - * this may break end-of-block comment when singular quotes are - * in a comment. If we don't interpret quotes in a comment, - * a quoted string with end-of-comment in it may break when - * commented. - * - * Unfortunately GeckOS has quotes in comments, and in an inconsistent way. - * - * #define E_FILLNAM <-34 / * illegal name (joker "*","?","\"") * / - * - * ... except if we handle backslash-escaped quotes? No, then this breaks - * in apps/lsh/lsh.a65:347 - * - * / * TODO: interpret "\" escape codes, shell variables * / - * - * But I guess for 2.4 it is ok to break things like this. - */ + flist[fsp].fline++; + nlf = 1; + } - if (!incomment) { - /* not in comment */ + /* check for start of comment anyway, to allow for nested comments */ + /* only allow this with 2.3 compatibility */ + if (!inquote && c == '/' && (xa23 || !incomment)) { + d = getc(fp); - /* flag if we're in a quoted string */ - /* but only if quote isnot escaped with backslash */ - if(c=='"' && last!='\\' && !quotebs) { - inquote ^= 1; - } - - /* implement backslashed quotes for 2.4 */ - if(!xa23 && c=='\\') quotebs=1; else quotebs=0; - - } else { - /* in comment */ - - /* check for end of comment */ - /* note: for xa2.3, incomment only set true if not quoted, and quote not changed in comment */ - if((!inquote || !xa23) && (c=='*')) - { - if((d=getc(fp))!='/') { - d_isvalid = 1; - } else { - incomment--; + // C++ double slash comment + if (d == '/') { + do { + c = getc(fp); + } while (c != '\n' && c != EOF); + if (c == '\n') { + flist[fsp].fline++; + nlf = 1; + } + } else if (d == '*') { + /* start block comment */ + incomment++; /* convene normal processing */ goto restart; + } else { + d_isvalid = 1; } - } + } - } - - /* force newline at the end of a file */ - if (c == EOF && last != EOF) { - last = EOF; - c = '\n'; - } else { - last = c; - } + /* here we are in a dilemma. If we interpret quotes in comments, + * this may break end-of-block comment when singular quotes are + * in a comment. If we don't interpret quotes in a comment, + * a quoted string with end-of-comment in it may break when + * commented. + * + * Unfortunately GeckOS has quotes in comments, and in an inconsistent way. + * + * #define E_FILLNAM <-34 / * illegal name (joker "*","?","\"") * / + * + * ... except if we handle backslash-escaped quotes? No, then this breaks + * in apps/lsh/lsh.a65:347 + * + * / * TODO: interpret "\" escape codes, shell variables * / + * + * But I guess for 2.4 it is ok to break things like this. + */ - } while(incomment && (c!=EOF)); + if (!incomment) { + /* not in comment */ - return(c-'\t'?c:' '); + /* flag if we're in a quoted string */ + /* but only if quote isnot escaped with backslash */ + if (c == '"' && last != '\\' && !quotebs) { + inquote ^= 1; + } + + /* implement backslashed quotes for 2.4 */ + if (!xa23 && c == '\\') + quotebs = 1; + else + quotebs = 0; + + } else { + /* in comment */ + + /* check for end of comment */ + /* note: for xa2.3, incomment only set true if not quoted, and quote not changed in comment */ + if ((!inquote || !xa23) && (c == '*')) { + if ((d = getc(fp)) != '/') { + d_isvalid = 1; + } else { + incomment--; + /* convene normal processing */ + goto restart; + } + } + + } + + /* force newline at the end of a file */ + if (c == EOF && last != EOF) { + last = EOF; + c = '\n'; + } else { + last = c; + } + + } while (incomment && (c != EOF)); + + return (c - '\t' ? c : ' '); } /** @@ -1232,25 +1176,23 @@ int rgetc(FILE *fp) * the rlen out parameter is just convenience, so that * a further strlen() can be saved */ -int fgetline(char *t, int len, int *rlen, FILE *fp) -{ - static int c,i; +int fgetline(char *t, int len, int *rlen, FILE *fp) { + static int c, i; - i=0; + i = 0; - do { - c=rgetc(fp); - - if(c==EOF || c=='\n') - { - t[i]='\0'; - break; - } - t[i]=c; - i= (irt.nlist>=afile->rt.mlist) { - afile->rt.mlist+=500; - afile->rt.rlist=realloc(afile->rt.rlist, afile->rt.mlist*sizeof(relocateInfo)); + + if (afile->rt.nlist >= afile->rt.mlist) { + afile->rt.mlist += 500; + afile->rt.rlist = realloc(afile->rt.rlist, + afile->rt.mlist * sizeof(relocateInfo)); } - if(!afile->rt.rlist) { - fprintf(stderr, "Oops: no memory for relocation table!\n"); - exit(1); + if (!afile->rt.rlist) { + fprintf(stderr, "Oops: no memory for relocation table!\n"); + exit(1); } afile->rt.rlist[afile->rt.nlist].adr = pc; afile->rt.rlist[afile->rt.nlist].afl = afl; 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... */ - if(afile->rt.first<0) { - afile->rt.first = afile->rt.nlist; + if (afile->rt.first < 0) { + afile->rt.first = afile->rt.nlist; } else { - p=afile->rt.first; pp=-1; - while(afile->rt.rlist[p].adrrt.rlist[p].next>=0) { - 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); -*/ - if(afile->rt.rlist[p].next<0 && afile->rt.rlist[p].adrrt.rlist[p].next=afile->rt.nlist; - } else - if(pp==-1) { - afile->rt.rlist[afile->rt.nlist].next = afile->rt.first; - afile->rt.first = afile->rt.nlist; - } else { - afile->rt.rlist[afile->rt.nlist].next = p; - afile->rt.rlist[pp].next = afile->rt.nlist; - } + p = afile->rt.first; + pp = -1; + while (afile->rt.rlist[p].adr < pc && afile->rt.rlist[p].next >= 0) { + 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); + */ + if (afile->rt.rlist[p].next < 0 && afile->rt.rlist[p].adr < pc) { + afile->rt.rlist[p].next = afile->rt.nlist; + } else if (pp == -1) { + afile->rt.rlist[afile->rt.nlist].next = afile->rt.first; + afile->rt.first = afile->rt.nlist; + } else { + afile->rt.rlist[afile->rt.nlist].next = p; + afile->rt.rlist[pp].next = 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 p=afile->rt.first; + int p = afile->rt.first; int pc2, afl; - while(p>=0) { - pc2=afile->rt.rlist[p].adr; - afl=afile->rt.rlist[p].afl; - /* hack to switch undef and abs flag from internal to file format */ - if( ((afl & A_FMASK)>>8) < SEG_TEXT) afl^=0x100; -/*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/ - if((pc2-pc) < 0) { - fprintf(stderr, "Oops, negative offset!\n"); - } else { - while((pc2-pc)>254) { - fputc(255,fp); - pc+=254; - } - fputc(pc2-pc, fp); - pc=pc2; - if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEFZP<<8)) { - fputc( (((afl & ~A_FMASK)>>8)&255)|SEG_UNDEF, fp); - fputc(afile->rt.rlist[p].lab & 255, fp); - fputc((afile->rt.rlist[p].lab>>8) & 255, fp); - } else { - fputc( (afl>>8)&255, fp); - if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8)) { - fputc(afile->rt.rlist[p].lab & 255, fp); - fputc((afile->rt.rlist[p].lab>>8) & 255, fp); - } - } - if((afl&A_MASK)==A_HIGH) fputc(afl&255,fp); - } - p=afile->rt.rlist[p].next; + while (p >= 0) { + pc2 = afile->rt.rlist[p].adr; + afl = afile->rt.rlist[p].afl; + /* hack to switch undef and abs flag from internal to file format */ + if (((afl & A_FMASK) >> 8) < SEG_TEXT) + afl ^= 0x100; + /*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/ + if ((pc2 - pc) < 0) { + fprintf(stderr, "Oops, negative offset!\n"); + } else { + while ((pc2 - pc) > 254) { + fputc(255, fp); + pc += 254; + } + fputc(pc2 - pc, fp); + pc = pc2; + if ((afile->rt.rlist[p].afl & A_FMASK) == (SEG_UNDEFZP << 8)) { + fputc((((afl & ~A_FMASK) >> 8) & 255) | SEG_UNDEF, fp); + fputc(afile->rt.rlist[p].lab & 255, fp); + fputc((afile->rt.rlist[p].lab >> 8) & 255, fp); + } else { + fputc((afl >> 8) & 255, fp); + if ((afile->rt.rlist[p].afl & A_FMASK) == (SEG_UNDEF << 8)) { + fputc(afile->rt.rlist[p].lab & 255, fp); + fputc((afile->rt.rlist[p].lab >> 8) & 255, fp); + } + } + if ((afl & A_MASK) == A_HIGH) + fputc(afl & 255, fp); + } + p = afile->rt.rlist[p].next; } fputc(0, fp); @@ -182,56 +186,58 @@ int rt_write(FILE *fp, int pc) { return 0; } - 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->slen = slen; afile->relmode = relmode; pc[SEG_TEXT] = afile->base[SEG_TEXT] = t_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; 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; int i; afile = malloc(sizeof(File)); - if(!afile) { - fprintf(stderr,"Oops: not enough memory!\n"); - exit(1); + if (!afile) { + fprintf(stderr, "Oops: not enough memory!\n"); + exit(1); } afile->mn.tmp = malloc(TMPMEM); - if(!afile->mn.tmp) { - fprintf(stderr,"Oops: not enough memory!\n"); - exit(1); + if (!afile->mn.tmp) { + fprintf(stderr, "Oops: not enough memory!\n"); + exit(1); } afile->mn.tmpz = 0; afile->mn.tmpe = 0; - afile->ud.ulist = NULL; afile->ud.un = afile->ud.um = 0; - afile->rt.rlist = NULL; afile->rt.first = -1; + afile->ud.ulist = NULL; + afile->ud.un = afile->ud.um = 0; + afile->rt.rlist = NULL; + afile->rt.first = -1; 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->fo.olist = NULL; afile->fo.mlist = afile->fo.nlist = 0; - for(i=0;i<256;i++) afile->la.hashindex[i]=0; - afile->la.lt = NULL; + for (i = 0; i < 256; i++) + afile->la.hashindex[i] = 0; + afile->la.lt = NULL; afile->la.lti = 0; afile->la.ltm = 0; - afile->len[SEG_TEXT] = afile->len[SEG_DATA] = - afile->len[SEG_BSS] = afile->len[SEG_ZERO] = 0; + afile->len[SEG_TEXT] = afile->len[SEG_DATA] = afile->len[SEG_BSS] = + afile->len[SEG_ZERO] = 0; return afile; } @@ -240,11 +246,11 @@ void seg_pass2(void) { pc[SEG_TEXT] = afile->base[SEG_TEXT]; 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]; afile->old_abspc = pc[SEG_ABS]; - pc[SEG_ABS] = pc[SEG_TEXT]; + pc[SEG_ABS] = pc[SEG_TEXT]; } 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]; #endif /* 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", - afile->len[SEG_TEXT], afile->len[SEG_DATA], afile->len[SEG_BSS], afile->len[SEG_ZERO]);*/ + /*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]);*/ segment = SEG_ABS; u_write(fpout); - rt_write(fpout, afile->base[SEG_TEXT]-1); - rd_write(fpout, afile->base[SEG_DATA]-1); - l_write(fpout); + rt_write(fpout, afile->base[SEG_TEXT] - 1); + rd_write(fpout, afile->base[SEG_DATA] - 1); + l_write(fpout); } /* write header for relocatable output format */ -int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen, - int stack) { +int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen, + int stack) { afile->len[SEG_TEXT] = tlen; afile->len[SEG_DATA] = dlen; - afile->len[SEG_BSS ] = blen; + afile->len[SEG_BSS] = blen; afile->len[SEG_ZERO] = zlen; - fputc(1, fp); /* version byte */ - fputc(0, fp); /* hi address 0 -> no C64 */ - fputc('o', fp); - fputc('6', fp); - fputc('5', fp); - fputc(0, fp); /* format version */ - fputw(mode, fp); /* file mode */ - fputw(afile->base[SEG_TEXT],fp); /* text base */ - fputw(tlen,fp); /* text length */ - fputw(afile->base[SEG_DATA],fp); /* data base */ - fputw(dlen,fp); /* data length */ - fputw(afile->base[SEG_BSS],fp); /* bss base */ - fputw(blen,fp); /* bss length */ - fputw(afile->base[SEG_ZERO],fp); /* zerop base */ - fputw(zlen,fp); /* zerop length */ - fputw(stack,fp); /* needed stack size */ + fputc(1, fp); /* version byte */ + fputc(0, fp); /* hi address 0 -> no C64 */ + fputc('o', fp); + fputc('6', fp); + fputc('5', fp); + fputc(0, fp); /* format version */ + fputw(mode, fp); /* file mode */ + fputw(afile->base[SEG_TEXT], fp); /* text base */ + fputw(tlen, fp); /* text length */ + fputw(afile->base[SEG_DATA], fp); /* data base */ + fputw(dlen, fp); /* data length */ + fputw(afile->base[SEG_BSS], fp); /* bss base */ + fputw(blen, fp); /* bss length */ + fputw(afile->base[SEG_ZERO], fp); /* zerop base */ + fputw(zlen, fp); /* zerop length */ + fputw(stack, fp); /* needed stack size */ - o_write(fp); + o_write(fp); - return 0; + return 0; } diff --git a/xa/src/xar2.c b/xa/src/xar2.c index 5075917..a8cd231 100644 --- a/xa/src/xar2.c +++ b/xa/src/xar2.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * * 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 @@ -25,67 +25,69 @@ #include "xar.h" /* -static relocateInfo *rlist = NULL; -static int mlist = 0, nlist = 0; -static int first = -1; -*/ + static relocateInfo *rlist = NULL; + static int mlist = 0, nlist = 0; + static int first = -1; + */ /* 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);*/ - if(l==2 && ((afl & A_MASK)!=A_ADR)) { - errout(W_BYTRELOC); - /*printf("Warning: byte relocation in word value at PC=$%04x!\n",pc);*/ + if (l == 2 && ((afl & A_MASK) != A_ADR)) { + errout(W_BYTRELOC); + /*printf("Warning: byte relocation in word value at PC=$%04x!\n",pc);*/ } - if(l==1 && ((afl&A_MASK)==A_ADR)) { - if((afl & A_FMASK) != (SEG_ZERO<<8)) errout(W_ADRRELOC); - /*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/ - afl = (afl & (~A_MASK)) | A_LOW; + if (l == 1 && ((afl & A_MASK) == A_ADR)) { + if ((afl & A_FMASK) != (SEG_ZERO << 8)) + errout(W_ADRRELOC); + /*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) { - afile->rd.mlist+=500; - afile->rd.rlist=realloc(afile->rd.rlist, afile->rd.mlist*sizeof(relocateInfo)); + + if (afile->rd.nlist >= afile->rd.mlist) { + afile->rd.mlist += 500; + afile->rd.rlist = realloc(afile->rd.rlist, + afile->rd.mlist * sizeof(relocateInfo)); } - if(!afile->rd.rlist) { - fprintf(stderr, "Oops: no memory for relocation table!\n"); - exit(1); + if (!afile->rd.rlist) { + fprintf(stderr, "Oops: no memory for relocation table!\n"); + exit(1); } afile->rd.rlist[afile->rd.nlist].adr = pc; afile->rd.rlist[afile->rd.nlist].afl = afl; 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... */ - if(afile->rd.first<0) { - afile->rd.first = afile->rd.nlist; + if (afile->rd.first < 0) { + afile->rd.first = afile->rd.nlist; } else { - p=afile->rd.first; pp=-1; - while(afile->rd.rlist[p].adrrd.rlist[p].next>=0) { - 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); -*/ - if(afile->rd.rlist[p].next<0 && afile->rd.rlist[p].adrrd.rlist[p].next=afile->rd.nlist; - } else - if(pp==-1) { - afile->rd.rlist[afile->rd.nlist].next = afile->rd.first; - afile->rd.first = afile->rd.nlist; - } else { - afile->rd.rlist[afile->rd.nlist].next = p; - afile->rd.rlist[pp].next = afile->rd.nlist; - } + p = afile->rd.first; + pp = -1; + while (afile->rd.rlist[p].adr < pc && afile->rd.rlist[p].next >= 0) { + 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); + */ + if (afile->rd.rlist[p].next < 0 && afile->rd.rlist[p].adr < pc) { + afile->rd.rlist[p].next = afile->rd.nlist; + } else if (pp == -1) { + afile->rd.rlist[afile->rd.nlist].next = afile->rd.first; + afile->rd.first = afile->rd.nlist; + } else { + afile->rd.rlist[afile->rd.nlist].next = p; + afile->rd.rlist[pp].next = 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 p=afile->rd.first; + int p = afile->rd.first; int pc2, afl; - while(p>=0) { - pc2=afile->rd.rlist[p].adr; - afl=afile->rd.rlist[p].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 */ - if( ((afl & A_FMASK)>>8) < SEG_TEXT) afl^=0x100; - if((pc2-pc) < 0) { - fprintf(stderr, "Oops, negative offset!\n"); - } else { - while((pc2-pc)>254) { - fputc(255,fp); - pc+=254; - } - fputc(pc2-pc, fp); - pc=pc2; - if((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEFZP<<8)) { - fputc((((afl & ~A_FMASK)>>8)&255)|SEG_UNDEF, fp); - fputc(afile->rd.rlist[p].lab & 255, fp); - fputc((afile->rd.rlist[p].lab>>8) & 255, fp); - } else { - fputc((afl>>8)&255, fp); - if(((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8))) { - fputc(afile->rd.rlist[p].lab & 255, fp); - fputc((afile->rd.rlist[p].lab>>8) & 255, fp); - } - } - if((afl&A_MASK)==A_HIGH) fputc(afl&255,fp); - } - p=afile->rd.rlist[p].next; + while (p >= 0) { + pc2 = afile->rd.rlist[p].adr; + afl = afile->rd.rlist[p].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 */ + if (((afl & A_FMASK) >> 8) < SEG_TEXT) + afl ^= 0x100; + if ((pc2 - pc) < 0) { + fprintf(stderr, "Oops, negative offset!\n"); + } else { + while ((pc2 - pc) > 254) { + fputc(255, fp); + pc += 254; + } + fputc(pc2 - pc, fp); + pc = pc2; + if ((afile->rd.rlist[p].afl & A_FMASK) == (SEG_UNDEFZP << 8)) { + fputc((((afl & ~A_FMASK) >> 8) & 255) | SEG_UNDEF, fp); + fputc(afile->rd.rlist[p].lab & 255, fp); + fputc((afile->rd.rlist[p].lab >> 8) & 255, fp); + } else { + fputc((afl >> 8) & 255, fp); + if (((afile->rd.rlist[p].afl & A_FMASK) == (SEG_UNDEF << 8))) { + fputc(afile->rd.rlist[p].lab & 255, fp); + fputc((afile->rd.rlist[p].lab >> 8) & 255, fp); + } + } + if ((afl & A_MASK) == A_HIGH) + fputc(afl & 255, fp); + } + p = afile->rd.rlist[p].next; } fputc(0, fp); - free(afile->rd.rlist); - afile->rd.rlist = NULL; - afile->rd.mlist = afile->rd.nlist = 0; - afile->rd.first = -1; + free(afile->rd.rlist); + afile->rd.rlist = NULL; + afile->rd.mlist = afile->rd.nlist = 0; + afile->rd.first = -1; return 0; } diff --git a/xa/src/xat.c b/xa/src/xat.c index 7f1d77e..5987786 100644 --- a/xa/src/xat.c +++ b/xa/src/xat.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) + * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de) * maintained by Cameron Kaiser * * Core tokenizing module/pass 1 and pass 2 @@ -115,7 +115,8 @@ char *arith_ops[] = { }; /* length of arithmetic operators indexed by operator number */ -static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2,2,2,1 }; +static int lp[] = { 0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, + 1 }; /* mvn and mvp are handled specially, they have a weird syntax */ #define Kmvp 38 @@ -179,7 +180,6 @@ static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2,2,2,1 }; /* last valid token+1 */ #define Anzkey Lastbef+43 /* define last valid token number; last define above plus one */ - #define Kreloc (Anzkey-256) /* *= (relocation mode) */ #define Ksegment (Anzkey+1-256) /* this actually now is above 127, which might be a problem as char is signed ... */ @@ -187,8 +187,8 @@ int number_of_valid_tokens = Anzkey; /* array used for hashing tokens (26 entries, a-z) */ -static int ktp[]={ 0,3,17,25,28,29,29,29,29,32,34,34,38,40,41,42,58, - 58,65,76,90,90,90,92,94,94,94,Anzkey }; +static int ktp[] = { 0, 3, 17, 25, 28, 29, 29, 29, 29, 32, 34, 34, 38, 40, 41, + 42, 58, 58, 65, 76, 90, 90, 90, 92, 94, 94, 94, Anzkey }; #define Admodes 24 @@ -384,67 +384,66 @@ static int opt[] ={ -1,-1,-1,-1,-1,-1,-1,-1,1,2,3,-1,4,5,-1,-1, /*********************************************************************************************/ /* pass 1 */ -int t_p1(signed char *s, signed char *t, int *ll, int *al) -{ - static int er,l,n,v,nk,na1,na2,bl,am,sy,i,label,byte; /*,j,v2 ;*/ - int afl = 0; - int tlen; /* token listing length, to adjust length that is returned */ - int inp; /* input pointer in t[] */ - unsigned char cast; +int t_p1(signed char *s, signed char *t, int *ll, int *al) { + static int er, l, n, v, nk, na1, na2, bl, am, sy, i, label, byte; /*,j,v2 ;*/ + int afl = 0; + int tlen; /* token listing length, to adjust length that is returned */ + int inp; /* input pointer in t[] */ + unsigned char cast; -/* notes and typical conventions ... er = error code - am = addressing mode in use -*/ + /* notes and typical conventions ... er = error code + am = addressing mode in use + */ - cast='\0'; - bl=0; - *al = 0; + cast = '\0'; + bl = 0; + *al = 0; -/* printf("\n"); */ + /* printf("\n"); */ - /* convert the next token from string s */ + /* convert the next token from string s */ #ifdef DEBUG_AM fprintf(stderr, "- p1 %d starting -\n", pc[segment]); #endif - - /* As the t_p1 code below always works through the tokens - * from t_conv in such a way that it always produces a shorter - * result, the conversion below takes place "in place". - * This, however, means that the original token sequence, which - * would be useful for some assembler listing, is overwritten. - * While the original assumption was ok for a constrained - * environment like the Atari ST, this is no longer true. - * Converting the code below to have separate input and output - * areas would be error-prone, so we do some copy-magic here - * instead...*/ - /* we keep three bytes buffer for "T_LISTING" and the length of the - * token list - */ - t[0]=T_LISTING; - er=t_conv(s,t+6,&l,pc[segment],&nk,&na1,&na2,0,&byte); - tlen = l+6; - t[1]=tlen&255; - t[2]=(tlen>>8)&255; - t[3]=segment; - t[4]=pc[segment]&255; - t[5]=(pc[segment]>>8)&255; - /* now we have to duplicate the token sequence from the T_LISTING buffer - * to the end of "t", so we can then in-place convert it - * below. Non-overlapping, size is known in advance, so - * using memcpy is fine here - */ - inp = 0; - /* discard label definitions before copying the buffer, so we don't get - * label defined errors */ - while (inp> 8) & 255; + t[3] = segment; + t[4] = pc[segment] & 255; + t[5] = (pc[segment] >> 8) & 255; + /* now we have to duplicate the token sequence from the T_LISTING buffer + * to the end of "t", so we can then in-place convert it + * below. Non-overlapping, size is known in advance, so + * using memcpy is fine here + */ + inp = 0; + /* discard label definitions before copying the buffer, so we don't get + * label defined errors */ + while (inp < l && t[6 + inp] == T_DEFINE) { + inp += 3; + } + /* copy the buffer; + * t+tlen is directly after the T_LISTING buffer + * t+6+inp is the start of the T_LISTING buffer, after label defines + * l-inp is the length of the T_LISTING buffer, without label defines + */ + memcpy(t + tlen, t + 6 + inp, l - inp); #ifdef DEBUG_CONV printf("t_conv s:%s\n",s); @@ -454,646 +453,610 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]); printf("\n"); #endif - // update pointers - t=t+tlen; - l-=inp; - /* the result of this is that we always have a Klisting entry in the buffer - * for each tokenization call */ - /* here continue as before, except for adjusting the returne *ll length - * in the end, just before return */ + // update pointers + t = t + tlen; + l -= inp; + /* the result of this is that we always have a Klisting entry in the buffer + * for each tokenization call */ + /* here continue as before, except for adjusting the returne *ll length + * in the end, just before return */ - /* return length default is input length */ - *ll=l; + /* return length default is input length */ + *ll = l; - /* if text/data produced, then no more fopt allowed in romable mode */ - /* TODO: need to check, Kbyte is being remapped to Kbyt. What is the effect here? */ - if((romable>1) && (t[inp]base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length(); - romable=1; - } - if(!er) - { + /* if text/data produced, then no more fopt allowed in romable mode */ + /* TODO: need to check, Kbyte is being remapped to Kbyt. What is the effect here? */ + if ((romable > 1) + && (t[inp] < Kopen || t[inp] == Kbyte || t[inp] == Kpcdef)) { + afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length(); + romable = 1; + } + if (!er) { -/* - * - * pseudo-op dispatch (except .byt, .asc) - * - */ - // fix sign - n=t[0]; // & 0xff; + /* + * + * pseudo-op dispatch (except .byt, .asc) + * + */ + // fix sign + n = t[0]; // & 0xff; - /* TODO: make that a big switch statement... */ - /* maybe later. Cameron */ + /* TODO: make that a big switch statement... */ + /* maybe later. Cameron */ - if(n==Kend || n==Klist || n==Kxlist) { - *ll = 0; /* ignore */ - } else - if(n==Kinclude) { - *ll = 0; /* no output length */ - i=1; - if(t[i]=='\"') { - int k,j=0; - char binfname[255]; - i++; - k=t[i]+i+1; - i++; - while(i 255) - er = E_NOMEM; /* buffer overflow */ - } - binfname[j] = '\0'; - er=icl_open(binfname); - } else { - er=E_SYNTAX; - } - } else - if(n==Kfopt) { - if(romable==1) er=E_ROMOPT; - t[0] = Kbyt; - set_fopt(l,t,nk+1-na1+na2); - *ll = 0; - } else - if(n==Klistbytes) { - int p = 0; - if(!(er=a_term(t+1,&p,&l,pc[segment],&afl,&label,0))) { - er=E_OKDEF; - } - *ll = 3; - t[0] = Klistbytes; - t[1] = p & 0xff; - t[2] = (p >> 8) & 0xff; - //printf("Klistbytes p1: er=%d, l=%d\n", er, l); - } else - if(n==Kpcdef) - { - int tmp; - // get parameter for *= - er=a_term(t+1,&tmp,&l,pc[segment],&afl,&label,0); - // found? - if(!er) - { - i=1; - wval(i,tmp, 0); /* writes T_VALUE, 3 bytes value, plus one byte */ - t[i++]=T_END; - *ll=7; - er=E_OKDEF; + if (n == Kend || n == Klist || n == Kxlist) { + *ll = 0; /* ignore */ + } else if (n == Kinclude) { + *ll = 0; /* no output length */ + i = 1; + if (t[i] == '\"') { + int k, j = 0; + char binfname[255]; + i++; + k = t[i] + i + 1; + i++; + while (i < k && !er) { + binfname[j++] = t[i++]; + if (j > 255) + er = E_NOMEM; /* buffer overflow */ + } + binfname[j] = '\0'; + er = icl_open(binfname); + } else { + er = E_SYNTAX; + } + } else if (n == Kfopt) { + if (romable == 1) + er = E_ROMOPT; + t[0] = Kbyt; + set_fopt(l, t, nk + 1 - na1 + na2); + *ll = 0; + } else if (n == Klistbytes) { + int p = 0; + if (!(er = a_term(t + 1, &p, &l, pc[segment], &afl, &label, 0))) { + er = E_OKDEF; + } + *ll = 3; + t[0] = Klistbytes; + t[1] = p & 0xff; + t[2] = (p >> 8) & 0xff; + //printf("Klistbytes p1: er=%d, l=%d\n", er, l); + } else if (n == Kpcdef) { + int tmp; + // get parameter for *= + er = a_term(t + 1, &tmp, &l, pc[segment], &afl, &label, 0); + // found? + if (!er) { + i = 1; + wval(i, tmp, 0); /* writes T_VALUE, 3 bytes value, plus one byte */ + t[i++] = T_END; + *ll = 7; + er = E_OKDEF; #ifdef DEBUG_RELOC printf("set pc=%04x, oldsegment=%d, pc[segm]=%04x, ", pc[SEG_ABS], segment, pc[segment]); printf(" wrote %02x %02x %02x %02x %02x %02x, %02x, %02x\n", t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7]); #endif - if(segment==SEG_TEXT) { - pc[SEG_ABS] = tmp; - r_mode(RMODE_ABS); - } else { - if(!relmode) { - pc[segment] = tmp; - } else { - er = E_ILLSEGMENT; - } - } -/*printf("newsegment=%d, pc[ABS]=%04x\n", segment, pc[SEG_ABS]);*/ - } else { - // no param found, only "*=". - // if we ABS, we switch back to reloc + if (segment == SEG_TEXT) { + pc[SEG_ABS] = tmp; + r_mode(RMODE_ABS); + } else { + if (!relmode) { + pc[segment] = tmp; + } else { + er = E_ILLSEGMENT; + } + } + /*printf("newsegment=%d, pc[ABS]=%04x\n", segment, pc[SEG_ABS]);*/ + } else { + // no param found, only "*=". + // if we ABS, we switch back to reloc #ifdef DEBUG_RELOC printf("reloc: er=%d, l=%d, segment=%d, pc[%d]=%04x, pc[abs(%d)]=%04x, pc[text(%d)]=%04x\n", er, l, segment, segment, pc[segment], SEG_ABS, pc[SEG_ABS],SEG_TEXT, pc[SEG_TEXT]); #endif - if((segment==SEG_ABS) && (er==E_SYNTAX && l==0)) { - t[0]=Kreloc; - i=1; - wval(i,pc[SEG_TEXT], 0); - t[i++]=T_END; - *ll=7; - er=E_OKDEF; - r_mode(RMODE_RELOC); -/*printf(" : newseg=%d, pc[newseg]=%04x, pc[abs]=%04x, pc[text]=%04x\n", - segment, pc[segment], pc[SEG_ABS], pc[SEG_TEXT]);*/ - } - } - } else - if(n==Kopen) - { - if(showblk) fprintf(stderr, "%s line %d: .(\n", pp_getidat()->fname, pp_getidat()->fline); - b_open(); - er=E_NOLINE; - } else - if(n==Kclose) - { - if(showblk) fprintf(stderr, "%s line %d: .)\n", pp_getidat()->fname, pp_getidat()->fline); - er=b_close(); - if(!er) er=E_NOLINE; - } else - if(n==Kalong) - { - if (!w65816) { - er=E_65816; - } else { - memode=1; - t[0]=Kalong; - *ll=1; - er=E_OKDEF; - } - } else - if(n==Kashort) - { - memode=0; - t[0]=Kashort; - *ll=1; - er=E_OKDEF; - } else - if(n==Kxlong) - { - if (!w65816) { - er=E_65816; - } else { - xmode=1; - t[0]=Kxlong; - *ll=1; - er=E_OKDEF; - } - } else - if(n==Kxshort) - { - xmode=0; - t[0]=Kxshort; - *ll=1; - er=E_OKDEF; - } else - if(n==Kdsb) - { - dsb_len = 1; - if(!(er=a_term(t+1,&bl,&l,pc[segment],&afl,&label,0))) { - er=E_OKDEF; - } - dsb_len = 0; - } else - if(n==Ktext) { - r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = relmode ? SEG_TEXT : SEG_ABS; - t[0]=Ksegment; - t[1]=segment; - *ll=2; - er=E_OKDEF; - } else - if(n==Kdata) { - if(relmode) { - r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_DATA; - t[0]=Ksegment; - t[1]=SEG_DATA; - *ll=2; - er=E_OKDEF; - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kbss) { - if(relmode) { - r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_BSS; - t[0]=Ksegment; - t[1]=SEG_BSS; - *ll=2; - er=E_OKDEF; - } else { - er=E_ILLSEGMENT; - } - } else - if(n==Kzero) { - if(relmode) { - r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode - segment = SEG_ZERO; - t[0]=Ksegment; - t[1]=SEG_ZERO; - *ll=2; - er=E_OKDEF; - } else { - er=E_ILLSEGMENT; - } - } else - if (n==Kassert) { /* ignore this in first pass, just check syntax */ - int x; - i = 1; - - /* XXX: sadly, can't implement unary logical not yet */ - if(!(er=a_term(t+i,&x,&l,pc[segment],&afl,&label,1))) { - i += l; - } - if(t[i] == ',') { /* skip comma */ - i++; - } else { - er = E_SYNTAX; - } - /* get filename. - the tokenizer can either see it as a multichar string ... */ - if (!er) { - int k; - - if(t[i]=='\"') { - i++; - k=t[i]+i+1; - i++; - while(i 255) - er = E_NOMEM; /* buffer overflow */ + if ((segment == SEG_ABS) && (er == E_SYNTAX && l == 0)) { + t[0] = Kreloc; + i = 1; + wval(i, pc[SEG_TEXT], 0); + t[i++] = T_END; + *ll = 7; + er = E_OKDEF; + r_mode(RMODE_RELOC); + /*printf(" : newseg=%d, pc[newseg]=%04x, pc[abs]=%04x, pc[text]=%04x\n", + segment, pc[segment], pc[SEG_ABS], pc[SEG_TEXT]);*/ + } } - binfnam[j] = '\0'; - /* or as a 'char' if it's a single character ("word" would - have been caught by the above) */ - } else - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { - binfnam[0] = v; - binfnam[1] = '\0'; - i += l; - } - } + } else if (n == Kopen) { + if (showblk) + fprintf(stderr, "%s line %d: .(\n", pp_getidat()->fname, + pp_getidat()->fline); + b_open(); + er = E_NOLINE; + } else if (n == Kclose) { + if (showblk) + fprintf(stderr, "%s line %d: .)\n", pp_getidat()->fname, + pp_getidat()->fline); + er = b_close(); + if (!er) + er = E_NOLINE; + } else if (n == Kalong) { + if (!w65816) { + er = E_65816; + } else { + memode = 1; + t[0] = Kalong; + *ll = 1; + er = E_OKDEF; + } + } else if (n == Kashort) { + memode = 0; + t[0] = Kashort; + *ll = 1; + er = E_OKDEF; + } else if (n == Kxlong) { + if (!w65816) { + er = E_65816; + } else { + xmode = 1; + t[0] = Kxlong; + *ll = 1; + er = E_OKDEF; + } + } else if (n == Kxshort) { + xmode = 0; + t[0] = Kxshort; + *ll = 1; + er = E_OKDEF; + } else if (n == Kdsb) { + dsb_len = 1; + if (!(er = a_term(t + 1, &bl, &l, pc[segment], &afl, &label, 0))) { + er = E_OKDEF; + } + dsb_len = 0; + } else if (n == Ktext) { + r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode + segment = relmode ? SEG_TEXT : SEG_ABS; + t[0] = Ksegment; + t[1] = segment; + *ll = 2; + er = E_OKDEF; + } else if (n == Kdata) { + if (relmode) { + r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode + segment = SEG_DATA; + t[0] = Ksegment; + t[1] = SEG_DATA; + *ll = 2; + er = E_OKDEF; + } else { + er = E_ILLSEGMENT; + } + } else if (n == Kbss) { + if (relmode) { + r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode + segment = SEG_BSS; + t[0] = Ksegment; + t[1] = SEG_BSS; + *ll = 2; + er = E_OKDEF; + } else { + er = E_ILLSEGMENT; + } + } else if (n == Kzero) { + if (relmode) { + r_mode(RMODE_RELOC); // use of segments restores previous segment / reloc mode + segment = SEG_ZERO; + t[0] = Ksegment; + t[1] = SEG_ZERO; + *ll = 2; + er = E_OKDEF; + } else { + er = E_ILLSEGMENT; + } + } else if (n == Kassert) { /* ignore this in first pass, just check syntax */ + int x; + i = 1; - /* three arguments only please */ - if (!er && t[i] != T_END && t[i] != T_COMMENT) { - er = E_SYNTAX; - } + /* XXX: sadly, can't implement unary logical not yet */ + if (!(er = a_term(t + i, &x, &l, pc[segment], &afl, &label, 1))) { + i += l; + } + if (t[i] == ',') { /* skip comma */ + i++; + } else { + er = E_SYNTAX; + } + /* get filename. + the tokenizer can either see it as a multichar string ... */ + if (!er) { + int k; - if (!er) { - FILE *foo; + if (t[i] == '\"') { + i++; + k = t[i] + i + 1; + i++; + while (i < k && !er) { + i++; + } + /* or as a 'char' if it's a single character ("word" would + have been caught by the above) */ + } else if (!(er = a_term(t + i, &x, &l, pc[segment], &afl, + &label, 1))) { + i += l; + } + } + + /* two arguments only please */ + if (!er && t[i] != T_END && t[i] != T_COMMENT) { + er = E_SYNTAX; + } + if (!er) { + /* pass parameters back to xa.c */ + *ll = i + 1; + bl = 0; /* zero length */ + er = E_OKDEF; /* defer to pass 2 */ + } + } else if (n == Kbin) { + int j; + int l; + + /* this first pass just calculates a prospective length + for pass 2. */ + char binfnam[255]; + int offset; + int length; + + i = 1; + j = 0; + + /* get offset */ + if (!(er = a_term(t + i, &offset, &l, pc[segment], &afl, &label, 1))) { + i += l; + } + if (offset < 0) + er = E_ILLQUANT; + if (t[i] == ',') { /* skip comma */ + i++; + } else { + er = E_SYNTAX; + } + + /* get length */ + if (!er + && !(er = a_term(t + i, &length, &l, pc[segment], &afl, + &label, 1))) { + i += l; + } + if (length < 0) + er = E_ILLQUANT; + if (t[i] == ',') { /* skip comma */ + i++; + } else { + er = E_SYNTAX; + } + + /* get filename. + the tokenizer can either see it as a multichar string ... */ + if (!er) { + int k; + + //fstart = i; + if (t[i] == '\"') { + i++; + k = t[i] + i + 1; + i++; + while (i < k && !er) { + binfnam[j++] = t[i++]; + if (j > 255) + er = E_NOMEM; /* buffer overflow */ + } + binfnam[j] = '\0'; + /* or as a 'char' if it's a single character ("word" would + have been caught by the above) */ + } else if (!(er = a_term(t + i, &v, &l, pc[segment], &afl, + &label, 1))) { + binfnam[0] = v; + binfnam[1] = '\0'; + i += l; + } + } + + /* three arguments only please */ + if (!er && t[i] != T_END && t[i] != T_COMMENT) { + er = E_SYNTAX; + } + + if (!er) { + FILE *foo; #ifdef DEBUG_AM fprintf(stderr, "binclude1 offset = %i len = %i filename = %s endchar = %i\n", offset, length, binfnam, i); #endif - if (!(foo = fopen(binfnam, "rb"))) { - er = E_FNF; - } else { - fseek(foo, 0, SEEK_END); - if ((length+offset) > ftell(foo)) { - er = E_OUTOFDATA; + if (!(foo = fopen(binfnam, "rb"))) { + er = E_FNF; } else { - length = (length) ? length : - (ftell(foo)-offset); + fseek(foo, 0, SEEK_END); + if ((length + offset) > ftell(foo)) { + er = E_OUTOFDATA; + } else { + length = (length) ? length : (ftell(foo) - offset); + } + fclose(foo); } - fclose(foo); - } - if (!er) { - if (length > 65535 && !w65816) { - errout(W_OVER64K); - } else if (length > 16777215) { - errout(W_OVER16M); + if (!er) { + if (length > 65535 && !w65816) { + errout(W_OVER64K); + } else if (length > 16777215) { + errout(W_OVER16M); + } + /* pass parameters back to xa.c */ + *ll = i + 1; + /* + bl=length+2; + */ + bl = length; + er = E_OKDEF; /* defer to pass 2 */ } - /* pass parameters back to xa.c */ - *ll=i+1; -/* - bl=length+2; -*/ - bl=length; - er = E_OKDEF; /* defer to pass 2 */ } - } - } else - if(n==Kalign) { - int tmp; - if(segment!=SEG_ABS) { - if(!(er=a_term(t+1,&tmp,&l,pc[segment],&afl,&label,0))) { - if(tmp == 1 || tmp == 2 || tmp == 4 || tmp == 256) { - set_align(tmp); - if(pc[segment] & (tmp-1)) { /* not aligned */ - int tmp2; - t[0]=Kdsb; - i=1; - bl=tmp=(tmp - (pc[segment] & (tmp-1))) & (tmp-1); - wval(i,tmp, 0); // 5 byte - t[i++]=','; - tmp2= 0xea; - wval(i,tmp2, 0); /* nop opcode, another 5 byte */ - t[i++]=T_END; - *ll=wval_len * 2 + 3; //13; //9; - er=E_OKDEF; - } else { - *ll=0; /* ignore if aligned right */ - } - } else { - er=E_ILLALIGN; - } - } - } else { - er=E_ILLSEGMENT; - } - } else - /* optimization okay on pass 1: use 0 for fl */ + } else if (n == Kalign) { + int tmp; + if (segment != SEG_ABS) { + if (!(er = a_term(t + 1, &tmp, &l, pc[segment], &afl, &label, 0))) { + if (tmp == 1 || tmp == 2 || tmp == 4 || tmp == 256) { + set_align(tmp); + if (pc[segment] & (tmp - 1)) { /* not aligned */ + int tmp2; + t[0] = Kdsb; + i = 1; + bl = tmp = (tmp - (pc[segment] & (tmp - 1))) + & (tmp - 1); + wval(i, tmp, 0); // 5 byte + t[i++] = ','; + tmp2 = 0xea; + wval(i, tmp2, 0); /* nop opcode, another 5 byte */ + t[i++] = T_END; + *ll = wval_len * 2 + 3; //13; //9; + er = E_OKDEF; + } else { + *ll = 0; /* ignore if aligned right */ + } + } else { + er = E_ILLALIGN; + } + } + } else { + er = E_ILLSEGMENT; + } + } else + /* optimization okay on pass 1: use 0 for fl */ { #ifdef DEBUG_AM fprintf(stderr, "E_OK ... t_p2 xat.c %i %i\n", t[0], *ll); #endif - /* this actually calls pass2 on the current tokenization stream, - * but without including the Klisting token listing */ - er=t_p2(t,ll,(0 | byte), al); + /* this actually calls pass2 on the current tokenization stream, + * but without including the Klisting token listing */ + er = t_p2(t, ll, (0 | byte), al); #ifdef DEBUG_AM fprintf(stderr, "... --> er=%d\n", er); #endif - } - - } else - if(er==E_NODEF) - { + } - /* - * no label was found from t_conv! - * try to figure out most likely length - * - */ + } else if (er == E_NODEF) { + + /* + * no label was found from t_conv! + * try to figure out most likely length + * + */ #ifdef DEBUG_AM fprintf(stderr, "E_NODEF pass1 xat.c\n"); #endif - er = E_OK; /* stuff error */ - n=t[0]; /* look at first token */ + er = E_OK; /* stuff error */ + n = t[0]; /* look at first token */ - /* mnemonic dispatch -- abbreviated form in t_p2, but changed here - to not do anything other than 24-bit optimization since we - don't know the value of the label */ + /* mnemonic dispatch -- abbreviated form in t_p2, but changed here + to not do anything other than 24-bit optimization since we + don't know the value of the label */ /* choose addressing mode; add commas found */ - if(n>=0 && n<=Lastbef && n != Kmvn && n != Kmvp) /* not for mvn/p */ - { - int inp = 1; /* input pointer */ + if (n >= 0 && n <= Lastbef && n != Kmvn && n != Kmvp) /* not for mvn/p */ + { + int inp = 1; /* input pointer */ - if(t[inp]==T_END || t[inp]==T_COMMENT) - { - sy=0; /* implied */ - inp++; - } else - if(t[inp]=='#') - { - sy=1+nk; /* immediate */ - inp++; - } else - if(t[inp]=='(') - { - sy=7+nk; /* computed */ - inp++; - } else { - sy=4+nk; /* absolute or zero page */ - } + if (t[inp] == T_END || t[inp] == T_COMMENT) { + sy = 0; /* implied */ + inp++; + } else if (t[inp] == '#') { + sy = 1 + nk; /* immediate */ + inp++; + } else if (t[inp] == '(') { + sy = 7 + nk; /* computed */ + inp++; + } else { + sy = 4 + nk; /* absolute or zero page */ + } - /* this actually finds the cast for all addressing modes, - but t_conv() only puts it there for immediate (#) or absolute/ - absolute indexed addressing modes */ - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; + /* this actually finds the cast for all addressing modes, + but t_conv() only puts it there for immediate (#) or absolute/ + absolute indexed addressing modes */ + if (t[inp] == T_CAST) { + inp++; + cast = t[inp]; + inp++; #ifdef DEBUG_CAST printf("Found cast to: %c\n", cast); #endif - } - - /* length counter set to maximum length + 1 */ - if (w65816 || (t[l-1]=='@' || t[l-1] == '!')) { - /* for 65816 allow addressing modes up to 4 byte overall length */ - bl=Maxbyt+1; - } else { - /* for other modes only check for addressing modes up to 3 byte overall length */ - bl=Maxbyt; - } - - /* find best fit for length of this operand */ - while(--bl) - { - - /* look at syntax table (at) using syntax (sy) as index. - is there an addressing mode for an operand - of this length? am = addressing mode */ - - if((am=at[sy][bl-1])>=0) - { - if(am>Admodes-1) /* no, it's -1, syntax error */ - { - er=E_SYNTAX; - break; - } - if(ct[n][am]>=0) /* yes, valid token *and* mode, - so we're done */ - break; - - /* no valid mode for this token, see if it's something - ambiguous; if so, try to interpret in that - context. */ - for(v=0;v=0) - break; - if(v=0 && am>16) /* <<< NOTE! */ - if(ct[n][opt[am]]>=0) - am=opt[am]; - } - /* if ` is declared, force further optimization */ - if (cast=='`') { - if (opt[am]<0 || ct[n][opt[am]]<0) - errout(E_ADRESS); - am=opt[am]; - } - /* if ! is declared, force to 16-bit quantity */ - if (cast=='!' && am>16 && opt[am]>=0 && bl) { - am=opt[am]; - } - - /* couldn't match anything for this opcode */ - if(!bl) - er=E_SYNTAX; - else { - /* ok, get length of instruction */ - bl=le[am]; - /* and add one for 65816 special instruction modes */ - if( ((ct[n][am]&0x400) && memode) || - ((ct[n][am]&0x800) && xmode)) { - bl++; } - } + /* length counter set to maximum length + 1 */ + if (w65816 || (t[l - 1] == '@' || t[l - 1] == '!')) { + /* for 65816 allow addressing modes up to 4 byte overall length */ + bl = Maxbyt + 1; + } else { + /* for other modes only check for addressing modes up to 3 byte overall length */ + bl = Maxbyt; + } - if (er == E_NODEF) - er = E_OK; + /* find best fit for length of this operand */ + while (--bl) { - /* .byt, .asc, .word, .dsb, .fopt pseudo-op dispatch */ + /* look at syntax table (at) using syntax (sy) as index. + is there an addressing mode for an operand + of this length? am = addressing mode */ - } else - if(n==Kimportzp) { - int i; - *ll=0; /* no output */ - bl = 0; /* no output length */ - /* import labels; next follow a comma-separated list of labels that are - imported. Tokenizer has already created label entries, we only need to - set the flags appropriately */ - i=1; -/*printf("Kimport: t[i]=%d\n",t[i]);*/ - while(t[i]==T_LABEL) { - int n = (t[i+1] & 255) | (t[i+2] << 8); /* label number */ -/*printf("lg_import: %d\n",n);*/ - lg_importzp(n); - i+=3; - while (t[i]==' ') i++; - if (t[i]!=',') break; - i++; - while (t[i]==' ') i++; - } - er=E_NOLINE; - } else - if(n==Kimport) { - int i; - *ll=0; /* no output */ - bl = 0; /* no output length */ - /* import labels; next follow a comma-separated list of labels that are - imported. Tokenizer has already created label entries, we only need to - set the flags appropriately */ - i=1; -/*printf("Kimport: t[i]=%d\n",t[i]);*/ - while(t[i]==T_LABEL) { - int n = (t[i+1] & 255) | (t[i+2] << 8); /* label number */ -/*printf("lg_import: %d\n",n);*/ - lg_import(n); - i+=3; - while (t[i]==' ') i++; - if (t[i]!=',') break; - i++; - while (t[i]==' ') i++; - } - er=E_NOLINE; - } else - if(n==Kmvn || n==Kmvp) - { - bl=3; - if (!w65816) er = E_65816; - } else - if(n==Kbyt || n==Kasc || n==Kaasc) - { + if ((am = at[sy][bl - 1]) >= 0) { + if (am > Admodes - 1) /* no, it's -1, syntax error */ + { + er = E_SYNTAX; + break; + } + if (ct[n][am] >= 0) /* yes, valid token *and* mode, + so we're done */ + break; + + /* no valid mode for this token, see if it's something + ambiguous; if so, try to interpret in that + context. */ + for (v = 0; v < AnzAlt; v++) + if (xt[v][0] == am && ct[n][xt[v][1]] >= 0) + break; + if (v < AnzAlt) /* got a match for another context */ + { + am = xt[v][1]; + break; + } + } + } + + /* optimize operand length for 24-bit quantities */ + /* look at cast byte from t_conv */ + + if (cast != '@' && cast != '!') { + if (bl && !er && opt[am] >= 0 && am > 16) /* <<< NOTE! */ + if (ct[n][opt[am]] >= 0) + am = opt[am]; + } + /* if ` is declared, force further optimization */ + if (cast == '`') { + if (opt[am] < 0 || ct[n][opt[am]] < 0) + errout(E_ADRESS); + am = opt[am]; + } + /* if ! is declared, force to 16-bit quantity */ + if (cast == '!' && am > 16 && opt[am] >= 0 && bl) { + am = opt[am]; + } + + /* couldn't match anything for this opcode */ + if (!bl) + er = E_SYNTAX; + else { + /* ok, get length of instruction */ + bl = le[am]; + /* and add one for 65816 special instruction modes */ + if (((ct[n][am] & 0x400) && memode) + || ((ct[n][am] & 0x800) && xmode)) { + bl++; + } + } + + if (er == E_NODEF) + er = E_OK; + + /* .byt, .asc, .word, .dsb, .fopt pseudo-op dispatch */ + + } else if (n == Kimportzp) { + int i; + *ll = 0; /* no output */ + bl = 0; /* no output length */ + /* import labels; next follow a comma-separated list of labels that are + imported. Tokenizer has already created label entries, we only need to + set the flags appropriately */ + i = 1; + /*printf("Kimport: t[i]=%d\n",t[i]);*/ + while (t[i] == T_LABEL) { + int n = (t[i + 1] & 255) | (t[i + 2] << 8); /* label number */ + /*printf("lg_import: %d\n",n);*/ + lg_importzp(n); + i += 3; + while (t[i] == ' ') + i++; + if (t[i] != ',') + break; + i++; + while (t[i] == ' ') + i++; + } + er = E_NOLINE; + } else if (n == Kimport) { + int i; + *ll = 0; /* no output */ + bl = 0; /* no output length */ + /* import labels; next follow a comma-separated list of labels that are + imported. Tokenizer has already created label entries, we only need to + set the flags appropriately */ + i = 1; + /*printf("Kimport: t[i]=%d\n",t[i]);*/ + while (t[i] == T_LABEL) { + int n = (t[i + 1] & 255) | (t[i + 2] << 8); /* label number */ + /*printf("lg_import: %d\n",n);*/ + lg_import(n); + i += 3; + while (t[i] == ' ') + i++; + if (t[i] != ',') + break; + i++; + while (t[i] == ' ') + i++; + } + er = E_NOLINE; + } else if (n == Kmvn || n == Kmvp) { + bl = 3; + if (!w65816) + er = E_65816; + } else if (n == Kbyt || n == Kasc || n == Kaasc) { #ifdef DEBUG_AM fprintf(stderr, "byt pass 1 %i\n", nk+1-na1+na2); #endif - bl=nk+1-na1+na2; - } else - if(n==Kword) - { - bl=2*nk+2; - } else - if(n==Kdsb) - { - er=a_term(t+1,&bl,&l,pc[segment],&afl,&label,0); - } else - if(n==Kfopt) - { - set_fopt(l-1,t+1, nk+1-na1+na2); - *ll = 0; - } else - if(n==T_OP) - { - er=E_OKDEF; - } else - er=E_NODEF; - - if(!er) - er=E_OKDEF; + bl = nk + 1 - na1 + na2; + } else if (n == Kword) { + bl = 2 * nk + 2; + } else if (n == Kdsb) { + er = a_term(t + 1, &bl, &l, pc[segment], &afl, &label, 0); + } else if (n == Kfopt) { + set_fopt(l - 1, t + 1, nk + 1 - na1 + na2); + *ll = 0; + } else if (n == T_OP) { + er = E_OKDEF; + } else + er = E_NODEF; + + if (!er) + er = E_OKDEF; #ifdef DEBUG_AM fprintf(stderr, "guessing instruction length is %d\n", bl); #endif - } - if(er==E_NOLINE) - { - er=E_OK; - *ll=0; - } + } + if (er == E_NOLINE) { + er = E_OK; + *ll = 0; + } - *al += bl; - pc[segment]+=bl; - if(segment==SEG_TEXT) pc[SEG_ABS]+=bl; - if(segment==SEG_ABS) pc[SEG_TEXT]+=bl; + *al += bl; + pc[segment] += bl; + if (segment == SEG_TEXT) + pc[SEG_ABS] += bl; + if (segment == SEG_ABS) + pc[SEG_TEXT] += bl; - /* adjust length by token listing buffer length */ + /* adjust length by token listing buffer length */ #ifdef DEBUG_CONV printf("converted: (er=%d, t=%p, ll=%d, tlen=%d):",er, t, *ll, tlen); for(i=0;i<*ll;i++) @@ -1102,8 +1065,8 @@ fprintf(stderr, "guessing instruction length is %d\n", bl); printf("adjusted len=%d\n", *ll+tlen); #endif - *ll = *ll + tlen; - return(er); + *ll = *ll + tlen; + return (er); } /*********************************************************************************************/ @@ -1131,12 +1094,12 @@ fprintf(stderr, "guessing instruction length is %d\n", bl); * into the file; note that for .dsb and .bin, this does NOT match * the length in the internal data structures! */ -int t_p2_l(signed char *t, int *ll, int *al) -{ +int t_p2_l(signed char *t, int *ll, int *al) { int er = E_OK; int l = *ll; - if (l < 0) l = -l; + if (l < 0) + l = -l; #if 0 { @@ -1147,43 +1110,42 @@ int t_p2_l(signed char *t, int *ll, int *al) } #endif - if (t[0] == T_LISTING) { - int tlen; - tlen=((t[2]&255)<<8) | (t[1]&255); - if (*ll<0) { - *ll=(*ll) + tlen; - } else { - *ll=(*ll) - tlen; - } + int tlen; + tlen = ((t[2] & 255) << 8) | (t[1] & 255); + if (*ll < 0) { + *ll = (*ll) + tlen; + } else { + *ll = (*ll) - tlen; + } - if (tlen > l) - { - int i; + if (tlen > l) { + int i; - // that is corrupt data and should not happen - list_flush(); - printf("corrupt: t_p2_l (l=%d, tlen=%d, ll=%d, t=%p):", l, tlen, *ll, t); - for(i=0;i0 when E_OKDEF */ + { + *ll = -*ll; + bl = *ll; + er = E_OK; - er=E_OK; - bl=0; - if(*ll<0) /* <0 when E_OK, >0 when E_OKDEF */ - { - *ll=-*ll; - bl=*ll; - er=E_OK; - - } else - { - n=t[0]; - if(n==T_OP) - { - n=cval(t+1); - er=a_term(t+4,&v,&l,pc[segment],&nafl,&label,0); + } else { + n = t[0]; + if (n == T_OP) { + n = cval(t + 1); + er = a_term(t + 4, &v, &l, pc[segment], &nafl, &label, 0); - if(!er) - { - if(t[3]=='=') - { - v2=v; - } else { - if( (!(er=l_get(n,&v2, &afl))) - && ((afl & A_FMASK)!=(SEG_UNDEF<<8)) - && ((afl & A_FMASK)!=(SEG_UNDEFZP<<8)) ) - { - if(t[3]=='+') - { - if(afl && nafl) { errout(E_WPOINTER); nafl=0; } - nafl = afl; - v2+=v; - } else - if(t[3]=='-') - { - if( (((nafl & A_FMASK)>>8) != afl) - || ((nafl & A_MASK)==A_HIGH) ) { - errout(E_WPOINTER); - nafl=0; - } else { - nafl = afl; - } - v2-=v; - } else - if(t[3]=='*') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - v2*=v; - } else - if(t[3]=='/') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - if(v) - v2/=v; - else - er=E_DIV; - } else - if(t[3]=='|') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - v2=v|v2; - } else - if(t[3]=='&') - { - if(afl || nafl) { errout(E_WPOINTER); nafl=0; } - v2=v2&v; - } - } - } - l_set(n,v2,nafl>>8); + if (!er) { + if (t[3] == '=') { + v2 = v; + } else { + if ((!(er = l_get(n, &v2, &afl))) + && ((afl & A_FMASK) != (SEG_UNDEF << 8)) + && ((afl & A_FMASK) != (SEG_UNDEFZP << 8))) { + if (t[3] == '+') { + if (afl && nafl) { + errout(E_WPOINTER); + nafl = 0; + } + nafl = afl; + v2 += v; + } else if (t[3] == '-') { + if ((((nafl & A_FMASK) >> 8) != afl) + || ((nafl & A_MASK) == A_HIGH)) { + errout(E_WPOINTER); + nafl = 0; + } else { + nafl = afl; + } + v2 -= v; + } else if (t[3] == '*') { + if (afl || nafl) { + errout(E_WPOINTER); + nafl = 0; + } + v2 *= v; + } else if (t[3] == '/') { + if (afl || nafl) { + errout(E_WPOINTER); + nafl = 0; + } + if (v) + v2 /= v; + else + er = E_DIV; + } else if (t[3] == '|') { + if (afl || nafl) { + errout(E_WPOINTER); + nafl = 0; + } + v2 = v | v2; + } else if (t[3] == '&') { + if (afl || nafl) { + errout(E_WPOINTER); + nafl = 0; + } + v2 = v2 & v; + } + } + } + l_set(n, v2, nafl >> 8); - *ll=0; - if(!er) - er=E_NOLINE; - } - } else - if(n==Kword) - { - i=1; - j=0; - while(!er && t[i]!=T_END && t[i] != T_COMMENT) - { - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) - { -/*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", - afl,pc[segment],v); */ - if(afl) u_set(pc[segment]+j, afl, label, 2); - t[j++]=v&255; - t[j++]=(v>>8)&255; + *ll = 0; + if (!er) + er = E_NOLINE; + } + } else if (n == Kword) { + i = 1; + j = 0; + while (!er && t[i] != T_END && t[i] != T_COMMENT) { + if (!(er = a_term(t + i, &v, &l, pc[segment], &afl, &label, 1))) { + /*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", + afl,pc[segment],v); */ + if (afl) + u_set(pc[segment] + j, afl, label, 2); + t[j++] = v & 255; + t[j++] = (v >> 8) & 255; - i+=l; - if(t[i]!=T_END && t[i] != T_COMMENT && t[i]!=',') - er=E_SYNTAX; - else - if(t[i]==',') - i++; + i += l; + if (t[i] != T_END && t[i] != T_COMMENT && t[i] != ',') + er = E_SYNTAX; + else if (t[i] == ',') + i++; - } - } - *ll=j; - bl=j; - } else - if (n == Kassert) - { - int result = 0; - int c; - i = 1; + } + } + *ll = j; + bl = j; + } else if (n == Kassert) { + int result = 0; + int c; + i = 1; - /* this time, actually check something */ - if(!(er=a_term(t+i,&result,&l,pc[segment],&afl,&label,1))) { - i += l; - } - if(t[i] == ',') { /* skip comma */ - i++; - } else { - er = E_SYNTAX; - } - /* get error string. - the tokenizer can either see it as a multichar string ... */ - if (!er) { - int k; - - if (!result) - fprintf(stderr, "Assertion failed: "); - if(t[i]=='\"') { - i++; - k=t[i]+i+1; - i++; - while(i 255) - er = E_NOMEM; /* buffer overflow */ + if (!result) + fprintf(stderr, "Assertion failed: "); + if (t[i] == '\"') { + i++; + k = t[i] + i + 1; + i++; + while (i < k && !er) { + if (!result) + fprintf(stderr, "%c", t[i]); + i++; + } + /* or as a 'char' if it's a single character ("word" would + have been caught by the above) */ + } else if (!(er = a_term(t + i, &c, &l, pc[segment], &afl, + &label, 1))) { + if (!result) + fprintf(stderr, "Assertion failed: %c", c); + i += l; + } } - binfnam[j] = '\0'; - flen = j; - /* or as a 'char' if it's a single character ("word" would - have been caught by the above) */ - } else - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { - binfnam[0] = v; - binfnam[1] = '\0'; - i += l; - flen = 1; - } - } - /* three arguments only please */ - if (!er && t[i] != T_END && t[i] != T_COMMENT) { - er = E_SYNTAX; - } + /* two arguments only please */ + if (!er && !result && t[i] != T_END && t[i] != T_COMMENT) { + er = E_SYNTAX; + } + if (!er && !result) { + fprintf(stderr, "\n"); + return E_AERROR; /* assertion failed, fail now */ + } + *ll = 0; + bl = 0; + } else if (n == Kbin) { + int j; + int l; - if (!er) { - FILE *foo; + /* figure out our parameters again. repeat most of + the error checking since we might not be over + the total number of bogosities */ + char binfnam[255]; + int offset; + int length; + int fstart; + int flen; + + i = 1; + j = 0; + flen = 0; + + /* get offset */ + if (!(er = a_term(t + i, &offset, &l, pc[segment], &afl, &label, 1))) { + i += l; + } + if (offset < 0) + er = E_ILLQUANT; + if (t[i] == ',') { /* skip comma */ + i++; + } else { + er = E_SYNTAX; + } + + /* get length */ + if (!er + && !(er = a_term(t + i, &length, &l, pc[segment], &afl, + &label, 1))) { + i += l; + } + if (length < 0) + er = E_ILLQUANT; + if (t[i] == ',') { /* skip comma */ + i++; + } else { + er = E_SYNTAX; + } + + /* get filename. + the tokenizer can either see it as a multichar string ... */ + if (!er) { + int k; + + fstart = i; + if (t[i] == '\"') { + i++; + k = t[i] + i + 1; + i++; + while (i < k && !er) { + binfnam[j++] = t[i++]; + if (j > 255) + er = E_NOMEM; /* buffer overflow */ + } + binfnam[j] = '\0'; + flen = j; + /* or as a 'char' if it's a single character ("word" would + have been caught by the above) */ + } else if (!(er = a_term(t + i, &v, &l, pc[segment], &afl, + &label, 1))) { + binfnam[0] = v; + binfnam[1] = '\0'; + i += l; + flen = 1; + } + } + + /* three arguments only please */ + if (!er && t[i] != T_END && t[i] != T_COMMENT) { + er = E_SYNTAX; + } + + if (!er) { + FILE *foo; #ifdef DEBUG_AM fprintf(stderr, "binclude2 offset = %i len = %i filename = %s endchar = %i\n", offset, length, binfnam, i); #endif - if (!(foo = fopen(binfnam, "rb"))) { - er = E_FNF; - } else { - fseek(foo, 0, SEEK_END); - if ((length+offset) > ftell(foo)) { - er = E_OUTOFDATA; + if (!(foo = fopen(binfnam, "rb"))) { + er = E_FNF; } else { - length = (length) ? length : - (ftell(foo)-offset); + fseek(foo, 0, SEEK_END); + if ((length + offset) > ftell(foo)) { + er = E_OUTOFDATA; + } else { + length = (length) ? length : (ftell(foo) - offset); + } + fclose(foo); } - fclose(foo); - } - if (!er) { - if (length > 65535 && !w65816) { - errout(W_OVER64K); - } else if (length > 16777215) { - errout(W_OVER16M); + if (!er) { + if (length > 65535 && !w65816) { + errout(W_OVER64K); + } else if (length > 16777215) { + errout(W_OVER16M); + } + /* pass parameters back to xa.c */ + *ll = length; + /* + bl=length+2; + */ + bl = length; + t[0] = offset & 255; + t[1] = (offset >> 8) & 255; + t[2] = (offset >> 16) & 255; + /* God help us if the index is > 65535 */ + t[3] = fstart & 255; + t[4] = (fstart >> 8) & 255; + t[5] = flen; /* to massage 'char' types */ + er = E_BIN; } - /* pass parameters back to xa.c */ - *ll=length; -/* - bl=length+2; -*/ - bl=length; - t[0] = offset & 255; - t[1] = (offset >> 8) & 255; - t[2] = (offset >> 16) & 255; - /* God help us if the index is > 65535 */ - t[3] = fstart & 255; - t[4] = (fstart >> 8) & 255; - t[5] = flen; /* to massage 'char' types */ - er = E_BIN; } - } - } else - if (n==Kmvn || n==Kmvp) - { - /* special case these instructions' syntax */ - int wide=0; - i=1; - j=1; - /* write opcode */ - t[0] = ((n == Kmvp) ? 0x44 : 0x54); - while(!er && t[i]!=T_END && t[i]!=T_COMMENT) - { - if (wide) /* oops */ - er = E_SYNTAX; + } else if (n == Kmvn || n == Kmvp) { + /* special case these instructions' syntax */ + int wide = 0; + i = 1; + j = 1; + /* write opcode */ + t[0] = ((n == Kmvp) ? 0x44 : 0x54); + while (!er && t[i] != T_END && t[i] != T_COMMENT) { + if (wide) /* oops */ + er = E_SYNTAX; #ifdef DEBUG_AM fprintf(stderr, "mvn mvp: %i %i %i %i %i\n", t[0], t[i], wide, i, j); #endif - if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) - { -/*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", - afl,pc[segment],v); */ - if(afl) u_set(pc[segment]+j, afl, label, 2); - i+=l; - if (v & 0xff00) - er=E_ILLQUANT; - else - t[j++]=v; + if (!(er = a_term(t + i, &v, &l, pc[segment], &afl, &label, 1))) { + /*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", + afl,pc[segment],v); */ + if (afl) + u_set(pc[segment] + j, afl, label, 2); + i += l; + if (v & 0xff00) + er = E_ILLQUANT; + else + t[j++] = v; + } + if (j > 3) + er = E_SYNTAX; + if (t[i] != T_END && t[i] != T_COMMENT && t[i] != ',') + er = E_SYNTAX; + else if (t[i] == ',') + i++; } - if (j > 3) - er=E_SYNTAX; - if(t[i]!=T_END && t[i]!=T_COMMENT && t[i]!=',') - er=E_SYNTAX; - else - if(t[i]==',') - i++; - } - if (j != 3) er = E_SYNTAX; /* oops */ + if (j != 3) + er = E_SYNTAX; /* oops */ - /* before we leave, swap the bytes. although disassembled as - mv? src,dest it's actually represented as - mv? $ddss -- see - http://6502org.wikidot.com/software-65816-memorymove */ - i = t[2]; - t[2] = t[1]; - t[1] = i; + /* before we leave, swap the bytes. although disassembled as + mv? src,dest it's actually represented as + mv? $ddss -- see + http://6502org.wikidot.com/software-65816-memorymove */ + i = t[2]; + t[2] = t[1]; + t[1] = i; - *ll = j; - bl = j; - if (!w65816) er = E_65816; - } else if(n==Kasc || n==Kbyt || n==Kaasc) { - i=1; - j=0; - while(!er && t[i]!=T_END && t[i] != T_COMMENT) - { - if(t[i]=='\"') - { - i++; - k=t[i]+i+1; - i++; - while(i er=%d, nbytes=%d\n", er, nbytes); - list_setbytes(nbytes); - l = 2; - *ll=0; - bl =0; - } else - if(n==Ksegment) { - segment = t[1]; - *ll=0; - bl =0; - } else - if(n==Kdsb) - { - dsb_len = 1; - if(!(er=a_term(t+1,&j,&i,pc[segment],&afl,&label,0))) - { - if (j<0) - er=E_NEGDSBLEN; - else -/* - if(t[i+1]!=',') - er=E_SYNTAX; - else -*/ -/* - if((segment!=SEG_ABS) && afl) - er=E_ILLPOINTER; - else -*/ - { - dsb_len = 0; + *ll = j; + bl = j; + if (!w65816) + er = E_65816; + } else if (n == Kasc || n == Kbyt || n == Kaasc) { + i = 1; + j = 0; + while (!er && t[i] != T_END && t[i] != T_COMMENT) { + if (t[i] == '\"') { + i++; + k = t[i] + i + 1; + i++; + while (i < k) + t[j++] = t[i++]; + } else { + if (!(er = a_term(t + i, &v, &l, pc[segment], &afl, &label, + 1))) { + /*if(afl) printf("relocation 2 %04x at pc=$%04x, value now =$%04x\n",afl,pc[segment]+j,v); */ + if (afl) + u_set(pc[segment] + j, afl, label, 1); + if (v & 0xff00) + er = E_OVERFLOW; + else { + t[j++] = v; + i += l; + } + } + } + if (t[i] != T_END && t[i] != T_COMMENT && t[i] != ',') + er = E_SYNTAX; + else if (t[i] == ',') + i++; + } + *ll = j; + bl = j; + } else if (n == Kalong) { + memode = 1; + *ll = 0; + } else if (n == Kashort) { + memode = 0; + *ll = 0; + } else if (n == Kxlong) { + xmode = 1; + *ll = 0; + } else if (n == Kxshort) { + xmode = 0; + *ll = 0; + } else if (n == Kpcdef) { + int npc; + er = a_term(t + 1, &npc, &l, pc[segment], &afl, &label, 0); + bl = 0; + *ll = 0; + if (segment == SEG_TEXT) { + r_mode(RMODE_ABS); + } + pc[segment] = npc; + } else if (n == Kreloc) { + int npc; + er = a_term(t + 1, &npc, &l, pc[segment], &afl, &label, 0); + /*printf("Kreloc: segment=%d, pc[seg]=%04x\n", segment, pc[segment]);*/ + bl = 0; + *ll = 0; + r_mode(RMODE_RELOC); + pc[segment] = npc; + /*printf("Kreloc: newsegment=%d, pc[seg]=%04x\n", segment, pc[segment]);*/ + } else if (n == Klistbytes) { + int nbytes = (t[1] & 0xff) + (t[2] << 8); + //printf("Klistbytes --> er=%d, nbytes=%d\n", er, nbytes); + list_setbytes(nbytes); + l = 2; + *ll = 0; + bl = 0; + } else if (n == Ksegment) { + segment = t[1]; + *ll = 0; + bl = 0; + } else if (n == Kdsb) { + dsb_len = 1; + if (!(er = a_term(t + 1, &j, &i, pc[segment], &afl, &label, 0))) { + if (j < 0) + er = E_NEGDSBLEN; + else + /* + if(t[i+1]!=',') + er=E_SYNTAX; + else + */ + /* + if((segment!=SEG_ABS) && afl) + er=E_ILLPOINTER; + else + */ + { + dsb_len = 0; - if(t[i+1]==',') { - er=a_term(t+2+i,&v,&l,pc[segment],&afl,&label,0); - } else { - v=0; - } - if(!er && v>>8) - er=E_OVERFLOW; - t[0]=v&255; - if(!er) - { - *ll=j; - bl=j; + if (t[i + 1] == ',') { + er = a_term(t + 2 + i, &v, &l, pc[segment], &afl, + &label, 0); + } else { + v = 0; + } + if (!er && v >> 8) + er = E_OVERFLOW; + t[0] = v & 255; + if (!er) { + *ll = j; + bl = j; #ifdef DEBUG_AM fprintf(stderr, "Kdsb E_DSB %i\n", j); #endif - er=E_DSB; - } - } - if(!er) - bl=j; - } - dsb_len = 0; - } else - if(n>=0 && n<=Lastbef) - { - int inp = 1; /* input pointer */ - signed char cast = '\0'; /* cast value */ + er = E_DSB; + } + } + if (!er) + bl = j; + } + dsb_len = 0; + } else if (n >= 0 && n <= Lastbef) { + int inp = 1; /* input pointer */ + signed char cast = '\0'; /* cast value */ - c = t[inp]; + c = t[inp]; - if(c=='#') - { - inp++; - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; + if (c == '#') { + inp++; + if (t[inp] == T_CAST) { + inp++; + cast = t[inp]; + inp++; #ifdef DEBUG_CAST printf("Found cast to (2): %c\n", cast); #endif - } - sy=1; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { -/* if(1) printf("a_term returns afl=%04x\n",afl); */ + } + sy = 1; + if (!(er = a_term(t + inp, vv, &l, pc[segment], &afl, &label, 1))) { + /* if(1) printf("a_term returns afl=%04x\n",afl); */ - rlt[0] = afl; - lab[0] = label; - inp+=l; - if(t[inp]!=T_END && t[inp] != T_COMMENT) - { - if(t[inp]!=',') - er=E_SYNTAX; - else - { - inp++; - sy++; - if(!(er=a_term(t+inp,vv+1,&l,pc[segment],&afl,&label,1))) - { - rlt[1] = afl; - lab[1] = label; - inp+=l; - if(t[inp]!=T_END && t[inp] != T_COMMENT) - { - if(t[inp]!=',') - er=E_SYNTAX; - else - { - inp++; - sy++; - if(!(er=a_term(t+inp,vv+2,&l,pc[segment],&afl,&label,1))) - { - rlt[2] = afl; - lab[2] = label; - inp+=l; - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - er=E_SYNTAX; - } - } - } - } - } - } - } - } else - if(c==T_END || c==T_COMMENT) - { - sy=0; - } else - if(c=='(') - { - inp++; - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; + rlt[0] = afl; + lab[0] = label; + inp += l; + if (t[inp] != T_END && t[inp] != T_COMMENT) { + if (t[inp] != ',') + er = E_SYNTAX; + else { + inp++; + sy++; + if (!(er = a_term(t + inp, vv + 1, &l, pc[segment], + &afl, &label, 1))) { + rlt[1] = afl; + lab[1] = label; + inp += l; + if (t[inp] != T_END && t[inp] != T_COMMENT) { + if (t[inp] != ',') + er = E_SYNTAX; + else { + inp++; + sy++; + if (!(er = a_term(t + inp, vv + 2, &l, + pc[segment], &afl, &label, 1))) { + rlt[2] = afl; + lab[2] = label; + inp += l; + if (t[inp] != T_END + && t[inp] != T_COMMENT) + er = E_SYNTAX; + } + } + } + } + } + } + } + } else if (c == T_END || c == T_COMMENT) { + sy = 0; + } else if (c == '(') { + inp++; + if (t[inp] == T_CAST) { + inp++; + cast = t[inp]; + inp++; #ifdef DEBUG_CAST printf("Found cast to (3): %c\n", cast); #endif - } - sy=7; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { - inp += l; - rlt[0] = afl; - lab[0] = label; + } + sy = 7; + if (!(er = a_term(t + inp, vv, &l, pc[segment], &afl, &label, 1))) { + inp += l; + rlt[0] = afl; + lab[0] = label; - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - { - if(t[inp]==',') - { - inp++; - if (tolower(t[inp])=='x') - sy=8; - else - sy=13; + if (t[inp] != T_END && t[inp] != T_COMMENT) { + if (t[inp] == ',') { + inp++; + if (tolower(t[inp]) == 'x') + sy = 8; + else + sy = 13; - } else - if(t[inp]==')') - { - inp++; - if(t[inp]==',') - { + } else if (t[inp] == ')') { + inp++; + if (t[inp] == ',') { + inp++; + if (tolower(t[inp]) == 'y') + sy = 9; + else + er = E_SYNTAX; + } else if (t[inp] != T_END && t[inp] != T_COMMENT) + er = E_SYNTAX; + } + } else + er = E_SYNTAX; + } + } else if (c == '[') { + inp++; + if (t[inp] == T_CAST) { + inp++; + cast = t[inp]; inp++; - if(tolower(t[inp])=='y') - sy=9; - else - er=E_SYNTAX; - } else - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - er=E_SYNTAX; - } - } else - er=E_SYNTAX; - } - } else - if(c=='[') - { - inp++; - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; #ifdef DEBUG_CAST printf("Found cast to (4): %c\n", cast); #endif - } - sy=10; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { - inp += l; - rlt[0] = afl; - lab[0] = label; + } + sy = 10; + if (!(er = a_term(t + inp, vv, &l, pc[segment], &afl, &label, 1))) { + inp += l; + rlt[0] = afl; + lab[0] = label; - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - { - if(t[inp]==']') - { - inp++; - if(t[inp]==',') - { + if (t[inp] != T_END && t[inp] != T_COMMENT) { + if (t[inp] == ']') { + inp++; + if (t[inp] == ',') { + inp++; + if (tolower(t[inp]) == 'y') + sy = 11; + else + er = E_SYNTAX; + } else if (t[inp] != T_END && t[inp] != T_COMMENT) + er = E_SYNTAX; + } + } else + er = E_SYNTAX; + } + } else { + if (t[inp] == T_CAST) { + inp++; + cast = t[inp]; inp++; - if(tolower(t[inp])=='y') - sy=11; - else - er=E_SYNTAX; - } else - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - er=E_SYNTAX; - } - } else - er=E_SYNTAX; - } - } else - { - if (t[inp] == T_CAST) { - inp++; - cast = t[inp]; - inp++; #ifdef DEBUG_CAST printf("Found cast to (5): %c\n", cast); #endif - } - sy=4; - if(!(er=a_term(t+inp,vv,&l,pc[segment],&afl,&label,1))) - { - inp += l; - rlt[0] = afl; - lab[0] = label; - if(t[inp]!=T_END && t[inp]!=T_COMMENT) - { - if(t[inp]==',') - { - inp++; - if(tolower(t[inp])=='y') - sy=6; - else - if(tolower(t[inp])=='s') - sy=12; - else - if(tolower(t[inp])=='x') - sy=5; - else - er=E_SYNTAX; - } else - er=E_SYNTAX; - } - } - } - - /* set bl to maximum overall length +1 as while() below starts with decrementing it */ - if (w65816 || cast=='@' || cast== '!') { - /* for 65816 allow addressing modes up to 4 byte overall length */ - bl=Maxbyt+1; - } else { - /* for other modes only check for addressing modes up to 3 byte overall length */ - bl=Maxbyt; - } - + } + sy = 4; + if (!(er = a_term(t + inp, vv, &l, pc[segment], &afl, &label, 1))) { + inp += l; + rlt[0] = afl; + lab[0] = label; + if (t[inp] != T_END && t[inp] != T_COMMENT) { + if (t[inp] == ',') { + inp++; + if (tolower(t[inp]) == 'y') + sy = 6; + else if (tolower(t[inp]) == 's') + sy = 12; + else if (tolower(t[inp]) == 'x') + sy = 5; + else + er = E_SYNTAX; + } else + er = E_SYNTAX; + } + } + } + + /* set bl to maximum overall length +1 as while() below starts with decrementing it */ + if (w65816 || cast == '@' || cast == '!') { + /* for 65816 allow addressing modes up to 4 byte overall length */ + bl = Maxbyt + 1; + } else { + /* for other modes only check for addressing modes up to 3 byte overall length */ + bl = Maxbyt; + } + #ifdef DEBUG_AM printf("--- trying to find am using: (max+1) bl=%d, sy=%d\n", bl, sy); #endif - while(--bl) - { - if((am=at[sy][bl-1])>=0) - { - if(am>Admodes) - { - er=E_SYNTAX; - break; - } - if(ct[n][am]>=0) - break; + while (--bl) { + if ((am = at[sy][bl - 1]) >= 0) { + if (am > Admodes) { + er = E_SYNTAX; + break; + } + if (ct[n][am] >= 0) + break; - for(v=0;v=0) - break; - if(v= 0) + break; + if (v < AnzAlt) { + am = xt[v][1]; + break; + } + } + } -/* FIXIT1 - fprintf(stderr, "t has: "); - for(v=0;v16 - && !er - && (((vv[0]&0xff8000)==0xff8000) || !(vv[0]&0xff0000)) - && opt[am]>=0) - if(ct[n][opt[am]]>=0) - am=opt[am]; + /* terrible KLUDGE!!!! OH NOES!!!1! + due to the way this is constructed, you must absolutely always specify @ to + get an absolute long or it will absolutely always be optimized down */ + /* now also checks for negative overflow, resp. not-overflow */ + if (bl && am > 16 && !er + && (((vv[0] & 0xff8000) == 0xff8000) + || !(vv[0] & 0xff0000)) && opt[am] >= 0) + if (ct[n][opt[am]] >= 0) + am = opt[am]; #ifdef DEBUG_AM fprintf(stderr, "aftaa1: pc= %d, am = %d and vv[0] = %d, optimize = %d, bitmask = %d, bl = %d\n", pc[segment], am, vv[0], fl, (vv[0]&0xffff00), bl); #endif - if(cast!='!') { - if(bl && !er && !(vv[0]&0xffff00) && opt[am]>=0) { - if(ct[n][opt[am]]>=0) { - if (!fl || cast=='`') { - am=opt[am]; - } else { - errout(W_FORLAB); + if (cast != '!') { + if (bl && !er && !(vv[0] & 0xffff00) && opt[am] >= 0) { + if (ct[n][opt[am]] >= 0) { + if (!fl || cast == '`') { + am = opt[am]; + } else { + errout(W_FORLAB); + } + } + } } - } - } - } #ifdef DEBUG_AM fprintf(stderr, "aftaa2: pc=%d, am=%d and vv[0]=%d, optimize=%d, bitmask=%d, op=%d, bl=%d\n", pc[segment], am, vv[0], fl, (vv[0]&0xffff00), ct[n][opt[am]], bl); #endif - } + } - if(!bl) - er=E_SYNTAX; - else - { - bl=le[am]; - if( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode)) { - bl++; - } - if ((am != 11 && am != 16) && (vv[0] > 255 || vv[0] < -256) && bl == 2) { - er = E_OVERFLOW; - } else - if ((am != 11 && am != 16) && (vv[0] > 65535 || vv[0] < -65536) && (bl == 2 || bl == 3)) { - er = E_OVERFLOW; - } - *ll=bl; - } + if (!bl) + er = E_SYNTAX; + else { + bl = le[am]; + if (((ct[n][am] & 0x400) && memode) + || ((ct[n][am] & 0x800) && xmode)) { + bl++; + } + if ((am != 11 && am != 16) && (vv[0] > 255 || vv[0] < -256) + && bl == 2) { + er = E_OVERFLOW; + } else if ((am != 11 && am != 16) + && (vv[0] > 65535 || vv[0] < -65536) + && (bl == 2 || bl == 3)) { + er = E_OVERFLOW; + } + *ll = bl; + } #ifdef DEBUG_AM fprintf(stderr, "byte length is now %d, am=%d, er=%d\n", bl, am, er); #endif - if(!er) - { - t[0]=ct[n][am]&0x00ff; - if(ct[n][am]&0x0300) - { - if(ct[n][am]&0x100) { - ncmos++; - if(!cmosfl) - er=E_CMOS; - } else { - n65816++; - if(!w65816) { + if (!er) { + t[0] = ct[n][am] & 0x00ff; + if (ct[n][am] & 0x0300) { + if (ct[n][am] & 0x100) { + ncmos++; + if (!cmosfl) + er = E_CMOS; + } else { + n65816++; + if (!w65816) { #ifdef DEBUG_AM fprintf(stderr,"not 65816 n=%d, am=%d\n", n, am); #endif - er=E_65816; - } - } - } - if(am!=0) - { - if((am<8 && !( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode) )) || (am>=19 && am!=23)) - { - if(vv[0]&0xff00) { + er = E_65816; + } + } + } + if (am != 0) { + if ((am < 8 + && !(((ct[n][am] & 0x400) && memode) + || ((ct[n][am] & 0x800) && xmode))) + || (am >= 19 && am != 23)) { + if (vv[0] & 0xff00) { #ifdef DEBUG_AM fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]); #endif - er=E_OVERFLOW; - } - else - t[1]=vv[0]; -/*if(rlt[0]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ - if(rlt[0]) u_set(pc[segment]+1, rlt[0], lab[0], 1); - } else - if(((am<14 || am==23) && am!=11) || am==7) - { - if (vv[0]>0xffff) { + er = E_OVERFLOW; + } else + t[1] = vv[0]; + /*if(rlt[0]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ + if (rlt[0]) + u_set(pc[segment] + 1, rlt[0], lab[0], 1); + } else if (((am < 14 || am == 23) && am != 11) || am == 7) { + if (vv[0] > 0xffff) { #ifdef DEBUG_AM fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]); #endif - er=E_OVERFLOW; - } - else { - t[1]=vv[0]&255; - t[2]=(vv[0]>>8)&255; -/*if(rlt[0]) printf("relocation 2 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ - if(rlt[0]) u_set(pc[segment]+1, rlt[0], lab[0], 2); - } - } else - if(am==11 || am==16) { - /* relative, relative long */ - if((segment!=SEG_ABS) && (!rlt[0])) { - er=E_ILLPOINTER; - } else { -/*printf("am=11, pc=%04x, vv[0]=%04x, segment=%d\n",pc[segment],vv[0], segment);*/ - v=vv[0]-pc[segment]-le[am]; - if(((v&0xff80)!=0xff80) && (v&0xff80) && (am==11)) - er=E_RANGE; - else { - t[1]=v&255; - t[2]=(v>>8)&255; - } - } - } else - if(am==14) { - if(vv[0]&0xfff8 || vv[1]&0xff00) - er=E_RANGE; - else - if((segment!=SEG_ABS) && (rlt[0] || !rlt[2])) { - er=E_ILLPOINTER; - } else { -/*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ - if(rlt[1]) u_set(pc[segment]+1, rlt[1], lab[1], 1); - t[0]=t[0]|(vv[0]<<4); - t[1]=vv[1]; - v=vv[2]-pc[segment]-3; - if((v&0xff80) && ((v&0xff80)!=0xff80)) - er=E_OVERFLOW; - else - t[2]=v; - } - } else - if(am==15) - { -/*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ - if(rlt[1]) u_set(pc[segment]+1, rlt[1], lab[1], 1); - if(vv[0]&0xfff8 || vv[1]&0xff00) - er=E_OVERFLOW; - else - { - t[0]=t[0]|(vv[0]<<4); - t[1]=vv[1]; - } - } else - if(am==17 || am==18) - { - t[1]=vv[0]&255; - t[2]=(vv[0]>>8)&255; - t[3]=(vv[0]>>16)&255; - if(rlt[0]) { - rlt[0]|=A_LONG; - u_set(pc[segment]+1, rlt[0], lab[0], 3); - } + er = E_OVERFLOW; + } else { + t[1] = vv[0] & 255; + t[2] = (vv[0] >> 8) & 255; + /*if(rlt[0]) printf("relocation 2 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ + if (rlt[0]) + u_set(pc[segment] + 1, rlt[0], lab[0], 2); + } + } else if (am == 11 || am == 16) { + /* relative, relative long */ + if ((segment != SEG_ABS) && (!rlt[0])) { + er = E_ILLPOINTER; + } else { + /*printf("am=11, pc=%04x, vv[0]=%04x, segment=%d\n",pc[segment],vv[0], segment);*/ + v = vv[0] - pc[segment] - le[am]; + if (((v & 0xff80) != 0xff80) && (v & 0xff80) + && (am == 11)) + er = E_RANGE; + else { + t[1] = v & 255; + t[2] = (v >> 8) & 255; + } + } + } else if (am == 14) { + if (vv[0] & 0xfff8 || vv[1] & 0xff00) + er = E_RANGE; + else if ((segment != SEG_ABS) && (rlt[0] || !rlt[2])) { + er = E_ILLPOINTER; + } else { + /*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ + if (rlt[1]) + u_set(pc[segment] + 1, rlt[1], lab[1], 1); + t[0] = t[0] | (vv[0] << 4); + t[1] = vv[1]; + v = vv[2] - pc[segment] - 3; + if ((v & 0xff80) && ((v & 0xff80) != 0xff80)) + er = E_OVERFLOW; + else + t[2] = v; + } + } else if (am == 15) { + /*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ + if (rlt[1]) + u_set(pc[segment] + 1, rlt[1], lab[1], 1); + if (vv[0] & 0xfff8 || vv[1] & 0xff00) + er = E_OVERFLOW; + else { + t[0] = t[0] | (vv[0] << 4); + t[1] = vv[1]; + } + } else if (am == 17 || am == 18) { + t[1] = vv[0] & 255; + t[2] = (vv[0] >> 8) & 255; + t[3] = (vv[0] >> 16) & 255; + if (rlt[0]) { + rlt[0] |= A_LONG; + u_set(pc[segment] + 1, rlt[0], lab[0], 3); + } - } else - er=E_SYNTAX; - } - } - - } else - er=E_SYNTAX; - } + } else + er = E_SYNTAX; + } + } + + } else + er = E_SYNTAX; + } #ifdef DEBUG_AM fprintf(stderr, "-- endof P2\n"); #endif - pc[segment]+=bl; - if(segment==SEG_TEXT) pc[SEG_ABS]+=bl; - if(segment==SEG_ABS) pc[SEG_TEXT]+=bl; - *al = bl; - return(er); + pc[segment] += bl; + if (segment == SEG_TEXT) + pc[SEG_ABS] += bl; + if (segment == SEG_ABS) + pc[SEG_TEXT] += bl; + *al = bl; + return (er); } /*********************************************************************************************/ @@ -2084,19 +1971,17 @@ fprintf(stderr, "-- endof P2\n"); * (e.g. for #if or #print). * First tokenizes it, then calculates the value */ -int b_term(char *s, int *v, int *l, int pc) -{ - static signed char t[MAXLINE]; - int er,i,afl, label; +int b_term(char *s, int *v, int *l, int pc) { + static signed char t[MAXLINE]; + int er, i, afl, label; - if(!(er=t_conv((signed char*)s,t,l,pc,&i,&i,&i,1,NULL))) - { - er=a_term(t,v,&i,pc,&afl,&label,0); - - } - return(er); + if (!(er = t_conv((signed char*) s, t, l, pc, &i, &i, &i, 1, NULL))) { + er = a_term(t, v, &i, pc, &afl, &label, 0); + + } + return (er); } - + /*********************************************************************************************/ /* translate a string into a first-pass sequence of tokens; * Take the text from *s (stopping at \0 or ';'), tokenize it @@ -2117,720 +2002,703 @@ int b_term(char *s, int *v, int *l, int pc) * bytep ??? */ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk, - int *na1, int *na2, int af, int *bytep) -{ - static int v,f; - static int operand,o; - int fl,afl; - int p,q,ll,mk,er; - int ud; /* counts undefined labels */ - int n; /* label number to be passed between l_def (definition) and l_set (set the value) */ - int byte; - int uz; /* unused at the moment */ - /*static unsigned char cast;*/ + int *na1, int *na2, int af, int *bytep) { + static int v, f; + static int operand, o; + int fl, afl; + int p, q, ll, mk, er; + int ud; /* counts undefined labels */ + int n; /* label number to be passed between l_def (definition) and l_set (set the value) */ + int byte; + int uz; /* unused at the moment */ + /*static unsigned char cast;*/ -/* ich verstehe deutsch, aber verstehen andere leute nicht; so, werde ich - diese bemerkungen uebersetzen ... cameron */ -/* I understand German, but other folks don't, so I'll translate these - comments ... Cameron */ -/* note that I don't write so good tho' ;) */ + /* ich verstehe deutsch, aber verstehen andere leute nicht; so, werde ich + diese bemerkungen uebersetzen ... cameron */ + /* I understand German, but other folks don't, so I'll translate these + comments ... Cameron */ + /* note that I don't write so good tho' ;) */ - *nk=0; /* comma count */ - *na1=0; /* asc text count */ - *na2=0; /* total bytecount in asc texts */ - ll=0; - er=E_OK; /* error state */ - p=0; - q=0; - ud = uz = byte =0; - mk=0; /* 0 = add'l commas ok */ - fl=0; /* 1 = pass text thru */ - afl=0; /* pointer flag for label */ + *nk = 0; /* comma count */ + *na1 = 0; /* asc text count */ + *na2 = 0; /* total bytecount in asc texts */ + ll = 0; + er = E_OK; /* error state */ + p = 0; + q = 0; + ud = uz = byte = 0; + mk = 0; /* 0 = add'l commas ok */ + fl = 0; /* 1 = pass text thru */ + afl = 0; /* pointer flag for label */ - // skip leading whitespace - while(isspace(s[p])) p++; - - n=T_END; - /*cast='\0';*/ - - if(!af) - { - while(s[p]!='\0' && s[p]!=';') - { - //printf("CONV: %s\n", s); - - if (s[p] == ':') { - // this is a ca65 unnamed label - if ((er = l_def((char*)s+p, &ll, &n, &f))) - break; - l_set(n,pc,segment); /* set as address value */ - t[q++]=T_DEFINE; - t[q++]=n&255; - t[q++]=(n>>8)&255; - n=0; - - p+=ll; - - while(isspace(s[p])) p++; - - // end of line - if (s[p] == 0 || s[p] == ';') { - break; - } - } - - /* is keyword? */ - if(!(er=t_keyword(s+p,&ll,&n))) - break; - - /* valid syntax, but just not a real token? */ - if(er && er!=E_NOKEY) - break; - - // if so, try to understand as label - // it returns the label number in n - if((er=l_def((char*)s+p,&ll,&n,&f))) - break; - - p+=ll; - - while(isspace(s[p])) p++; - - if(s[p]=='=') - { - /*printf("Found = @%s\n",s+p);*/ - t[q++]=T_OP; - t[q++]=n&255; - t[q++]=(n>>8)&255; - t[q++]='='; - p++; - ll=n=0; - break; - } else - if(s[p]==':' && s[p+1]=='=') /* support := label assignments (ca65 compatibility) */ - { - /*printf("Found := @%s\n", s+p);*/ - t[q++]=T_OP; - t[q++]=n&255; - t[q++]=(n>>8)&255; - t[q++]='='; - p+=2; - ll=n=0; - break; - } else - if(f && s[p]!='\0' && s[p+1]=='=') - { - t[q++]=T_OP; - t[q++]=n&255; - t[q++]=(n>>8)&255; - t[q++]=s[p]; - p+=2; - ll=n=0; - break; - } else - if(s[p]==':') /* to support label: ... syntax */ - { - p++; - while(s[p]==' ') p++; - l_set(n,pc,segment); /* set as address value */ - t[q++]=T_DEFINE; - t[q++]=n&255; - t[q++]=(n>>8)&255; - n=0; - - } else { /* label ... syntax */ - l_set(n,pc,segment); /* set as address value */ - t[q++]=T_DEFINE; - t[q++]=n&255; - t[q++]=(n>>8)&255; - n=0; - } - - } - - if(n != Kmvn && n != Kmvp && ((n & 0xff) <=Lastbef)) { - mk=1; /* = only 1 comma ok for normal opcodes */ - } - } - - if(s[p]=='\0' || s[p]==';') - { - er=E_NOLINE; - ll=0; - } else - if(!er) - { - - p+=ll; - if(ll) { - t[q++]= n & 0xff; -/* - if( (n&0xff) == Kmacro) { - t[q++]= (n >> 8) & 0xff; - } -*/ - } - - operand=1; - - // skip whitespace - while(isspace(s[p])) { + // skip leading whitespace + while (isspace(s[p])) p++; - } - if(s[p]=='#') - { - mk=0; - t[q++]=s[p++]; + n = T_END; + /*cast='\0';*/ - // skip following whitespace - while(isspace(s[p])) { - p++; - } - } + if (!af) { + while (s[p] != '\0' && s[p] != ';') { + //printf("CONV: %s\n", s); -/* - * - * operand processing - * byte = length of operand in bytes to be assembled - * - * - */ + if (s[p] == ':') { + // this is a ca65 unnamed label + if ((er = l_def((char*) s + p, &ll, &n, &f))) + break; + l_set(n, pc, segment); /* set as address value */ + t[q++] = T_DEFINE; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + n = 0; - /* this addresses forced high/low/two byte addressing, but only - for the first operand. Further processing is done in a_term() - */ + p += ll; -/* FIXIT2 */ + while (isspace(s[p])) + p++; - while(s[p]!='\0' && s[p]!=';' && !er) - { - if(fl) - { - // pass through text (e.g. for ",y") - t[q++]=s[p++]; + // end of line + if (s[p] == 0 || s[p] == ';') { + break; + } + } - } else - { - if(operand) - { - /* are we forcing the operand into a particular - addressing mode? !, @, ` operators - Note these are not available in ca65, but we only - switch off "@" which are used for cheap local labels*/ - if(s[p]=='!' || (s[p]=='@' && !ca65) || s[p]=='`') - { + /* is keyword? */ + if (!(er = t_keyword(s + p, &ll, &n))) + break; + + /* valid syntax, but just not a real token? */ + if (er && er != E_NOKEY) + break; + + // if so, try to understand as label + // it returns the label number in n + if ((er = l_def((char*) s + p, &ll, &n, &f))) + break; + + p += ll; + + while (isspace(s[p])) + p++; + + if (s[p] == '=') { + /*printf("Found = @%s\n",s+p);*/ + t[q++] = T_OP; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + t[q++] = '='; + p++; + ll = n = 0; + break; + } else if (s[p] == ':' && s[p + 1] == '=') /* support := label assignments (ca65 compatibility) */ + { + /*printf("Found := @%s\n", s+p);*/ + t[q++] = T_OP; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + t[q++] = '='; + p += 2; + ll = n = 0; + break; + } else if (f && s[p] != '\0' && s[p + 1] == '=') { + t[q++] = T_OP; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + t[q++] = s[p]; + p += 2; + ll = n = 0; + break; + } else if (s[p] == ':') /* to support label: ... syntax */ + { + p++; + while (s[p] == ' ') + p++; + l_set(n, pc, segment); /* set as address value */ + t[q++] = T_DEFINE; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + n = 0; + + } else { /* label ... syntax */ + l_set(n, pc, segment); /* set as address value */ + t[q++] = T_DEFINE; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + n = 0; + } + + } + + if (n != Kmvn && n != Kmvp && ((n & 0xff) <= Lastbef)) { + mk = 1; /* = only 1 comma ok for normal opcodes */ + } + } + + if (s[p] == '\0' || s[p] == ';') { + er = E_NOLINE; + ll = 0; + } else if (!er) { + + p += ll; + if (ll) { + t[q++] = n & 0xff; + /* + if( (n&0xff) == Kmacro) { + t[q++]= (n >> 8) & 0xff; + } + */ + } + + operand = 1; + + // skip whitespace + while (isspace(s[p])) { + p++; + } + + if (s[p] == '#') { + mk = 0; + t[q++] = s[p++]; + + // skip following whitespace + while (isspace(s[p])) { + p++; + } + } + + /* + * + * operand processing + * byte = length of operand in bytes to be assembled + * + * + */ + + /* this addresses forced high/low/two byte addressing, but only + for the first operand. Further processing is done in a_term() + */ + + /* FIXIT2 */ + + while (s[p] != '\0' && s[p] != ';' && !er) { + if (fl) { + // pass through text (e.g. for ",y") + t[q++] = s[p++]; + + } else { + if (operand) { + /* are we forcing the operand into a particular + addressing mode? !, @, ` operators + Note these are not available in ca65, but we only + switch off "@" which are used for cheap local labels*/ + if (s[p] == '!' || (s[p] == '@' && !ca65) || s[p] == '`') { #ifdef DEBUG_CAST printf("Setting cast to: %c\n", s[p]); #endif - t[q++]=T_CAST; - t[q++]=s[p]; - operand= -operand+1; - p++; - } else - if(s[p]=='(' || s[p]=='-' || s[p]=='>' || - s[p]=='<' || s[p]=='[') - { - t[q++]=s[p++]; - operand= -operand+1; /* invert to become reinverted */ - } else - if(s[p]=='*') - { - t[q++]=s[p++]; - } else - /* maybe it's a label - Note that for ca65 cheap local labels, we check for "@" */ - if(isalpha(s[p]) || s[p]=='_' || (s[p]==':' && collab) || ((s[p]==':' || s[p]=='@') && ca65)) - { - - int p2 = 0; - if (n == (Klistbytes & 0xff)) { - // check for "unlimited" - // Note: this could be done by a more general "constants" handling, - // where in appropriate places (like the one here), constants are - // replaced by a pointer to a predefined constants info, e.g. using - // a T_CONSTANT. Which would also fix the listing of this constant - // (which is currently listed as "0") - static char *unlimited = "unlimited"; - while (s[p+p2] != 0 && unlimited[p2] != 0 && s[p+p2] == unlimited[p2]) p2++; - } - if (p2 == 9) { // length of "unlimited" - er = E_OK; - // found constant - wval(q, 0, 'd'); - p += p2; - } else { - //m=n; - er=l_search((char*)s+p,&ll,&n,&v,&afl); + t[q++] = T_CAST; + t[q++] = s[p]; + operand = -operand + 1; + p++; + } else if (s[p] == '(' || s[p] == '-' || s[p] == '>' + || s[p] == '<' || s[p] == '[') { + t[q++] = s[p++]; + operand = -operand + 1; /* invert to become reinverted */ + } else if (s[p] == '*') { + t[q++] = s[p++]; + } else + /* maybe it's a label + Note that for ca65 cheap local labels, we check for "@" */ + if (isalpha(s[p]) || s[p] == '_' || (s[p] == ':' && collab) + || ((s[p] == ':' || s[p] == '@') && ca65)) { - if (er == E_NODEF && undefok) { - lg_toglobal(s+p); - } + int p2 = 0; + if (n == (Klistbytes & 0xff)) { + // check for "unlimited" + // Note: this could be done by a more general "constants" handling, + // where in appropriate places (like the one here), constants are + // replaced by a pointer to a predefined constants info, e.g. using + // a T_CONSTANT. Which would also fix the listing of this constant + // (which is currently listed as "0") + static char *unlimited = "unlimited"; + while (s[p + p2] != 0 && unlimited[p2] != 0 + && s[p + p2] == unlimited[p2]) + p2++; + } + if (p2 == 9) { // length of "unlimited" + er = E_OK; + // found constant + wval(q, 0, 'd'); + p += p2; + } else { + //m=n; + er = l_search((char*) s + p, &ll, &n, &v, &afl); - if(!er) - { - if(afl) { - t[q++]=T_POINTER; - t[q++]=afl & 255; - t[q++]=v & 255; - t[q++]=(v>>8) & 255; - t[q++]=n & 255; /* cheap fix for listing */ - t[q++]=(n>>8) & 255; /* why is the label already resolved in t_conv? */ - } else { - t[q++]=T_LABEL; - t[q++]=n & 255; - t[q++]=(n>>8) & 255; - /*wval(q,v, 0);*/ - } - } else - if(er==E_NODEF) - { + if (er == E_NODEF && undefok) { + lg_toglobal(s + p); + } + + if (!er) { + if (afl) { + t[q++] = T_POINTER; + t[q++] = afl & 255; + t[q++] = v & 255; + t[q++] = (v >> 8) & 255; + t[q++] = n & 255; /* cheap fix for listing */ + t[q++] = (n >> 8) & 255; /* why is the label already resolved in t_conv? */ + } else { + t[q++] = T_LABEL; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + /*wval(q,v, 0);*/ + } + } else if (er == E_NODEF) { #ifdef DEBUG_AM fprintf(stderr, "could not find %s\n", (char *)s+p); #endif - t[q++]=T_LABEL; - t[q++]=n & 255; - t[q++]=(n>>8) & 255; -/* - if(afl==SEG_ZEROUNDEF) uz++; -*/ - ud++; // number of undefined labels - er=E_OK; - } - p+=ll; + t[q++] = T_LABEL; + t[q++] = n & 255; + t[q++] = (n >> 8) & 255; + /* + if(afl==SEG_ZEROUNDEF) uz++; + */ + ud++; // number of undefined labels + er = E_OK; + } + p += ll; + } + } else if (s[p] <= '9' + && (s[p] > '0' || (s[p] == '0' && !ctypes))) { + tg_dez(s + p, &ll, &v); + p += ll; + wval(q, v, 'd'); + } else + /* handle encodings: hex, binary, octal, quoted strings */ + switch (s[p]) { + case '0': + // only gets here when "ctypes" is set, and starts with 0 + // we here check for the C stype "0xHEX" and "0OCTAL" encodings + if ('x' == tolower(s[p + 1])) { + // c-style hex + tg_hex(s + p + 2, &ll, &v); + p += 2 + ll; + wval(q, v, '$'); + } else if (isdigit(s[p + 1])) { + // c-style octal if digit follows + tg_oct(s + p + 1, &ll, &v); + p += 1 + ll; + wval(q, v, '&'); + } else { + // else use decimal (0) + tg_dez(s + p, &ll, &v); + p += ll; + wval(q, v, 'd'); + } + break; + case '$': + tg_hex(s + p + 1, &ll, &v); + p += 1 + ll; + wval(q, v, '$'); + break; + case '%': + tg_bin(s + p + 1, &ll, &v); + p += 1 + ll; + wval(q, v, '%'); + break; + case '&': + tg_oct(s + p + 1, &ll, &v); + p += 1 + ll; + wval(q, v, '&'); + break; + case '\'': + case '\"': + er = tg_asc(s + p, t + q, &q, &p, na1, na2, n); + break; + case ',': + if (mk) + while (s[p] != '\0' && s[p] != ';') { + while (s[p] == ' ') + p++; + *nk += (s[p] == ','); + t[q++] = s[p++]; + } + else { + *nk += 1; + t[q++] = s[p++]; + } + break; + default: + er = E_SYNTAX; + break; + } + operand = -operand + 1; + + } else /* operator */ + { + o = 0; + if (s[p] == ')' || s[p] == ']') { + t[q++] = s[p++]; + operand = -operand + 1; + } else if (s[p] == ',') { + t[q++] = s[p++]; + if (mk) { + // if only one comma, pass through all following text - esp. ",y" or ",x" etc + fl++; + } + *nk += 1; + } else + switch (s[p]) { + case '+': + o = 1; + break; + case '-': + o = 2; + break; + case '*': + o = 3; + break; + case '/': + o = 4; + break; + case '!': + if (s[p + 1] == '=') + o = 12; + break; + case '<': + switch (s[p + 1]) { + case '<': + o = 6; + break; + case '>': + o = 12; + break; + case '=': + o = 10; + break; + default: + o = 7; + break; + } + break; + case '>': + switch (s[p + 1]) { + case '>': + o = 5; + break; + case '<': + o = 12; + break; + case '=': + o = 11; + break; + default: + o = 8; + break; + } + break; + case '=': + switch (s[p + 1]) { + case '<': + o = 10; + break; + case '>': + o = 11; + break; + case '=': + o = 9; + p++; /* hack */ + break; + default: + o = 9; + break; + } + break; + case '&': + if (s[p + 1] == '&') + o = 16; + else + o = 13; + break; + case '|': + if (s[p + 1] == '|') + o = 17; + else + o = 15; + break; + case '^': + o = 14; + break; + default: + er = E_SYNTAX; + break; + } + if (o) { + t[q++] = o; + p += lp[o]; + } + operand = -operand + 1; + } + + while (s[p] == ' ') + p++; } - } - else - if(s[p]<='9' && (s[p]>'0' || (s[p] == '0' && !ctypes))) - { - tg_dez(s+p,&ll,&v); - p+=ll; - wval(q,v, 'd'); - } - else - /* handle encodings: hex, binary, octal, quoted strings */ - switch(s[p]) { - case '0': - // only gets here when "ctypes" is set, and starts with 0 - // we here check for the C stype "0xHEX" and "0OCTAL" encodings - if ('x' == tolower(s[p+1])) { - // c-style hex - tg_hex(s+p+2, &ll, &v); - p+=2+ll; - wval(q, v, '$'); - } else - if (isdigit(s[p+1])) { - // c-style octal if digit follows - tg_oct(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '&'); - } else { - // else use decimal (0) - tg_dez(s+p,&ll,&v); - p+=ll; - wval(q,v, 'd'); - } - break; - case '$': - tg_hex(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '$'); - break; - case '%': - tg_bin(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '%'); - break; - case '&': - tg_oct(s+p+1,&ll,&v); - p+=1+ll; - wval(q,v, '&'); - break; - case '\'': - case '\"': - er=tg_asc(s+p,t+q,&q,&p,na1,na2,n); - break; - case ',': - if(mk) - while(s[p]!='\0' && s[p]!=';') - { - while(s[p]==' ') p++; - *nk+=(s[p]==','); - t[q++]=s[p++]; - } - else - { - *nk+=1; - t[q++]=s[p++]; - } - break; - default : - er=E_SYNTAX; - break; - } - operand= -operand+1; - - } else /* operator */ - { - o=0; - if(s[p]==')' || s[p]==']') - { - t[q++]=s[p++]; - operand =-operand+1; - } else - if(s[p]==',') - { - t[q++]=s[p++]; - if(mk) { - // if only one comma, pass through all following text - esp. ",y" or ",x" etc - fl++; - } - *nk+=1; - } else - switch(s[p]) { - case '+': - o=1; - break; - case '-': - o=2; - break; - case '*': - o=3; - break; - case '/': - o=4; - break; - case '!': - if (s[p+1] == '=') o=12; - break; - case '<': - switch (s[p+1]) { - case '<': - o=6; - break; - case '>': - o=12; - break; - case '=': - o=10; - break; - default : - o=7; - break; - } - break; - case '>': - switch (s[p+1]) { - case '>': - o=5; - break; - case '<': - o=12; - break; - case '=': - o=11; - break; - default: - o=8; - break; - } - break; - case '=': - switch (s[p+1]) { - case '<': - o=10; - break; - case '>': - o=11; - break; - case '=': - o=9; p++; /* hack */ - break; - default: - o=9; - break; - } - break; - case '&': - if (s[p+1]=='&') - o=16; - else - o=13; - break; - case '|': - if (s[p+1]=='|') - o=17; - else - o=15; - break; - case '^': - o=14; - break; - default: - er=E_SYNTAX; - break; - } - if(o) - { - t[q++]=o; - p+=lp[o]; - } - operand= -operand+1; - } - - while(s[p]==' ') p++; - } - } - } + } + } //printf("er=%d, ud=%d\n", er, ud); - if(!er) - { -/* - if(uz==1 && ud==1 && byte!=2) { - byte=1; - } - if(byte == 1) { - t[q++] = T_FBYTE; - } else if(byte == 2) { - t[q++] = T_FADDR; - } -*/ - byte = 0; - if(ud > 0) { - er=E_NODEF; - byte = 1; - } - } - - if (s[p] == ';') { - /* handle comments */ - /* first find out how long */ - int i; - for (i = p+1; s[i] != '\0'; i++); - i = i - p; /* actual length of the comment, including zero-byte terminator */ - /*if (i >= 1) {*/ + if (!er) { + /* + if(uz==1 && ud==1 && byte!=2) { + byte=1; + } + if(byte == 1) { + t[q++] = T_FBYTE; + } else if(byte == 2) { + t[q++] = T_FADDR; + } + */ + byte = 0; + if (ud > 0) { + er = E_NODEF; + byte = 1; + } + } + + if (s[p] == ';') { + /* handle comments */ + /* first find out how long */ + int i; + for (i = p + 1; s[i] != '\0'; i++) + ; + i = i - p; /* actual length of the comment, including zero-byte terminator */ + /*if (i >= 1) {*/ /* there actually is a comment */ t[q++] = T_COMMENT; - t[q++] = i&255; - t[q++] = (i>>8)&255; - memcpy(t+q, s+p+1, i); /* also copy zero terminator, used in listing */ + t[q++] = i & 255; + t[q++] = (i >> 8) & 255; + memcpy(t + q, s + p + 1, i); /* also copy zero terminator, used in listing */ q += i; - /*}*/ - } - t[q++]=T_END; - /* FIXME: this is an unholy union of two "!" implementations :-( */ - /* FIXME FIXME FIXME ... - if (operand==1) { - t[q++]='\0'; - t[q++]=cast; - } - */ - *l=q; - if(bytep) *bytep=byte; - return(er); + /*}*/ + } + t[q++] = T_END; + /* FIXME: this is an unholy union of two "!" implementations :-( */ + /* FIXME FIXME FIXME ... + if (operand==1) { + t[q++]='\0'; + t[q++]=cast; + } + */ + *l = q; + if (bytep) + *bytep = byte; + return (er); } /********************************************************************************************* * identifies a keyword in s, if it is found, starting with s[0] * A keyword is either a mnemonic, or a pseudo-opcode */ -static int t_keyword(signed char *s, int *l, int *n) -{ - int i = 0; // index into keywords - int j = 0; - int hash; +static int t_keyword(signed char *s, int *l, int *n) { + int i = 0; // index into keywords + int j = 0; + int hash; - // keywords either start with a character, a "." or "*" - if(!isalpha(s[0]) && s[0]!='.' && s[0]!='*' ) - return(E_NOKEY); + // keywords either start with a character, a "." or "*" + if (!isalpha(s[0]) && s[0] != '.' && s[0] != '*') + return (E_NOKEY); - // if first char is a character, use it as hash... - if(isalpha(s[0])) - hash=tolower(s[0])-'a'; - else - hash=26; - + // if first char is a character, use it as hash... + if (isalpha(s[0])) + hash = tolower(s[0]) - 'a'; + else + hash = 26; - // check for "*=" - if(s[0]=='*') { - j=1; - while(s[j] && isspace(s[j])) j++; - if(s[j]=='=') { - i=Kpcdef; - j++; + // check for "*=" + if (s[0] == '*') { + j = 1; + while (s[j] && isspace(s[j])) + j++; + if (s[j] == '=') { + i = Kpcdef; + j++; + } } - } - // no keyword yet found? - if(!i) { - // get sub-table from hash code, and compare with table content - // (temporarily) redefine i as start index in opcode table, and hash as end index - i=ktp[hash]; - hash=ktp[hash+1]; - // check all entries in opcode table from start to end for that hash code - while(i='0') - val=val*8+(s[i++]-'0'); + while (s[i] < '8' && s[i] >= '0') + val = val * 8 + (s[i++] - '0'); - *l=i; - *v=val; + *l = i; + *v = val; } -static void tg_hex(signed char *s, int *l, int *v) -{ - int i=0,val=0; +static void tg_hex(signed char *s, int *l, int *v) { + int i = 0, val = 0; - while((s[i]>='0' && s[i]<='9') || (tolower(s[i])<='f' && tolower(s[i])>='a')) - { - val=val*16+(s[i]<='9' ? s[i]-'0' : tolower(s[i])-'a'+10); - i++; - } - *l=i; - *v=val; + while ((s[i] >= '0' && s[i] <= '9') + || (tolower(s[i]) <= 'f' && tolower(s[i]) >= 'a')) { + val = val * 16 + (s[i] <= '9' ? s[i] - '0' : tolower(s[i]) - 'a' + 10); + i++; + } + *l = i; + *v = val; } /* * tokenize a string - handle two delimiter types, ' and " */ -static int tg_asc(signed char *s, signed char *t, int *q, int *p, int *na1, int *na2,int n) -{ +static int tg_asc(signed char *s, signed char *t, int *q, int *p, int *na1, + int *na2, int n) { - int er=E_OK,i=0,j=0,bs=0; + int er = E_OK, i = 0, j = 0, bs = 0; + + signed char delimiter = s[i++]; - signed char delimiter = s[i++]; - #ifdef DEBUG_AM fprintf(stderr, "tg_asc token = %i\n", n); #endif - t[j++]='"'; /* pass2 token for string */ - j++; /* skip place for length */ + t[j++] = '"'; /* pass2 token for string */ + j++; /* skip place for length */ - while(s[i]!='\0' && (bs || s[i]!=delimiter)) - { + while (s[i] != '\0' && (bs || s[i] != delimiter)) { - /* implement backslashed quotes for 2.4 */ - if(n != Kbin && s[i] == '\\' && !bs && !xa23) { - bs=1; i++; continue; - } else bs=0; - /* do NOT convert for Kbin or Kaasc, or for initial parse */ - if (!n || n == Kbin || n == Kaasc) { - t[j++]=s[i]; -/* XXX 2.4 implement option for ^ for backwards compatibility */ - } else if(ca65 || (!xa23 && !mask) || s[i]!='^') { /* no escape code "^" - TODO: does ca65 has an escape code */ - t[j++]=convert_char(s[i]); - } else { /* escape code */ - signed char payload = s[i+1]; - switch(payload) { - case '\0': - er=E_SYNTAX; - break; - case '\"': - if (payload == delimiter) { - t[j++]=convert_char(payload); - i++; - } else { - er=E_SYNTAX; - } - break; - case '\'': - if (payload == delimiter) { - t[j++]=convert_char(payload); - i++; - } else { - er=E_SYNTAX; - } - break; - case '^': - t[j++]=convert_char('^'); - i++; - break; - default: - t[j++]=convert_char(payload&0x1f); - i++; - break; - } - } - i++; - } - if(j==3) /* optimize single byte string to value */ - { - t[0]=T_VALUE; - t[1]=t[2]; - t[2]=0; - t[3]=0; - t[4]=delimiter; - j+=2; - } else - { /* handle as string */ - t[1]=j-2; - *na1 +=1; - *na2 +=j-2; - } - if(s[i]==delimiter) { /* in case of no error */ - i++; /* skip ending delimiter */ - } - *q +=j; - *p +=i; - return(er); + /* implement backslashed quotes for 2.4 */ + if (n != Kbin && s[i] == '\\' && !bs && !xa23) { + bs = 1; + i++; + continue; + } else + bs = 0; + /* do NOT convert for Kbin or Kaasc, or for initial parse */ + if (!n || n == Kbin || n == Kaasc) { + t[j++] = s[i]; + /* XXX 2.4 implement option for ^ for backwards compatibility */ + } else if (ca65 || (!xa23 && !mask) || s[i] != '^') { /* no escape code "^" - TODO: does ca65 has an escape code */ + t[j++] = convert_char(s[i]); + } else { /* escape code */ + signed char payload = s[i + 1]; + switch (payload) { + case '\0': + er = E_SYNTAX; + break; + case '\"': + if (payload == delimiter) { + t[j++] = convert_char(payload); + i++; + } else { + er = E_SYNTAX; + } + break; + case '\'': + if (payload == delimiter) { + t[j++] = convert_char(payload); + i++; + } else { + er = E_SYNTAX; + } + break; + case '^': + t[j++] = convert_char('^'); + i++; + break; + default: + t[j++] = convert_char(payload & 0x1f); + i++; + break; + } + } + i++; + } + if (j == 3) /* optimize single byte string to value */ + { + t[0] = T_VALUE; + t[1] = t[2]; + t[2] = 0; + t[3] = 0; + t[4] = delimiter; + j += 2; + } else { /* handle as string */ + t[1] = j - 2; + *na1 += 1; + *na2 += j - 2; + } + if (s[i] == delimiter) { /* in case of no error */ + i++; /* skip ending delimiter */ + } + *q += j; + *p += i; + return (er); } - diff --git a/xa/src/xau.c b/xa/src/xau.c index 2962ada..0ba0f9e 100644 --- a/xa/src/xau.c +++ b/xa/src/xau.c @@ -1,6 +1,6 @@ /* xa65 - 65xx/65816 cross-assembler and utility suite * - * Copyright (C) 1989-1997 André Fachat (fachat@web.de) + * Copyright (C) 1989-1997 Andr� Fachat (fachat@web.de) * * Undefined label tracking module (also see xal.c) * @@ -34,21 +34,23 @@ int u_label(int labnr) { #ifdef DEBUG_UNDEF printf("u_label: %d\n",labnr); #endif - if(!afile->ud.ulist) { - afile->ud.ulist = malloc(200*sizeof(int)); - if(afile->ud.ulist) afile->ud.um=200; + if (!afile->ud.ulist) { + afile->ud.ulist = malloc(200 * sizeof(int)); + if (afile->ud.ulist) + afile->ud.um = 200; } - for(i=0;iud.un;i++) { - if(afile->ud.ulist[i] == labnr) return i; + for (i = 0; i < afile->ud.un; i++) { + if (afile->ud.ulist[i] == labnr) + return i; } - if(afile->ud.un>=afile->ud.um) { - afile->ud.um *= 1.5; - afile->ud.ulist = realloc(afile->ud.ulist, afile->ud.um * sizeof(int)); - if(!afile->ud.ulist) { - fprintf(stderr, "Panic: No memory!\n"); - exit(1); - } + if (afile->ud.un >= afile->ud.um) { + afile->ud.um *= 1.5; + afile->ud.ulist = realloc(afile->ud.ulist, afile->ud.um * sizeof(int)); + if (!afile->ud.ulist) { + fprintf(stderr, "Panic: No memory!\n"); + exit(1); + } } afile->ud.ulist[afile->ud.un] = labnr; return afile->ud.un++; @@ -57,15 +59,15 @@ printf("u_label: %d\n",labnr); void u_write(FILE *fp) { int i, d; 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); - for(i=0;iud.un;i++) { - l_vget(afile->ud.ulist[i], &d, &s); - fprintf(fp,"%s", s); - fputc(0,fp); + for (i = 0; i < afile->ud.un; i++) { + l_vget(afile->ud.ulist[i], &d, &s); + fprintf(fp, "%s", s); + fputc(0, fp); } free(afile->ud.ulist); - afile->ud.ulist=NULL; + afile->ud.ulist = NULL; afile->ud.um = afile->ud.un = 0; }