X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=as%2Fxa51%2Fxa_main.c;h=aadba0f5468e1cb2990b5480c1617c6ec200a466;hb=37911686415ff7fa528ef889dcbbc173625e0c07;hp=d0a0832d2b3df50cf4928d085fe02e554b593495;hpb=d010bd18867edba95da10d259068d22d5d7c114f;p=fw%2Fsdcc diff --git a/as/xa51/xa_main.c b/as/xa51/xa_main.c index d0a0832d..aadba0f5 100644 --- a/as/xa51/xa_main.c +++ b/as/xa51/xa_main.c @@ -17,6 +17,15 @@ /* adapted from the osu8asm project, 1995 */ /* http://www.pjrc.com/tech/osu8/index.html */ +/* + made "relocatable" by johan.knol@iduna.nl for sdcc + + This isn't a standalone assembler anymore. It's only purpose is to + create relocatable modules (that has to be processed with xa_link) + out of sdcc-generated .xa files +*/ + +#define D(x) x #include #include @@ -26,15 +35,20 @@ #define printf(x...) fprintf(stderr,x) #include "xa_main.h" - +#include "xa_version.h" extern void yyrestart(FILE *new_file); -extern void hexout(int byte, int memory_location, int end); extern int yyparse(); +char modulename[PATH_MAX]; +char infilename[PATH_MAX]; +char outfilename[PATH_MAX]; +char listfilename[PATH_MAX]; +char symfilename[PATH_MAX]; + /* global variables */ -FILE *fhex, *fmem, *list_fp, *sym_fp; +FILE *frel, *fmem, *list_fp, *sym_fp; extern FILE *yyin; extern char *yytext; extern char last_line_text[]; @@ -46,8 +60,9 @@ int expr_result, expr_ok, jump_dest, inst; int opcode, operand; char symbol_name[1000]; struct area_struct area[NUM_AREAS]; -int current_area=AREA_CSEG; +int current_area=0; +char rel_line[2][132]; char *areaToString (int area) { switch (area) @@ -80,7 +95,13 @@ struct symbol * build_sym_list(char *thename) { struct symbol *new, *p; -/* printf(" Symbol: %s Line: %d\n", thename, lineno); */ + if ((p=findSymbol(thename))) { + p->area=current_area; + //fprintf (stderr, "warning, symbol %s already defined\n", thename); + return p; + } + + //printf(" Symbol: %s Line: %d\n", thename, lineno); new = (struct symbol *) malloc(sizeof(struct symbol)); new->name = (char *) malloc(strlen(thename)+1); strcpy(new->name, thename); @@ -91,6 +112,7 @@ struct symbol * build_sym_list(char *thename) new->isreg = 0; new->line_def = lineno - 1; new->area = current_area; + new->mode = 'X'; // start with an external new->next = NULL; if (sym_list == NULL) return (sym_list = new); p = sym_list; @@ -99,7 +121,17 @@ struct symbol * build_sym_list(char *thename) return (new); } -int assign_value(char *thename, int thevalue) +struct symbol *findSymbol (char *thename) { + struct symbol *p; + for (p=sym_list; p; p=p->next) { + if (strcasecmp(thename, p->name)==0) { + return p; + } + } + return NULL; +} + +int assign_value(char *thename, int thevalue, char mode) { struct symbol *p; @@ -108,6 +140,7 @@ int assign_value(char *thename, int thevalue) if (!(strcasecmp(thename, p->name))) { p->value = thevalue; p->isdef = 1; + p->mode = mode; return (0); } p = p->next; @@ -116,7 +149,7 @@ int assign_value(char *thename, int thevalue) exit(1); } -int mk_bit(char *thename) +int mk_bit(char *thename, int area) { struct symbol *p; @@ -124,6 +157,7 @@ int mk_bit(char *thename) while (p != NULL) { if (!(strcasecmp(thename, p->name))) { p->isbit = 1; + p->area = area; return (0); } p = p->next; @@ -140,6 +174,7 @@ int mk_sfr(char *thename) while (p != NULL) { if (!(strcasecmp(thename, p->name))) { p->issfr = 1; + p->area = 0; return (0); } p = p->next; @@ -165,19 +200,36 @@ int mk_reg(char *thename) exit(1); } - +int mk_global(char *thename) +{ + struct symbol *p; + + p = sym_list; + while (p != NULL) { + if (!(strcasecmp(thename, p->name))) { + p->global = 1; + return (0); + } + p = p->next; + } + fprintf(stderr, "Internal Error! Couldn't find symbol\n"); + exit(1); +} int get_value(char *thename) { - struct symbol *p; - p = sym_list; - while (p != NULL) { - if (!(strcasecmp(thename, p->name))) - return (p->value); - p = p->next; - } - fprintf(stderr, "Internal Error! Couldn't find symbol value\n"); - exit(1); + struct symbol *p; + p = sym_list; + while (p != NULL) { + if (!(strcasecmp(thename, p->name))) { + if (p->mode=='=') + return 0; + return (p->value); + } + p = p->next; + } + fprintf(stderr, "Internal Error! Couldn't find symbol value\n"); + exit(1); } @@ -232,8 +284,12 @@ void print_symbol_table() #else if (p->issfr) { fprintf (sym_fp, "%-5s", "SFR"); - } else if (p->isbit) { - fprintf (sym_fp, "%-5s", "BIT"); + } else if (p->isbit && !p->area) { + fprintf (sym_fp, "%-5s", "SBIT"); + } else if (p->mode=='=') { + fprintf (sym_fp,"ABS"); + } else if (!p->isdef) { + fprintf (sym_fp,"EXTRN"); } else { fprintf (sym_fp, "%-5s", areaToString(p->area)); } @@ -251,20 +307,21 @@ void print_symbol_table() void check_redefine() { - struct symbol *p1, *p2; - p1 = sym_list; - while (p1 != NULL) { - p2 = p1->next; - while (p2 != NULL) { - if (!strcasecmp(p1->name, p2->name)) { - fprintf(stderr, "Error: symbol '%s' redefined on line %d", p1->name, p2->line_def); - fprintf(stderr, ", first defined on line %d\n", p1->line_def); - exit(1); - } - p2 = p2->next; - } - p1 = p1->next; - } + struct symbol *p1, *p2; + p1 = sym_list; + while (p1 != NULL) { + p2 = p1->next; + while (p2 != NULL) { + if (!strcasecmp(p1->name, p2->name)) { + fprintf(stderr, "Error: symbol '%s' redefined on line %d", + p1->name, p2->line_def); + fprintf(stderr, ", first defined on line %d\n", p1->line_def); + exit(1); + } + p2 = p2->next; + } + p1 = p1->next; + } } int is_target(char *thename) @@ -301,15 +358,27 @@ int is_reg(char *thename) } -int is_def(char *thename) +struct symbol *is_def(char *thename) { - struct symbol *p; - p = sym_list; - while (p != NULL) { - if (!strcasecmp(thename, p->name) && p->isdef) return(1); - p = p->next; - } - return (0); + struct symbol *p; + p = sym_list; + while (p != NULL) { + if (!strcasecmp(thename, p->name) && p->isdef) + return p; + p = p->next; + } + return NULL; +} + +struct symbol *is_ref(char *thename) { + struct symbol *p; + p = sym_list; + while (p != NULL) { + if (strcasecmp(thename, p->name)==0) + return p; + p = p->next; + } + return NULL; } /* this routine is used to dump a group of bytes to the output */ @@ -319,31 +388,82 @@ int is_def(char *thename) /* though is it expected that the lexer has placed all the actual */ /* original text from the line in "last_line_text" */ -void out(int *byte_list, int num) -{ - int i, first=1; - - if (num > 0) fprintf(list_fp, "%06X: ", MEM_POS); - else fprintf(list_fp, "\t"); - - for (i=0; i 0) fprintf(list_fp, "%06X: ", MEM_POS); + else fprintf(list_fp, "\t"); + + if (last_area!=current_area) { + // emit area information + if (area[current_area].size) { + fprintf (frel, "A %s size %d flags 0\n", + areaToString(current_area), + area[current_area].size); + if (!area[current_area].defsEmitted) { + for (p=sym_list; p; p=p->next) { + if (p->global && p->isdef && p->area==current_area) { + // skip temp labels + if (p->name[strlen(p->name)-1]!='$') { + if (p->mode=='=') { + fprintf (frel, "S %s Abs%04x\n", p->name, p->value); + } else { + fprintf (frel, "S %s Def%04x\n", p->name, p->value); + } + } + } + } + area[current_area].defsEmitted=1; + } + } + last_area=current_area; + } + if (current_area==AREA_CSEG || + current_area==AREA_GSINIT || + current_area==AREA_GSFINAL || + current_area==AREA_XINIT) { + if (num) { + for (i=0; inext) { + if (p->isdef) { + // skip temp labels, sfr and sbit + if (p->name[strlen(p->name)-1]!='$' && + p->area) { + globals++; + } + } + } + fprintf (frel, "H %d areas %d global symbols\n", areas, globals); + fprintf (frel, "M %s\n", modulename); + for (p=sym_list; p; p=p->next) { + if (!p->isdef) { + fprintf (frel, "S %s Ref0000\n", p->name); + } } } @@ -451,12 +579,6 @@ void printVersion() { printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); } -char infilename[PATH_MAX]; -char outfilename[PATH_MAX]; -char listfilename[PATH_MAX]; -char symfilename[PATH_MAX]; -//char mapfilename[PATH_MAX]; - int verbose=0, createSymbolFile=0; void process_args(int argc, char **argv) @@ -491,22 +613,18 @@ void process_args(int argc, char **argv) strcpy(infilename, argv[i]); - if (strncasecmp(infilename+strlen(infilename)-3, ".xa", 3)) { + if (strncasecmp(infilename+strlen(infilename)-4, ".asm", 3)) { fprintf (stderr, "unrecognized input file: \"%s\"\n", argv[i]); print_usage(1); } - strcpy(outfilename, infilename); - outfilename[strlen(outfilename)-3] = '\0'; - strcpy(listfilename, outfilename); + strcpy(modulename, infilename); + modulename[strlen(modulename)-4] = '\0'; + sprintf (outfilename, "%s.rel", modulename); + sprintf (listfilename, "%s.lst", modulename); if (createSymbolFile) { - strcpy(symfilename, outfilename); - strcat(symfilename, ".sym"); + sprintf (symfilename, "%s.sym", modulename); } - //strcpy(mapfilename, outfilename); - strcat(outfilename, ".hex"); - strcat(listfilename, ".lst"); - //strcat(mapfilename, ".map"); } /* pass #1 (p1=1) find all symbol defs and branch target names */ @@ -522,8 +640,8 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open file '%s'.\n", infilename); exit(1); } - fhex = fopen(outfilename, "w"); - if (fhex == NULL) { + frel = fopen(outfilename, "w"); + if (frel == NULL) { fprintf(stderr, "Can't write file '%s'.\n", outfilename); exit(1); } @@ -556,7 +674,7 @@ int main(int argc, char **argv) init_areas(); yyparse(); - addAreaSymbols(); + relPrelude(); if (createSymbolFile) print_symbol_table(); if (verbose) printf("Pass 3: Generating Object Code:\n"); @@ -569,7 +687,6 @@ int main(int argc, char **argv) yyparse(); fclose(yyin); - hexout(0, 0, 1); /* flush and close intel hex file output */ return 0; }