/* 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 <stdio.h>
int lineno=1;
int p1=0, p2=0, p3=0;
int expr_result, expr_ok, jump_dest, inst;
-int opcode, operand;
+int opcode;
char symbol_name[1000];
struct area_struct area[NUM_AREAS];
int current_area=0;
case AREA_XISEG: return "XISEG";
case AREA_XINIT: return "XINIT";
case AREA_GSINIT: return "GSINIT";
- case AREA_GSFINAL: return "GSFINAL";
- case AREA_HOME: return "HOME";
- case AREA_SSEG: return "SSEG";
+ //case AREA_GSFINAL: return "GSFINAL";
+ //case AREA_HOME: return "HOME";
+ //case AREA_SSEG: return "SSEG";
}
return ("UNKNOW");
}
struct symbol *new, *p;
if ((p=findSymbol(thename))) {
- p->area=current_area;
- //fprintf (stderr, "warning, symbol %s already defined\n", thename);
- return p;
+ if (p->isdef) {
+ fprintf (stderr, "error: symbol %s already defined\n", thename);
+ exit (1);
+ } else {
+ return p;
+ }
}
//printf(" Symbol: %s Line: %d\n", thename, lineno);
return NULL;
}
-int assign_value(char *thename, int thevalue, char mode)
-{
- struct symbol *p;
-
- p = sym_list;
- while (p != NULL) {
- if (!(strcasecmp(thename, p->name))) {
- p->value = thevalue;
- p->isdef = 1;
- p->mode = mode;
- return (0);
- }
- p = p->next;
- }
- fprintf(stderr, "Internal Error! Couldn't find symbol\n");
- exit(1);
+int assign_value(char *thename, int thevalue, char mode) {
+ struct symbol *p;
+
+ p = sym_list;
+ while (p != NULL) {
+ if (!(strcasecmp(thename, p->name))) {
+ p->area=current_area;
+ p->value = thevalue;
+ p->isdef = 1;
+ p->mode = mode;
+ return (0);
+ }
+ p = p->next;
+ }
+ fprintf(stderr, "Internal Error! Couldn't find symbol\n");
+ exit(1);
}
int mk_bit(char *thename, int area)
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);
}
fprintf(sym_fp, " Line %d\n", p->line_def);
#else
if (p->issfr) {
- fprintf (sym_fp, "%-5s", "SFR");
+ fprintf (sym_fp, "%-7s", "SFR");
} else if (p->isbit && !p->area) {
- fprintf (sym_fp, "%-5s", "SBIT");
+ fprintf (sym_fp, "%-7s", "SBIT");
+ } else if (p->mode=='=') {
+ fprintf (sym_fp,"ABS ");
} else if (!p->isdef) {
- fprintf (sym_fp,"EXTRN");
+ fprintf (sym_fp,"EXTRN ");
} else {
- fprintf (sym_fp, "%-5s", areaToString(p->area));
+ fprintf (sym_fp, "%-7s", areaToString(p->area));
}
fprintf (sym_fp, " 0x%04x (%5d)", p->value, p->value);
fprintf (sym_fp, " %s", p->isdef ? "D" : "-");
return NULL;
}
+int is_abs(char *thename) {
+ struct symbol *p;
+ p = sym_list;
+ while (p != NULL) {
+ if (strcasecmp(thename, p->name)==0)
+ return p->mode == '=';
+ p = p->next;
+ }
+ return 0;
+}
+
/* this routine is used to dump a group of bytes to the output */
/* it is responsible for generating the list file and sending */
/* the bytes one at a time to the object code generator */
if (last_area!=current_area) {
// emit area information
- fprintf (frel, "A %s size %d flags 0\n",
- areaToString(current_area),
- area[current_area].size);
- area[current_area].defsEmitted=1;
- if (!area[current_area].defsEmitted) {
- for (p=sym_list; p; p=p->next) {
- if (p->isdef && p->area==current_area) {
- if (debug || p->name[strlen(p->name)-1]!='$') {
- fprintf (frel, "S %s Def%04x\n", p->name, p->value);
+ 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_GSFINAL ||
+ current_area==AREA_GSINIT ||
current_area==AREA_XINIT) {
if (num) {
- fprintf (frel, "T %02x %02x", (MEM_POS>>16)&0xff, MEM_POS&0xff);
for (i=0; i<num; i++) {
+ if ((i%16)==0) {
+ fprintf (frel, "%sT %04x", i ? "\n" : "", MEM_POS+i);
+ }
fprintf (frel, " %02x", byte_list[i]);
}
fprintf (frel, "\n");
} else {
if (num % 4) fprintf(list_fp, "\n");
}
- expr_var[0][0]='\0';
- expr_var[1][0]='\0';
+ operand[0][0]='\0';
+ operand[1][0]='\0';
rel_line[0][0]='\0';
rel_line[1][0]='\0';
}
void pad_with_nop()
{
- static int nops[] = {NOP_OPCODE, NOP_OPCODE, NOP_OPCODE, NOP_OPCODE};
- int num;
-
- last_line_text[0] = '\0';
-
- for(num=0; (MEM_POS + num) % BRANCH_SPACING; num++) ;
- if (p3) out(nops, num);
- MEM_POS += num;
+ static int nops[] = {NOP_OPCODE, NOP_OPCODE, NOP_OPCODE, NOP_OPCODE};
+ int num;
+
+ last_line_text[0] = '\0';
+
+ for(num=0; (MEM_POS + num) % BRANCH_SPACING; num++) {
+ sprintf (last_line_text, "\tnop\t; word allignment");
+ }
+ if (p3) out(nops, num);
+ MEM_POS += num;
}
/* print branch out of bounds error */
exit(1);
}
-/* output the jump either direction on carry */
-/* jump_dest and MEM_POS must have the proper values */
-
-/*
-void do_jump_on_carry()
-{
- if (p3) {
- operand = REL4(jump_dest, MEM_POS);
- if (operand < 0) {
- operand *= -1;
- operand -= 1;
- if (operand > 15) boob_error();
- out(0x20 + (operand & 15));
- } else {
- if (operand > 15) boob_error();
- out(0x30 + (operand & 15));
- }
- }
-}
-*/
-
/* turn a string like "10010110b" into an int */
int binary2int(char *str)
void print_usage(int);
-
-/* todo: someday this will allow the user to control where the */
-/* various memory areas go, and it will take care of assigning */
-/* positions to area which follow others (such as OSEG getting */
-/* set just after DSEG on the 2nd and 3rd passes when we have */
-/* leared the size needed for each segment */
-
void init_areas(void)
{
area[AREA_CSEG].start=area[AREA_CSEG].alloc_position = 0;
- area[AREA_DSEG].start=area[AREA_DSEG].alloc_position = 0x30;
+ area[AREA_DSEG].start=area[AREA_DSEG].alloc_position = 0;
area[AREA_BSEG].start=area[AREA_BSEG].alloc_position = 0;
area[AREA_XSEG].start=area[AREA_XSEG].alloc_position = 0;
area[AREA_XISEG].start=area[AREA_XISEG].alloc_position = 0;
struct symbol *p;
fprintf (frel, "SDCCXA rel, version %1.1f\n", version);
- for (i=0; i<NUM_AREAS; i++) {
+ for (i=1; i<NUM_AREAS; i++) {
if ((area[i].size=area[i].alloc_position-area[i].start)) {
areas++;
}
-#if 0
- current_area=i;
- sprintf (buffer, "s_%s", areaToString(i));
- build_sym_list (buffer);
- buffer[0]='l';
- build_sym_list (buffer);
-#endif
}
for (p=sym_list; p; p=p->next) {
if (p->isdef) {
- if (debug || p->name[strlen(p->name)-1]!='$') {
+ // skip temp labels
+ if (p->name[strlen(p->name)-1]!='$') {
globals++;
}
}
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(modulename, infilename);
- modulename[strlen(modulename)-3] = '\0';
+ modulename[strlen(modulename)-4] = '\0';
sprintf (outfilename, "%s.rel", modulename);
sprintf (listfilename, "%s.lst", modulename);
if (createSymbolFile) {