From 5dc5912c87c4a23e12c62a7a240aaed20cbca574 Mon Sep 17 00:00:00 2001 From: jesusc Date: Wed, 11 Dec 2002 07:22:57 +0000 Subject: [PATCH] Added support to generate aomf51 file. (Basic Intel support, no Keil extensions yet) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2114 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 11 + as/mcs51/aslink.h | 17 +- as/mcs51/lkaomf51.c | 933 ++++++++++++++++++++++++++++++++++++++++++++ as/mcs51/lkdata.c | 2 +- as/mcs51/lklex.c | 3 +- as/mcs51/lklibr.c | 2 +- as/mcs51/lklist.c | 317 +-------------- as/mcs51/lkmain.c | 13 +- as/mcs51/lkmem.c | 339 ++++++++++++++++ 9 files changed, 1310 insertions(+), 327 deletions(-) create mode 100644 as/mcs51/lkaomf51.c create mode 100644 as/mcs51/lkmem.c diff --git a/ChangeLog b/ChangeLog index b6414bcc..63280917 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2002-12-10 Jesus Calvino-Fraga + + * in \sdcc\as\mcs51\ changed these files in order to create an + aomf51 file: aslink.h, lkdta.c, lklex.c, lklibr.c, lklist.c, + lkmain.c. Also added: lkmem.c and lkaomf51.c. Changed the + following files to include the previous two files: aslink.dsp, + Makefile.aslink, Makefile.bcc, and Makefile.in. + + * Changed \sdcc\src\SDCCmain.c so it creates files with extension + .adb instead of .cdb + 2002-11-09 Jesus Calvino-Fraga * \sdcc\as\mcs51\lklist.c: Now reports memory usage using the diff --git a/as/mcs51/aslink.h b/as/mcs51/aslink.h index 9ce5dc4c..6d8500e0 100644 --- a/as/mcs51/aslink.h +++ b/as/mcs51/aslink.h @@ -80,11 +80,16 @@ #endif /* - * PATH_AMX + * PATH_MAX */ #include #ifndef PATH_MAX /* POSIX, but not required */ -#define PATH_MAX 255 /* define a reasonable value */ + #if defined(__BORLANDC__) || defined(_MSC_VER) + #include + #define PATH_MAX _MAX_PATH + #else + #define PATH_MAX 255 /* define a reasonable value */ + #endif #endif /* @@ -449,7 +454,7 @@ extern char *rp; /* pointer into the LST file extern char rb[NINPUT]; /* LST file text line being * address relocated */ -extern char ctype[]; /* array of character types, one per +extern unsigned char ctype[]; /* array of character types, one per * ASCII character */ @@ -749,9 +754,13 @@ extern char *StoreString( char *str ); /* lknoice.c */ extern void DefineNoICE( char *name, Addr_T value, int page ); -/* JCF: lksmry.c */ +/* JCF: lkmem.c */ extern int summary(struct area * xp); +/* JCF: lkaomf51.c */ +extern void SaveLinkedFilePath(char * filepath); +extern void CreateAOMF51(void); + /* SD added this to change strcmpi --> strcmp (strcmpi NOT ANSI) */ #define strcmpi strcmp diff --git a/as/mcs51/lkaomf51.c b/as/mcs51/lkaomf51.c new file mode 100644 index 00000000..7082e675 --- /dev/null +++ b/as/mcs51/lkaomf51.c @@ -0,0 +1,933 @@ +/*------------------------------------------------------------------------- + lkaomf51.c - Create an absolute object memory format 51 file + + Written By - Jesus Calvino-Fraga, jesusc@ieee.org (2002) + + 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 the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-------------------------------------------------------------------------*/ + +#include +#include +#include +#include "aslink.h" + +#define EQ(A,B) !strcmp((A),(B)) +#define MEMSIZE 0x10000 + +typedef struct +{ + char PathName[PATH_MAX]; + char ModuleName[PATH_MAX]; +} _infn; + +int numin=0; +_infn * infn=NULL; + +char ihxFileName[PATH_MAX]; +char aomf51FileName[PATH_MAX]; + +typedef struct +{ + char name[0x100]; + int FileNameNumber; + int Procedure;//If the symbol belongs to a function + int Static; //If the symbol is only public on its file + int Address; + int UsageType; +} _symbol; + +int numsym=0; +_symbol * symbol=NULL; + +typedef struct +{ + char name[0x100]; + int FileNameNumber; + int BeginAdd; + int EndAdd; +} _procedure; + +int numproc=0; +_procedure * procedure=NULL; + +typedef struct +{ + int Number; + int Address; + int Procedure; + int FileNameNumber; +} _linenum; + +int numlinenum=0; +_linenum * linenum=NULL; + +typedef struct +{ + char * name; + int usage; +} +_UsageType; + +_UsageType UsageType[]= +{ + {"CSEG", 0}, + {"GSINIT", 0}, + {"GSFINAL", 0}, + {"HOME", 0}, + {"XINIT", 0}, + {"XSEG", 1}, + {"XISEG", 1}, + {"REG_BANK_0", 2}, + {"REG_BANK_1", 2}, + {"REG_BANK_2", 2}, + {"REG_BANK_3", 2}, + {"DSEG", 2}, + {"OSEG", 2}, + {"SSEG", 2}, + {"ISEG", 3}, + {"BSEG", 4}, + {"", 5} /*A typeless number?*/ +}; + +char * UsageTypeName[]={"CODE", "XDATA", "DATA", "IDATA", "BIT", "NUMBER"}; +int AddNumber; +unsigned char * ihxBuff=NULL; +FILE * aomf51out; +int GlobalChkSum=0; +int HexSize, HexBegin=0x10000; + + +void GetName(char * filepath, char * name) +{ + int j, k; + for(j=strlen(filepath); j>0; j--) + if( (filepath[j-1]=='/')||(filepath[j-1]=='\\') ) break; + for(k=0; (filepath[j]!=0)&&(filepath[j]!='.'); j++, k++) + name[k]=filepath[j]; + name[k]=0; +} + +void SaveLinkedFilePath(char * filepath) +{ + int j; + + if(dflag) + { + infn=realloc(infn, sizeof(_infn)*(numin+1)); + + strcpy(infn[numin].PathName, filepath); + j=strlen(infn[numin].PathName); + + /*If there is an extension remove it*/ + if(j>=4) + { + if(EQ(&infn[numin].PathName[j-4], ".rel")) + { + infn[numin].PathName[j-4]=0; + } + } + + /*Get the module name=filename, no drive, no dir, no ext*/ + GetName(infn[numin].PathName, infn[numin].ModuleName); + //printf("%s, %s\n", infn[numin].PathName, infn[numin].ModuleName); + + numin++; + } +} + +void FreeAll(void) +{ + if(infn!=NULL) + { + free(infn); + numin=0; + infn=NULL; + } + + if(symbol!=NULL) + { + free(symbol); + numsym=0; + symbol=NULL; + } + + if(procedure!=NULL) + { + free(procedure); + numproc=0; + procedure=NULL; + + } + if(linenum!=NULL) + { + free(linenum); + numlinenum=0; + linenum=NULL; + } + + if(ihxBuff!=NULL) + { + free(ihxBuff); + ihxBuff=NULL; + } +} + +void OutputByte(unsigned char value) +{ + GlobalChkSum+=value; + fwrite( &value, 1, 1, aomf51out ); +} + +void OutputWord(int value) +{ + OutputByte((unsigned char)(value%0x100)); + OutputByte((unsigned char)(value/0x100)); +} + +void OutputName(char * name) +{ + int k; + OutputByte((unsigned char)strlen(name)); + for(k=0; name[k]!=0; k++) + OutputByte((unsigned char)toupper(name[k])); +} + +void OutputChkSum(void) +{ + OutputByte((unsigned char)(0x100-(GlobalChkSum%0x100))); + GlobalChkSum=0; +} + +void DumpForDebug (void) +{ + char DumpFileName[PATH_MAX]; + FILE * DumpFile; + int j; + + strcpy(DumpFileName, infn[0].PathName); + strcat(DumpFileName, ".d51"); + + DumpFile=fopen(DumpFileName, "wb"); + if(DumpFile==NULL) + { + printf("Couldn't create file %s\n", DumpFileName); + return; + } + + fprintf(DumpFile,"SYMBOLS:\n"); + + for(j=0; j=0)?procedure[symbol[j].Procedure].name:"GLOBAL", + symbol[j].Address, + UsageTypeName[symbol[j].UsageType&0xf]); + } + + fprintf(DumpFile,"\nPROCEDURES:\n"); + for(j=0; j %s\n", + linenum[j].Number, + linenum[j].Address, + infn[linenum[j].FileNameNumber].PathName, + (linenum[j].Procedure>=0)?procedure[linenum[j].Procedure].name:"I don't know"); + } + + fclose(DumpFile); +} + +void OutputAOEMF51(void) +{ + int i, j, k, recsize; + char MHRname[0x100], Mname[0x100]; + + strcpy(aomf51FileName, infn[0].PathName); + + aomf51out=fopen(aomf51FileName, "wb"); + if(aomf51out==NULL) + { + printf("Couldn't create file %s\n", aomf51FileName); + return; + } + + GetName(infn[0].PathName, MHRname); + GlobalChkSum=0; + + /*Module header record*/ + OutputByte(0x02);/*REC TYPE*/ + OutputWord((strlen(MHRname)+1)+3);/*Record Length*/ + OutputName(MHRname);/*Module Name*/ + OutputByte(0xff);/*TRN ID: RL51?*/ + OutputByte(0x00); + OutputChkSum(); + + for(j=0; j2) /*If there are any symbols*/ + { + OutputByte(0x12); /*REC TYPE*/ + OutputWord(recsize);/*Record Length*/ + OutputByte(0x01); /*DEF TYPE: Public symbols*/ + for(k=0; k2) /*If there are any symbols*/ + { + OutputByte(0x12); /*REC TYPE*/ + OutputWord(recsize);/*Record Length*/ + OutputByte(0x00); /*DEF TYPE: Local symbols*/ + for(k=0; k2) /*If there are any symbols*/ + { + OutputByte(0x12); /*REC TYPE*/ + OutputWord(recsize);/*Record Length*/ + OutputByte(0x00); /*DEF TYPE: Local symbols*/ + for(i=0; i2) /*If there are any line numbers*/ + { + OutputByte(0x12); /*REC TYPE*/ + OutputWord(recsize);/*Record Length*/ + OutputByte(0x03); /*DEF TYPE: Line numbers*/ + for(i=0; i|L}$$$(),
,," + char Sfmt[]="%[^$] %c %[^$] %c %[^$] %c %s"; + char c; + char scope[0x100]; + char name[0x100]; + char level[0x100]; + char block[0x100]; + char Bfmt[]="%[^)] %c %c %c %c %d %c %d"; + char TypeInfo[0x100]; + char AddressSpace; + int OnStack; + int StackOffset; + int Address, CLine; + + if(numin==0) return; + + if (dfp != NULL) + { + fclose(dfp); + dfp=NULL; + } + + /*Build the source filename*/ + strcpy(SourceName, infn[0].PathName); + strcat(SourceName, ".cdb"); + CDBin=fopen(SourceName, "r"); + if(CDBin==NULL) + { + printf("Couldn't open file '%s'\n", SourceName); + } + + CurrentModule=0; /*Set the active module as the first one*/ + while(!feof(CDBin)) + { + fgets(buff, sizeof(buff)-1, CDBin); + + if(!feof(CDBin)) switch(buff[0]) + { + /*Example: "M:adq"*/ + case 'M': + sscanf(&buff[2], "%s", name); + for(j=0; j(),
,,*/ + sscanf(block, Bfmt, + TypeInfo, &c, &c, + &AddressSpace, &c, + &OnStack, &c, + &StackOffset); + + i=-1; k=-1; + switch(scope[2]) + { + case 'G': /*Global symbol*/ + break; + case 'L': /*Local symbol of a procedure*/ + for(j=0; j=procedure[k].BeginAdd) && + (linenum[j].Address<=procedure[k].EndAdd) && + (linenum[j].FileNameNumber==procedure[k].FileNameNumber) ) + { + linenum[j].Procedure=k; + } + } + } + + fclose(CDBin); +} + +int hex2dec (char hex_digit) +{ + int j; + j=toupper(hex_digit)-'0'; + if (j>9) j -= 7; + return j; +} + +unsigned char GetByte(char * buffer) +{ + return hex2dec(buffer[0])*0x10+hex2dec(buffer[1]); +} + +unsigned short GetWord(char * buffer) +{ + return hex2dec(buffer[0])*0x1000+ + hex2dec(buffer[1])*0x100+ + hex2dec(buffer[2])*0x10+ + hex2dec(buffer[3]); +} + +int ReadHexFile(int * Begin) +{ + char buffer[1024]; + FILE * filein; + int j; + unsigned char linesize, recordtype, rchksum, value; + unsigned short address; + int MaxAddress=0; + int chksum; + + /*If the hexfile is already open, close it*/ + if(ofp!=NULL) + { + fclose(ofp); + ofp=NULL; + } + + strcpy(ihxFileName, infn[0].PathName); + strcat(ihxFileName, ".ihx"); + + if ( (filein=fopen(ihxFileName, "r")) == NULL ) + { + printf("Error: Can't open file `%s`.\r\n", ihxFileName); + return 0; + } + + ihxBuff=calloc(MEMSIZE, sizeof(unsigned char)); + if(ihxBuff==NULL) + { + printf("Insufficient memory\n"); + fclose(filein); + return -1; + } + + for(j=0; jf_type == F_STD) sfp = afile(fid, "rel", 0); /* if a .cdb file exists then copy it over */ if (dflag && sfp && dfp && pass == 0) { - FILE *xfp = afile(fid,"cdb",0); + FILE *xfp = afile(fid,"adb",0); //JCF: Nov 30, 2002 if (xfp) { copyfile(dfp,xfp); fclose(xfp); } } if (uflag && pass != 0) { + SaveLinkedFilePath(fid); //Save the linked path for aomf51 if ((tfp = afile(fid, "lst", 0)) != NULL) { if ((rfp = afile(fid, "rst", 1)) == NULL) { fclose(tfp); diff --git a/as/mcs51/lklibr.c b/as/mcs51/lklibr.c index cadcbfa1..26d4a881 100644 --- a/as/mcs51/lklibr.c +++ b/as/mcs51/lklibr.c @@ -460,7 +460,7 @@ char *name; fclose(libfp); /* if cdb information required & cdb file present */ if (dflag && dfp) { - FILE *xfp = afile(str,"cdb",0); + FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002 if (xfp) { copyfile(dfp,xfp); fclose(xfp); diff --git a/as/mcs51/lklist.c b/as/mcs51/lklist.c index 688134a0..5325ec89 100644 --- a/as/mcs51/lklist.c +++ b/as/mcs51/lklist.c @@ -368,6 +368,7 @@ struct area *xp; if (dflag && strchr(ptr,'$')) fprintf(dfp,"L:%s:%X\n",ptr,aj); + /* NoICE output of symbol */ if (jflag) DefineNoICE( ptr, aj, memPage ); @@ -1096,319 +1097,3 @@ char *str; } return(1); } - -/*JCF: Create a memory summary file with extension .mem*/ -int summary(struct area * areap) -{ - #define EQ(A,B) !strcmpi((A),(B)) - #define MIN_STACK 16 - #define REPORT_ERROR(A, H) \ - {\ - fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \ - fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \ - toreturn=1; \ - } - - #define REPORT_WARNING(A, H) \ - { \ - fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \ - fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \ - } - - char buff[128]; - int j, toreturn=0; - unsigned int Total_Last=0, k; - - struct area * xp; - FILE * of; - - /*Artifacts used for printing*/ - char start[8], end[8], size[8], max[8]; - char format[]=" %-16.16s %-7.7s %-7.7s %-7.7s %-7.7s\n"; - char line[]="---------------------"; - - typedef struct - { - unsigned int Start; - unsigned int Size; - unsigned int Max; - char Name[NCPS]; - unsigned int flag; - } _Mem; - - unsigned int dram[0x100]; - _Mem Ram[]={ - {0, 8, 8, "REG_BANK_0", 0x0001}, - {0x8, 8, 8, "REG_BANK_1", 0x0002}, - {0x10, 8, 8, "REG_BANK_2", 0x0004}, - {0x18, 8, 8, "REG_BANK_3", 0x0008}, - {0x20, 0, 16, "BSEG_BYTES", 0x0010}, - {0, 0, 128, "UNUSED", 0x0000}, - {0x7f, 0, 128, "DATA", 0x0020}, - {0, 0, 128, "TOTAL:", 0x0000} - }; - - _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080}; - _Mem Stack={0xff, 0, 1, "STACK", 0x0000}; - _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100}; - _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200}; - - if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/ - { - Ram[5].Max=0x80; - Ram[6].Max=0x80; - Ram[7].Max=0x80; - IRam.Max=0x80; - iram_size=0x100; - } - else if(iram_size<0x80) - { - Ram[5].Max=iram_size; - Ram[6].Max=iram_size; - Ram[7].Max=iram_size; - IRam.Max=0; - } - else - { - Ram[5].Max=0x80; - Ram[6].Max=0x80; - Ram[7].Max=0x80; - IRam.Max=iram_size-0x80; - } - - for(j=0; j<(int)iram_size; j++) dram[j]=0; - for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/ - - /* Open Memory Summary File*/ - of = afile(linkp->f_idp, "mem", 1); - if (of == NULL) - { - lkexit(1); - } - - xp=areap; - while (xp) - { - /**/ if (EQ(xp->a_id, "REG_BANK_0")) - { - Ram[0].Size=xp->a_size; - } - else if (EQ(xp->a_id, "REG_BANK_1")) - { - Ram[1].Size=xp->a_size; - } - else if (EQ(xp->a_id, "REG_BANK_2")) - { - Ram[2].Size=xp->a_size; - } - else if (EQ(xp->a_id, "REG_BANK_3")) - { - Ram[3].Size=xp->a_size; - } - else if (EQ(xp->a_id, "BSEG_BYTES")) - { - Ram[4].Size=xp->a_size; - } - else if ( EQ(xp->a_id, "DSEG") || EQ(xp->a_id, "OSEG") ) - { - Ram[6].Size+=xp->a_size; - if(xp->a_addra_addr; - } - - else if( EQ(xp->a_id, "CSEG") || EQ(xp->a_id, "GSINIT") || - EQ(xp->a_id, "GSFINAL") || EQ(xp->a_id, "HOME") ) - { - Rom.Size+=xp->a_size; - if(xp->a_addra_addr; - } - - else if (EQ(xp->a_id, "SSEG")) - { - Stack.Size+=xp->a_size; - if(xp->a_addra_addr; - } - - else if (EQ(xp->a_id, "XSEG") || EQ(xp->a_id, "XISEG")) - { - XRam.Size+=xp->a_size; - if(xp->a_addra_addr; - } - - else if (EQ(xp->a_id, "ISEG")) - { - IRam.Size+=xp->a_size; - if(xp->a_addra_addr; - } - xp=xp->a_ap; - } - - for(j=0; j<7; j++) - for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++) - dram[k]|=Ram[j].flag; /*Mark as used*/ - - for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++) - dram[k]|=IRam.flag; /*Mark as used*/ - - /*Compute the amount of unused memory in direct data Ram. This is the - gap between the last register bank or bit segment and the data segment.*/ - for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--); - Ram[5].Start=k+1; - Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/ - - /*Compute the data Ram totals*/ - for(j=0; j<7; j++) - { - if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start; - Ram[7].Size+=Ram[j].Size; - } - Total_Last=Ram[6].Size+Ram[6].Start-1; - - /*Report the Ram totals*/ - fprintf(of, "Direct Internal RAM:\n"); - fprintf(of, format, "Name", "Start", "End", "Size", "Max"); - - for(j=0; j<8; j++) - { - if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line); - if((j!=5) || (Ram[j].Size>0)) - { - sprintf(start, "0x%02x", Ram[j].Start); - if(Ram[j].Size==0) - end[0]=0;/*Empty string*/ - else - sprintf(end, "0x%02x", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1); - sprintf(size, "%5u", Ram[j].Size); - sprintf(max, "%5u", Ram[j].Max); - fprintf(of, format, Ram[j].Name, start, end, size, max); - } - } - - for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++) - { - if(dram[k]!=Ram[6].flag) - { - sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k); - REPORT_ERROR(buff, 1); - break; - } - } - - if(Ram[4].Size>Ram[4].Max) - { - k=Ram[4].Size-Ram[4].Max; - sprintf(buff, "Insufficient bit addressable memory. " - "%d byte%s short.\n", k, (k==1)?"":"s"); - REPORT_ERROR(buff, 1); - } - - if(Ram[5].Size!=0) - { - sprintf(buff, "%d bytes in DRAM wasted. " - "SDCC link could use: --data-loc 0x%02x\n", - Ram[5].Size, Ram[6].Start-Ram[5].Size); - REPORT_WARNING(buff, 1); - } - - if((Ram[6].Start+Ram[6].Size)>Ram[6].Max) - { - k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max; - sprintf(buff, "Insufficient DRAM memory. " - "%d byte%s short.\n", k, (k==1)?"":"s"); - REPORT_ERROR(buff, 1); - } - - /*Report the position of the begining of the stack*/ - fprintf(of, "\nStack starts at: 0x%02x", Stack.Start); - - /*Check that the stack pointer is landing in a safe place:*/ - if( (dram[Stack.Start] & 0x8000) == 0x8000 ) - { - fprintf(of, ".\n"); - sprintf(buff, "Stack set to unavailable memory.\n"); - REPORT_ERROR(buff, 1); - } - else if(dram[Stack.Start]) - { - fprintf(of, ".\n"); - sprintf(buff, "Stack overlaps area "); - REPORT_ERROR(buff, 1); - for(j=0; j<7; j++) - { - if(dram[Stack.Start]&Ram[j].flag) - { - sprintf(buff, "'%s'\n", Ram[j].Name); - break; - } - } - if(dram[Stack.Start]&IRam.flag) - { - sprintf(buff, "'%s'\n", IRam.Name); - } - REPORT_ERROR(buff, 0); - } - else - { - for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++); - fprintf(of, " with %d bytes available\n", k); - if (k(IRam.Max+0x80)) - { - sprintf(buff, "Insufficient INDIRECT RAM memory.\n"); - REPORT_ERROR(buff, 1); - } - if((XRam.Start+XRam.Size)>XRam.Max) - { - sprintf(buff, "Insufficient EXTERNAL RAM memory.\n"); - REPORT_ERROR(buff, 1); - } - if((Rom.Start+Rom.Size)>Rom.Max) - { - sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n"); - REPORT_ERROR(buff, 1); - } - - fclose(of); - return toreturn; -} diff --git a/as/mcs51/lkmain.c b/as/mcs51/lkmain.c index 899e70e1..1d8df7cf 100644 --- a/as/mcs51/lkmain.c +++ b/as/mcs51/lkmain.c @@ -244,7 +244,8 @@ char *argv[]; syminit(); if (dflag){ - dfp = afile("temp", "cdb", 1); + //dfp = afile("temp", "cdb", 1); + dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002 if (dfp == NULL) lkexit(1); } @@ -339,6 +340,9 @@ char *argv[]; reloc('E'); } } + //JCF: + CreateAOMF51(); + lkexit(lkerr); return 0; } @@ -378,14 +382,15 @@ int i; 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); } @@ -1111,7 +1116,7 @@ char *ft; } *p2++ = 0; if ((fp = fopen(fb, omode)) == NULL) { - if (strcmp(ft,"cdb")) { + if (strcmp(ft,"adb")) { fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); lkerr++; } diff --git a/as/mcs51/lkmem.c b/as/mcs51/lkmem.c new file mode 100644 index 00000000..2588276e --- /dev/null +++ b/as/mcs51/lkmem.c @@ -0,0 +1,339 @@ +/*------------------------------------------------------------------------- + lkmem.c - Create a memory summary file with extension .mem + + Written By - Jesus Calvino-Fraga, jesusc@ieee.org (2002) + + 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 the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-------------------------------------------------------------------------*/ + +#include +#include +#include +#include "aslink.h" + +int summary(struct area * areap) +{ + #define EQ(A,B) !strcmpi((A),(B)) + #define MIN_STACK 16 + #define REPORT_ERROR(A, H) \ + {\ + fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \ + fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \ + toreturn=1; \ + } + + #define REPORT_WARNING(A, H) \ + { \ + fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \ + fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \ + } + + char buff[128]; + int j, toreturn=0; + unsigned int Total_Last=0, k; + + struct area * xp; + FILE * of; + + /*Artifacts used for printing*/ + char start[8], end[8], size[8], max[8]; + char format[]=" %-16.16s %-7.7s %-7.7s %-7.7s %-7.7s\n"; + char line[]="---------------------"; + + typedef struct + { + unsigned int Start; + unsigned int Size; + unsigned int Max; + char Name[NCPS]; + unsigned int flag; + } _Mem; + + unsigned int dram[0x100]; + _Mem Ram[]={ + {0, 8, 8, "REG_BANK_0", 0x0001}, + {0x8, 8, 8, "REG_BANK_1", 0x0002}, + {0x10, 8, 8, "REG_BANK_2", 0x0004}, + {0x18, 8, 8, "REG_BANK_3", 0x0008}, + {0x20, 0, 16, "BSEG_BYTES", 0x0010}, + {0, 0, 128, "UNUSED", 0x0000}, + {0x7f, 0, 128, "DATA", 0x0020}, + {0, 0, 128, "TOTAL:", 0x0000} + }; + + _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080}; + _Mem Stack={0xff, 0, 1, "STACK", 0x0000}; + _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100}; + _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200}; + + if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/ + { + Ram[5].Max=0x80; + Ram[6].Max=0x80; + Ram[7].Max=0x80; + IRam.Max=0x80; + iram_size=0x100; + } + else if(iram_size<0x80) + { + Ram[5].Max=iram_size; + Ram[6].Max=iram_size; + Ram[7].Max=iram_size; + IRam.Max=0; + } + else + { + Ram[5].Max=0x80; + Ram[6].Max=0x80; + Ram[7].Max=0x80; + IRam.Max=iram_size-0x80; + } + + for(j=0; j<(int)iram_size; j++) dram[j]=0; + for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/ + + /* Open Memory Summary File*/ + of = afile(linkp->f_idp, "mem", 1); + if (of == NULL) + { + lkexit(1); + } + + xp=areap; + while (xp) + { + /**/ if (EQ(xp->a_id, "REG_BANK_0")) + { + Ram[0].Size=xp->a_size; + } + else if (EQ(xp->a_id, "REG_BANK_1")) + { + Ram[1].Size=xp->a_size; + } + else if (EQ(xp->a_id, "REG_BANK_2")) + { + Ram[2].Size=xp->a_size; + } + else if (EQ(xp->a_id, "REG_BANK_3")) + { + Ram[3].Size=xp->a_size; + } + else if (EQ(xp->a_id, "BSEG_BYTES")) + { + Ram[4].Size=xp->a_size; + } + else if ( EQ(xp->a_id, "DSEG") || EQ(xp->a_id, "OSEG") ) + { + Ram[6].Size+=xp->a_size; + if(xp->a_addra_addr; + } + + else if( EQ(xp->a_id, "CSEG") || EQ(xp->a_id, "GSINIT") || + EQ(xp->a_id, "GSFINAL") || EQ(xp->a_id, "HOME") ) + { + Rom.Size+=xp->a_size; + if(xp->a_addra_addr; + } + + else if (EQ(xp->a_id, "SSEG")) + { + Stack.Size+=xp->a_size; + if(xp->a_addra_addr; + } + + else if (EQ(xp->a_id, "XSEG") || EQ(xp->a_id, "XISEG")) + { + XRam.Size+=xp->a_size; + if(xp->a_addra_addr; + } + + else if (EQ(xp->a_id, "ISEG")) + { + IRam.Size+=xp->a_size; + if(xp->a_addra_addr; + } + xp=xp->a_ap; + } + + for(j=0; j<7; j++) + for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++) + dram[k]|=Ram[j].flag; /*Mark as used*/ + + for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++) + dram[k]|=IRam.flag; /*Mark as used*/ + + /*Compute the amount of unused memory in direct data Ram. This is the + gap between the last register bank or bit segment and the data segment.*/ + for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--); + Ram[5].Start=k+1; + Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/ + + /*Compute the data Ram totals*/ + for(j=0; j<7; j++) + { + if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start; + Ram[7].Size+=Ram[j].Size; + } + Total_Last=Ram[6].Size+Ram[6].Start-1; + + /*Report the Ram totals*/ + fprintf(of, "Direct Internal RAM:\n"); + fprintf(of, format, "Name", "Start", "End", "Size", "Max"); + + for(j=0; j<8; j++) + { + if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line); + if((j!=5) || (Ram[j].Size>0)) + { + sprintf(start, "0x%02x", Ram[j].Start); + if(Ram[j].Size==0) + end[0]=0;/*Empty string*/ + else + sprintf(end, "0x%02x", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1); + sprintf(size, "%5u", Ram[j].Size); + sprintf(max, "%5u", Ram[j].Max); + fprintf(of, format, Ram[j].Name, start, end, size, max); + } + } + + for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++) + { + if(dram[k]!=Ram[6].flag) + { + sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k); + REPORT_ERROR(buff, 1); + break; + } + } + + if(Ram[4].Size>Ram[4].Max) + { + k=Ram[4].Size-Ram[4].Max; + sprintf(buff, "Insufficient bit addressable memory. " + "%d byte%s short.\n", k, (k==1)?"":"s"); + REPORT_ERROR(buff, 1); + } + + if(Ram[5].Size!=0) + { + sprintf(buff, "%d bytes in DRAM wasted. " + "SDCC link could use: --data-loc 0x%02x\n", + Ram[5].Size, Ram[6].Start-Ram[5].Size); + REPORT_WARNING(buff, 1); + } + + if((Ram[6].Start+Ram[6].Size)>Ram[6].Max) + { + k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max; + sprintf(buff, "Insufficient DRAM memory. " + "%d byte%s short.\n", k, (k==1)?"":"s"); + REPORT_ERROR(buff, 1); + } + + /*Report the position of the begining of the stack*/ + fprintf(of, "\nStack starts at: 0x%02x", Stack.Start); + + /*Check that the stack pointer is landing in a safe place:*/ + if( (dram[Stack.Start] & 0x8000) == 0x8000 ) + { + fprintf(of, ".\n"); + sprintf(buff, "Stack set to unavailable memory.\n"); + REPORT_ERROR(buff, 1); + } + else if(dram[Stack.Start]) + { + fprintf(of, ".\n"); + sprintf(buff, "Stack overlaps area "); + REPORT_ERROR(buff, 1); + for(j=0; j<7; j++) + { + if(dram[Stack.Start]&Ram[j].flag) + { + sprintf(buff, "'%s'\n", Ram[j].Name); + break; + } + } + if(dram[Stack.Start]&IRam.flag) + { + sprintf(buff, "'%s'\n", IRam.Name); + } + REPORT_ERROR(buff, 0); + } + else + { + for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++); + fprintf(of, " with %d bytes available\n", k); + if (k(IRam.Max+0x80)) + { + sprintf(buff, "Insufficient INDIRECT RAM memory.\n"); + REPORT_ERROR(buff, 1); + } + if((XRam.Start+XRam.Size)>XRam.Max) + { + sprintf(buff, "Insufficient EXTERNAL RAM memory.\n"); + REPORT_ERROR(buff, 1); + } + if((Rom.Start+Rom.Size)>Rom.Max) + { + sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n"); + REPORT_ERROR(buff, 1); + } + + fclose(of); + return toreturn; +} -- 2.30.2