* - use a_type == 0 as "virgin area" flag: set == 1 if -b
*/
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <alloc.h>
#include "aslink.h"
+#ifdef WIN32T
+#include <time.h>
+
+void Timer(int action, char * message)
+{
+ static double start, end, total=0.0;
+ static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC;
+
+ if(action==0) start=clock()*secs_per_tick;
+ else if(action==1)
+ {
+ end=clock() * secs_per_tick;
+ printf("%s \t%f seconds.\n", message, (end-start));
+ total+=end-start;
+ }
+ else
+ {
+ printf("Total time: \t%f seconds.\n", total);
+ total=0.0;
+ }
+}
+#endif
+
/* yuck - but including unistd.h causes problems on Cygwin by redefining
- * addr_t.
+ * Addr_T.
*/
extern int unlink(const char *);
*
*/
+/*JCF: Creates some of the default areas so they are allocated in the right order.*/
+void Areas51 (void)
+{
+ char * rel[]={
+ "XH",
+ "H 7 areas 0 global symbols",
+ "A _CODE size 0 flags 0", /*Each .rel has one, so...*/
+ "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/
+ "A REG_BANK_1 size 0 flags 4",
+ "A REG_BANK_2 size 0 flags 4",
+ "A REG_BANK_3 size 0 flags 4",
+ "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/
+ "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/
+ ""
+ };
+ int j;
+
+ for (j=0; rel[j][0]!=0; j++)
+ {
+ ip=rel[j];
+ link_main();
+ }
+
+ /*Set the start address of the default areas:*/
+ for(ap=areap; ap; ap=ap->a_ap)
+ {
+ /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; }
+ else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; }
+ }
+}
+
/*)Function VOID main(argc,argv)
*
* int argc number of command line arguments + 1
register char *p;
register int c, i;
- fprintf(stdout, "\n");
+#ifdef WIN32T
+ Timer(0, "");
+#endif
startp = (struct lfile *) new (sizeof (struct lfile));
syminit();
if (dflag){
- dfp = afile("temp", "cdb", 1);
+ //dfp = afile("temp", "cdb", 1);
+ SaveLinkedFilePath(linkp->f_idp); //Must be the first one...
+ dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002
if (dfp == NULL)
lkexit(1);
}
filep = linkp;
hp = NULL;
radix = 10;
+
+ Areas51(); /*JCF: Create the default 8051 areas in the right order*/
while (getline()) {
ip = ib;
if (mflag || jflag)
map();
+ if (sflag) /*JCF: memory usage summary output*/
+ if(summary(areap))lkexit(1);
+
if (iram_size)
iramcheck();
reloc('E');
}
}
+ //JCF:
+ CreateAOMF51();
+
+#ifdef WIN32T
+ Timer(1, "Linker execution time");
+#endif
+
lkexit(lkerr);
return 0;
}
if (rfp != NULL) fclose(rfp);
if (sfp != NULL) fclose(sfp);
if (tfp != NULL) fclose(tfp);
- if (dfp != NULL) {
+ if (dfp != NULL) fclose(dfp);
+ /*if (dfp != NULL)
FILE *xfp = afile(linkp->f_idp,"cdb",1);
dfp = freopen("temp.cdb","r",dfp);
copyfile(xfp,dfp);
fclose(xfp);
fclose(dfp);
unlink("temp.cdb");
- }
+ }*/
exit(i);
}
if ((c=endline()) == 0) { return; }
switch (c) {
+ case 'O': /*For some important sdcc options*/
+ if (pass == 0)
+ {
+ if(strlen(sdccopt)==0)
+ {
+ strcpy(sdccopt, &ip[1]);
+ strcpy(sdccopt_module, curr_module);
+ }
+ else
+ {
+ if(strcmp(sdccopt, &ip[1])!=0)
+ {
+ fprintf(stderr,
+ "?ASlink-Warning-Conflicting sdcc options:\n"
+ " \"%s\" in module \"%s\" and\n"
+ " \"%s\" in module \"%s\".\n",
+ sdccopt, sdccopt_module, &ip[1], curr_module);
+ lkerr++;
+ }
+ }
+ }
+ break;
+
case 'X':
radix = 16;
break;
sdp.s_area = NULL;
sdp.s_areax = NULL;
sdp.s_addr = 0;
- lastExtendedAddress = -1;
break;
case 'M':
if (pass == 0)
+ {
+ strcpy(curr_module, &ip[1]);
module();
+ }
break;
case 'A':
++mflag;
break;
+ case 'y': /*JCF: memory usage summary output*/
+ case 'Y':
+ ++sflag;
+ break;
+
case 'j':
case 'J':
jflag = 1;
iramsav();
return(0);
+ case 'v':
+ case 'V':
+ xramsav();
+ return(0);
+
+ case 'w':
+ case 'W':
+ codesav();
+ return(0);
+
case 'z':
case 'Z':
dflag = 1;
* int lkerr error flag
*
* functions called:
- * addr_t expr() lkeval.c
+ * Addr_T expr() lkeval.c
* int fprintf() c_library
* VOID getid() lklex.c
* char getnb() lklex.c
}
if (ap == NULL) {
fprintf(stderr,
- "No definition of area %s\n", id);
+ "ASlink-Warning-No definition of area %s\n", id);
lkerr++;
} else {
ap->a_addr = v;
ap->a_type = 1; /* JLH: value set */
}
} else {
- fprintf(stderr, "No '=' in base expression");
+ fprintf(stderr, "ASlink-Warning-No '=' in base expression");
lkerr++;
}
bsp = bsp->b_base;
* int lkerr error flag
*
* functions called:
- * addr_t expr() lkeval.c
+ * Addr_T expr() lkeval.c
* int fprintf() c_library
* VOID getid() lklex.c
* char getnb() lklex.c
* the assembler on an open error.
*
* local variables:
- * int c character value
* char fb[] constructed file specification string
* FILE * fp filehandle for opened file
- * char * p1 pointer to filespec string fn
- * char * p2 pointer to filespec string fb
- * char * p3 pointer to filetype string ft
*
* global variables:
* int lkerr error flag
char *fn;
char *ft;
{
- register char *p1, *p2, *p3;
- register int c;
FILE *fp;
- char fb[FILSPC];
+ char fb[PATH_MAX];
char *omode = (wf ? (wf == 2 ? "a" : "w") : "r");
-
- p1 = fn;
- p2 = fb;
- p3 = ft;
- while ((c = *p1++) != 0 && c != FSEPX) {
- if (p2 < &fb[FILSPC-4])
- *p2++ = c;
- }
- *p2++ = FSEPX;
- if (*p3 == 0) {
- if (c == FSEPX) {
- p3 = p1;
- } else {
- p3 = "rel";
- }
+ int i;
+
+ /*Look backward the name path and get rid of the extension, if any*/
+ i=strlen(fn);
+ for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>=0); i--);
+ if( (fn[i]=='.') && strcmp(ft, "lnk") )
+ {
+ strncpy(fb, fn, i);
+ fb[i]=0;
}
- while ((c = *p3++) != 0) {
- if (p2 < &fb[FILSPC-1])
- *p2++ = c;
+ else
+ {
+ strcpy(fb, fn);
}
- *p2++ = 0;
- if ((fp = fopen(fb, omode)) == NULL) {
- if (strcmp(ft,"cdb")) {
- fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
- lkerr++;
+
+ /*Add the extension*/
+ strcat(fb, ".");
+ strcat(fb, strlen(ft)?ft:"rel");
+
+ fp = fopen(fb, omode);
+ if (fp==NULL)
+ {
+ if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/
+ {
+ fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
+ lkerr++;
}
}
return (fp);
* functions called:
* char getnb() lklex.c
* VOID unget() lklex.c
- * addr_t expr() lkeval.c
+ * Addr_T expr() lkeval.c
*
* side effects:
* The iram_size may be modified.
iram_size = 128; /* Default is 128 (0x80) bytes */
}
+/*Similar to iramsav but for xram memory*/
+VOID
+xramsav()
+{
+ unget(getnb());
+ if (ip && *ip)
+ xram_size = expr(0); /* evaluate size expression */
+ else
+ xram_size = rflag?0x1000000:0x10000;
+}
+
+/*Similar to iramsav but for code memory*/
+VOID
+codesav()
+{
+ unget(getnb());
+ if (ip && *ip)
+ code_size = expr(0); /* evaluate size expression */
+ else
+ code_size = rflag?0x1000000:0x10000;
+}
+
+
/*)Function VOID iramcheck()
*
* The function iramcheck() is used at the end of linking to check that
" -u Update listing file(s) with link data as file(s)[.RST]",
"Miscellaneous:\n"
" -a [iram-size] Check for internal RAM overflow",
+ " -v [xram-size] Check for external RAM overflow",
+ " -w [code-size] Check for code overflow",
"End:",
" -e or null line terminates input",
0