From: MaartenBrock Date: Wed, 14 Mar 2007 08:59:32 +0000 (+0000) Subject: * as/link/aslink.h: added LKOBJEXT X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=31b9b53110921b95ab99a245cd4ab5e12005aa27;p=fw%2Fsdcc * as/link/aslink.h: added LKOBJEXT * as/link/hc08/link_hc08.dsp, * as/link/hc08/Makefile.bcc, * as/link/hc08/Makefile.in, * as/link/mcs51/aslink.dsp, * as/link/mcs51/Makefile.bcc, * as/link/mcs51/Makefile.in: moved lkamof51.c and lkdata.c * as/link/hc08/lkaomf51.c, as/link/mcs51/lkaomf51.c, * as/link/lkaomf51.c: merged and moved * as/link/hc08/lkdata.c, as/link/mcs51/lkdata.c, * as/link/z80/lkdata.c, * as/link/lkdata.c: merged and moved * as/link/hc08/lkmain.c, * as/link/mcs51/lkmain.c: cosmetic changes * as/link/z80/lkeval.c, as/link/lkeval.c: merged * as/link/lklex.c: use LKOBJEXT * as/link/z80/lklist.c, as/link/lklist.c: merged, ANSI-fied functions, removed bubble-sorts * as/link/z80/lksym.c as/link/lksym.c: merged, ANSI-fied functions * as/link/z80/linkgbz80.dsp, * as/link/z80/linkz80.dsp, * as/link/z80/Makefile.in: added lkaomf51.c and lknoice.c, moved lkdata.c, lkeval.c, lkhead.c, lklex.x, lklist.c, lksym.c * as/link/z80/lkhead.c, * as/link/z80/lklex.c: deleted * as/link/z80/lklibr.c: moved LKOBJEXT to aslink.h * as/link/z80/lkmain.c: added copyfile() git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4690 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 9094995e..2ad89d66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2007-03-14 Maarten Brock + + * as/link/aslink.h: added LKOBJEXT + * as/link/hc08/link_hc08.dsp, + * as/link/hc08/Makefile.bcc, + * as/link/hc08/Makefile.in, + * as/link/mcs51/aslink.dsp, + * as/link/mcs51/Makefile.bcc, + * as/link/mcs51/Makefile.in: moved lkamof51.c and lkdata.c + * as/link/hc08/lkaomf51.c, as/link/mcs51/lkaomf51.c, + * as/link/lkaomf51.c: merged and moved + * as/link/hc08/lkdata.c, as/link/mcs51/lkdata.c, + * as/link/z80/lkdata.c, + * as/link/lkdata.c: merged and moved + * as/link/hc08/lkmain.c, + * as/link/mcs51/lkmain.c: cosmetic changes + * as/link/z80/lkeval.c, as/link/lkeval.c: merged + * as/link/lklex.c: use LKOBJEXT + * as/link/z80/lklist.c, as/link/lklist.c: merged, + ANSI-fied functions, removed bubble-sorts + * as/link/z80/lksym.c as/link/lksym.c: merged, + ANSI-fied functions + * as/link/z80/linkgbz80.dsp, + * as/link/z80/linkz80.dsp, + * as/link/z80/Makefile.in: added lkaomf51.c and lknoice.c, + moved lkdata.c, lkeval.c, lkhead.c, lklex.x, lklist.c, lksym.c + * as/link/z80/lkhead.c, + * as/link/z80/lklex.c: deleted + * as/link/z80/lklibr.c: moved LKOBJEXT to aslink.h + * as/link/z80/lkmain.c: added copyfile() + 2007-03-13 Jesus Calvino-Fraga * device/include/mcs51/P89LPC925.h: Added missing P1_6 and P1_7. @@ -19,7 +50,7 @@ 2007-03-13 Borut Razem - * src/Makefile.in, sim/ucsim/avr.src/Makefile.in, + * src/Makefile.in, sim/ucsim/avr.src/Makefile.in, sim/ucsim/hc08.src/Makefile.in, sim/ucsim/s51.src/Makefile.in, sim/ucsim/xa.src/Makefile.in, sim/ucsim/z80.src/Makefile.in, as/link/z80/Makefile.in, as/z80/Makefile.in: diff --git a/as/link/aslink.h b/as/link/aslink.h index 26be3fd3..086a7e11 100644 --- a/as/link/aslink.h +++ b/as/link/aslink.h @@ -94,6 +94,12 @@ #endif #endif +#ifdef SDK + #define LKOBJEXT "o" +#else /* SDK */ + #define LKOBJEXT "rel" +#endif /* SDK */ + /* * This file defines the format of the * relocatable binary file. diff --git a/as/link/hc08/Makefile.bcc b/as/link/hc08/Makefile.bcc index 51c73f5d..b64ff7bb 100644 --- a/as/link/hc08/Makefile.bcc +++ b/as/link/hc08/Makefile.bcc @@ -4,10 +4,10 @@ PRJDIR = ../.. !include $(PRJDIR)/Bcc.inc -LKOBJECTS = lkmain.obj lkarea.obj lkdata.obj \ - lkrloc.obj \ - lklibr.obj lkihx.obj lks19.obj \ - lkmem.obj lkaomf51.obj \ +LKOBJECTS = lkmain.obj lkarea.obj lkihx.obj \ + lklibr.obj lkrloc.obj lks19.obj \ + lkmem.obj \ + ../lkaomf51.obj ../lkdata.obj \ ../lkeval.obj ../lkhead.obj ../lklex.obj ../lklist.obj \ ../lknoice.obj ../lkstore.obj ../lksym.obj \ ../../strcmpi.obj diff --git a/as/link/hc08/Makefile.in b/as/link/hc08/Makefile.in index d066a787..9a3265a5 100644 --- a/as/link/hc08/Makefile.in +++ b/as/link/hc08/Makefile.in @@ -38,13 +38,13 @@ CFLAGS = @CFLAGS@ -Wall M_OR_MM = @M_OR_MM@ LDFLAGS = @LDFLAGS@ -LKOBJECTS = lkmain.o lkarea.o lkdata.o \ - lkrloc.o \ - lklibr.o lkihx.o lks19.o lkelf.o \ - lkmem.o lkaomf51.o \ - ../lkeval.o ../lkhead.o ../lklex.o ../lklist.o \ - ../lknoice.o ../lkstore.o ../lksym.o \ - ../../strcmpi.o +LKOBJECTS = lkmain.o lkarea.o lkihx.o \ + lklibr.o lkrloc.o lks19.o \ + lkelf.o lkmem.o \ + ../lkaomf51.o ../lkdata.o \ + ../lkeval.o ../lkhead.o ../lklex.o ../lklist.o \ + ../lknoice.o ../lkstore.o ../lksym.o \ + ../../strcmpi.o LKSOURCES = $(patsubst %.o,%.c,$(LKOBJECTS)) ASLINK = $(top_builddir)/bin/link-hc08$(EXEEXT) diff --git a/as/link/hc08/link_hc08.dsp b/as/link/hc08/link_hc08.dsp index ca05142d..01a8808f 100644 --- a/as/link/hc08/link_hc08.dsp +++ b/as/link/hc08/link_hc08.dsp @@ -7,19 +7,19 @@ CFG=link_hc08 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "link_hc08.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "link_hc08.mak" CFG="link_hc08 - Win32 Debug" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "link_hc08 - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "link_hc08 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -76,7 +76,7 @@ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\link-hc08.exe" /pdbtype:sept -!ENDIF +!ENDIF # Begin Target @@ -87,7 +87,7 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\lkaomf51.c +SOURCE=..\lkaomf51.c # End Source File # Begin Source File @@ -95,7 +95,7 @@ SOURCE=.\lkarea.c # End Source File # Begin Source File -SOURCE=.\lkdata.c +SOURCE=..\lkdata.c # End Source File # Begin Source File diff --git a/as/link/hc08/lkaomf51.c b/as/link/hc08/lkaomf51.c deleted file mode 100644 index f81a96a9..00000000 --- a/as/link/hc08/lkaomf51.c +++ /dev/null @@ -1,980 +0,0 @@ -/*------------------------------------------------------------------------- - 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 -#include "aslink.h" - -#define EQ(A,B) !strcmp((A),(B)) -#define MEMSIZE 0x10000 -//#define DODUMP 1 - -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; -#if 0 -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?*/ -}; -#endif -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) && (!rflag)) - { - 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); - - /*Check if this filename is already in*/ - for(j=0; j=0)?procedure[symbol[j].Procedure].name:"GLOBAL", - symbol[j].Address, - k<6?UsageTypeName[k]:"???"); - } - - 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); -} -#endif - -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); - lkexit(1); - } - - 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 (unsigned char hex_digit) -{ - if (isdigit(hex_digit)) - return hex_digit-'0'; - else - return toupper(hex_digit)-'A'+10; -} - -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; j -#include -#include "aslink.h" - -/*)Module lkdata.c - * - * The module lkdata contains the global variables - * and structures used in the linker aslink. - */ - -/* - * Definitions for all Global Variables - */ - -char *_abs_ = { ". .ABS." }; - -int lkerr; /* Linker error flag - */ -char *ip; /* Pointer into the REL file text line in ib[] - */ -char ib[NINPUT]; /* REL file text line - */ -char *rp; /* pointer into the LST file - * text line in rb[] - */ -char rb[NINPUT]; /* LST file text line being - * address relocated - */ - -char sdccopt[NINPUT]=""; -char sdccopt_module[NINPUT]=""; -char curr_module[NINPUT]=""; - -int dflag; /* Debug information output flag - */ -int oflag; /* Output file type flag - */ -int mflag; /* Map output flag - */ -int sflag; /* JCF: Memory usage output flag - */ -int aflag; /* Overlapping area warning flag - */ -int jflag; /* NoICE output flag - */ -int xflag; /* Map file radix type flag - */ -int pflag; /* print linker command file flag - */ -int uflag; /* Listing relocation flag - */ -int rflag; /* Extended linear address record flag. - */ -int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -int line; /* current line number - */ -int page; /* current page number - */ -int lop; /* current line number on page - */ -int pass; /* linker pass number - */ -int rtcnt; /* count of elements in the - * rtval[] and rtflg[] arrays - */ -Addr_T rtval[NTXT]; /* data associated with relocation - */ -int rtflg[NTXT]; /* indicates if rtval[] value is - * to be sent to the output file. - * (always set in this linker) - */ -int hilo; /* REL file byte ordering - */ -int gline; /* LST file relocation active - * for current line - */ -int gcntr; /* LST file relocation active - * counter - */ -Addr_T iram_size; /* internal ram size - */ -long xram_size=-1; /* external ram size - */ -long code_size=-1; /* code size - */ - -/* - * The structure lfile contains a pointer to a - * file specification string, the file type, and - * a link to the next lfile structure. - * - * struct lfile - * { - * struct lfile *f_flp; lfile link - * int f_type; File type - * char *f_idp; Pointer to file spec - * }; - */ -struct lfile *filep; /* The pointers (lfile *) filep, - * (lfile *) cfp, and (FILE *) sfp - * are used in conjunction with - * the routine lk_getline() to read - * asmlnk commands from - * (1) the standard input or - * (2) or a command file - * and to read the REL files - * sequentially as defined by the - * asmlnk input commands. - * - * The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - */ -struct lfile *cfp; /* The pointer *cfp points to the - * current lfile structure - */ -struct lfile *startp;/* asmlnk startup file structure - */ -struct lfile *linkp; /* pointer to first lfile structure - * containing an input REL file - * specification - */ -struct lfile *lfp; /* pointer to current lfile structure - * being processed by parse() - */ -FILE *ofp; /* Output file handle - * for word formats - */ -FILE *mfp; /* Map output file handle - */ -FILE *jfp; /* NoICE output file handle - */ -FILE *rfp; /* File handle for output - * address relocated ASxxxx - * listing file - */ -FILE *sfp; /* The file handle sfp points to the - * currently open file - */ -FILE *tfp; /* File handle for input - * ASxxxx listing file - */ -FILE *dfp = NULL ; /* - * File handle for debug - * information output file - */ -/* - * The structures of head, area, areax, and sym are created - * as the REL files are read during the first pass of the - * linker. The struct head is created upon encountering a - * H directive in the REL file. The structure contains a - * link to a link file structure (struct lfile) which describes - * the file containing the H directive, the number of data/code - * areas contained in this header segment, the number of - * symbols referenced/defined in this header segment, a pointer - * to an array of pointers to areax structures (struct areax) - * created as each A directive is read, and a pointer to an - * array of pointers to symbol structures (struct sym) for - * all referenced/defined symbols. As H directives are read - * from the REL files a linked list of head structures is - * created by placing a link to the new head structure - * in the previous head structure. - * - * struct head - * { - * struct head *h_hp; Header link - * struct lfile *h_lfile; Associated file - * int h_narea; # of areas - * struct areax **a_list; Area list - * int h_nglob; # of global symbols - * struct sym **s_list; Global symbol list - * char m_id[NCPS]; Module name - * }; - */ -struct head *headp; /* The pointer to the first - * head structure of a linked list - */ -struct head *hp; /* Pointer to the current - * head structure - */ - -/* - * A structure area is created for each 'unique' data/code - * area definition found as the REL files are read. The - * struct area contains the name of the area, a flag byte - * which contains the area attributes (REL/CON/OVR/ABS), - * an area subtype (not used in this assembler), and the - * area base address and total size which will be filled - * in at the end of the first pass through the REL files. - * As A directives are read from the REL files a linked - * list of unique area structures is created by placing a - * link to the new area structure in the previous area structure. - * - * struct area - * { - * struct area *a_ap; Area link - * struct areax *a_axp; Area extension link - * Addr_T a_addr; Beginning address of area - * Addr_T a_size; Total size of the area - * char a_type; Area subtype - * char a_flag; Flag byte - * char a_id[NCPS]; Name - * }; - */ -struct area *areap; /* The pointer to the first - * area structure of a linked list - */ -struct area *ap; /* Pointer to the current - * area structure - */ - -/* - * An areax structure is created for every A directive found - * while reading the REL files. The struct areax contains a - * link to the 'unique' area structure referenced by the A - * directive and to the head structure this area segment is - * a part of. The size of this area segment as read from the - * A directive is placed in the areax structure. The beginning - * address of this segment will be filled in at the end of the - * first pass through the REL files. As A directives are read - * from the REL files a linked list of areax structures is - * created for each unique area. The final areax linked - * list has at its head the 'unique' area structure linked - * to the linked areax structures (one areax structure for - * each A directive for this area). - * - * struct areax - * { - * struct areax *a_axp; Area extension link - * struct area *a_bap; Base area link - * struct head *a_bhp; Base header link - * Addr_T a_addr; Beginning address of section - * Addr_T a_size; Size of the area in section - * }; - */ -struct areax *axp; /* Pointer to the current - * areax structure - */ - -/* - * A sym structure is created for every unique symbol - * referenced/defined while reading the REL files. The - * struct sym contains the symbol's name, a flag value - * (not used in this linker), a symbol type denoting - * referenced/defined, and an address which is loaded - * with the relative address within the area in which - * the symbol was defined. The sym structure also - * contains a link to the area where the symbol was defined. - * The sym structures are linked into linked lists using - * the symbol link element. - * - * struct sym - * { - * struct sym *s_sp; Symbol link - * struct areax *s_axp; Symbol area link - * char s_type; Symbol subtype - * char s_flag; Flag byte - * Addr_T s_addr; Address - * char *s_id; Name (JLH) - * }; - */ -struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -/* - * The struct base contains a pointer to a - * base definition string and a link to the next - * base structure. - * - * struct base - * { - * struct base *b_base; Base link - * char *b_strp; String pointer - * }; - */ -struct base *basep; /* The pointer to the first - * base structure - */ -struct base *bsp; /* Pointer to the current - * base structure - */ - -/* - * The struct globl contains a pointer to a - * global definition string and a link to the next - * global structure. - * - * struct globl - * { - * struct globl *g_globl; Global link - * char *g_strp; String pointer - * }; - */ -struct globl *globlp;/* The pointer to the first - * globl structure - */ -struct globl *gsp; /* Pointer to the current - * globl structure - */ - -/* - * A structure sdp is created for each 'unique' paged - * area definition found as the REL files are read. - * As P directives are read from the REL files a linked - * list of unique sdp structures is created by placing a - * link to the new sdp structure in the previous area structure. - * - * struct sdp - * { - * struct area *s_area; Paged Area link - * struct areax *s_areax; Paged Area Extension Link - * Addr_T s_addr; Page address offset - * }; - */ -struct sdp sdp; /* Base Page Structure */ - -/* - * The structure rerr is loaded with the information - * required to report an error during the linking - * process. The structure contains an index value - * which selects the areax structure from the header - * areax structure list, a mode value which selects - * symbol or area relocation, the base address in the - * area section, an area/symbol list index value, and - * an area/symbol offset value. - * - * struct rerr - * { - * int aindex; Linking area - * int mode; Relocation mode - * Addr_T rtbase; Base address in section - * int rindex; Area/Symbol reloaction index - * Addr_T rval; Area/Symbol offset value - * }; - */ -struct rerr rerr; /* Structure containing the - * linker error information - */ - -/* - * The structure lbpath is created for each library - * path specification input by the -k option. The - * lbpath structures are linked into a list using - * the next link element. - * - * struct lbpath { - * struct lbpath *next; - * char *path; - * }; - */ -struct lbpath *lbphead; /* pointer to the first - * library path structure - */ - -/* - * The structure lbname is created for all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file. The element path points to - * the path string, element libfil points to the library - * file string, and the element libspc is the concatenation - * of the valid path and libfil strings. - * - * The lbpath structures are linked into a list - * using the next link element. - * - * Each library file contains a list of object files - * that are contained in the particular library. e.g.: - * - * \iolib\termio - * \inilib\termio - * - * Only one specification per line is allowed. - * - * struct lbname { - * struct lbname *next; - * char *path; - * char *libfil; - * char *libspc; - * }; - */ -struct lbname *lbnhead; /* pointer to the first - * library name structure - */ - -/* - * The function fndsym() searches through all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file for a symbol definition. - * - * The structure lbfile is created for the first library - * object file which contains the definition for the - * specified undefined symbol. - * - * The element libspc points to the library file path specification - * and element relfil points to the object file specification string. - * The element filspc is the complete path/file specification for - * the library file to be imported into the linker. The - * file specicifation may be formed in one of two ways: - * - * (1) If the library file contained an absolute - * path/file specification then this becomes filspc. - * (i.e. C:\...) - * - * (2) If the library file contains a relative path/file - * specification then the concatenation of the path - * and this file specification becomes filspc. - * (i.e. \...) - * - * The lbpath structures are linked into a list - * using the next link element. - * - * struct lbfile { - * struct lbfile *next; - * char *libspc; - * char *relfil; - * char *filspc; - * }; - */ -struct lbfile *lbfhead; /* pointer to the first - * library file structure - */ - -/* - * array of character types, one per - * ASCII character - */ -unsigned char ctype[128] = { -/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, -/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, -/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, -/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, -/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, -/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, -/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC -}; - -/* - * an array of characters which - * perform the case translation function - */ -#if CASE_SENSITIVE -#else -char ccase[128] = { -/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', -/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' -}; -#endif diff --git a/as/link/hc08/lkmain.c b/as/link/hc08/lkmain.c index 9b37da68..e2aa0d63 100644 --- a/as/link/hc08/lkmain.c +++ b/as/link/hc08/lkmain.c @@ -10,7 +10,7 @@ * * 31-Oct-97 JLH: * - add jflag and jfp to control NoICE output file genration - * 3-Nov-97 JLH: + * 3-Nov-97 JLH: * - use a_type == 0 as "virgin area" flag: set == 1 if -b */ @@ -91,7 +91,7 @@ void Areas51 (void) ip=rel[j]; link_main(); } - + /*Set the start address of the default areas:*/ for(ap=areap; ap; ap=ap->a_ap) { @@ -215,7 +215,7 @@ main(int argc, char *argv[]) case 'F': startp->f_type = F_LNK; break; - + case 'n': case 'N': pflag = 0; @@ -263,12 +263,12 @@ main(int argc, char *argv[]) usage(); syminit(); - + if (dflag){ //dfp = afile("temp", "cdb", 1); - SaveLinkedFilePath(linkp->f_idp); //Must be the first one... + SaveLinkedFilePath(linkp->f_idp); //Must be the first one... dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002 - if (dfp == NULL) + if (dfp == NULL) lkexit(1); } @@ -278,7 +278,7 @@ main(int argc, char *argv[]) filep = linkp; hp = NULL; radix = 10; - + Areas51(); /*JCF: Create the default 8051 areas in the right order*/ while (lk_getline()) { @@ -865,7 +865,7 @@ parse() case 'z': case 'Z': - dflag = 1; + dflag = 1; return(0); default: fprintf(stderr, "Invalid option\n"); @@ -1051,7 +1051,7 @@ gblsav() gsp->g_strp = (char *) new (strlen(ip)+1); strcpy(gsp->g_strp, ip); } - + /*)Function VOID setgbl() * * The function setgbl() scans the global variable lines in the @@ -1162,7 +1162,7 @@ afile(char *fn, char *ft, int wf) char fb[PATH_MAX]; char *omode; int i; - + switch (wf) { case 0: omode = "r"; break; case 1: omode = "w"; break; @@ -1192,7 +1192,7 @@ afile(char *fn, char *ft, int wf) strcat(fb, "."); strcat(fb, strlen(ft)?ft:"rel"); } - + fp = fopen(fb, omode); if (fp==NULL) { @@ -1371,27 +1371,27 @@ usage() lkexit(1); } -/*)Function VOID copyfile() - * - * FILE *dest destination file - * FILE *src source file +/*)Function VOID copyfile() + * + * FILE *dest destination file + * FILE *src source file * * function will copy source file to destination file * * - * functions called: - * int fgetc() c_library - * int fputc() c_library + * functions called: + * int fgetc() c_library + * int fputc() c_library * - * side effects: - * none + * side effects: + * none */ VOID copyfile (dest,src) FILE *src,*dest ; -{ +{ int ch; - while ((ch = fgetc(src)) != EOF) { - fputc(ch,dest); + while ((ch = fgetc(src)) != EOF) { + fputc(ch,dest); } } diff --git a/as/link/lkaomf51.c b/as/link/lkaomf51.c new file mode 100644 index 00000000..7e650317 --- /dev/null +++ b/as/link/lkaomf51.c @@ -0,0 +1,987 @@ +/*------------------------------------------------------------------------- + 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 +#include "aslink.h" + +#define EQ(A,B) !strcmp((A),(B)) +#define MEMSIZE 0x10000 +//#define DODUMP 1 + +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; +#if 0 +typedef struct +{ + char * name; + int usage; +} +_UsageType; + +_UsageType UsageType[]= +{ + {"CSEG", 0}, + {"GSINIT", 0}, + {"GSINIT0", 0}, + {"GSINIT1", 0}, + {"GSINIT2", 0}, + {"GSINIT3", 0}, + {"GSINIT4", 0}, + {"GSINIT5", 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?*/ +}; +#endif +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) && (!rflag)) + { + 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); + + /*Check if this filename is already in*/ + for(j=0; j=0)?procedure[symbol[j].Procedure].name:"GLOBAL", + symbol[j].Address, + k<6?UsageTypeName[k]:"???"); + } + + 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); +} +#endif + +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); + lkexit(1); + } + + 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 (unsigned char hex_digit) +{ + if (isdigit (hex_digit)) + return hex_digit-'0'; + else + return toupper (hex_digit)-'A'+10; +} + +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; j +#include +#include "aslink.h" + +/*)Module lkdata.c + * + * The module lkdata contains the global variables + * and structures used in the linker aslink. + */ + +/* + * Definitions for all Global Variables + */ + +char *_abs_ = { ". .ABS." }; + +int lkerr; /* Linker error flag + */ +char *ip; /* Pointer into the REL file text line in ib[] + */ +char ib[NINPUT]; /* REL file text line + */ +char *rp; /* pointer into the LST file + * text line in rb[] + */ +char rb[NINPUT]; /* LST file text line being + * address relocated + */ + +char sdccopt[NINPUT]=""; +char sdccopt_module[NINPUT]=""; +char curr_module[NINPUT]=""; + +int dflag; /* Debug information output flag + */ +int oflag; /* Output file type flag + */ +int mflag; /* Map output flag + */ +int sflag; /* JCF: Memory usage output flag + */ +int packflag=0; /* JCF: Pack internal memory flag + */ +int stacksize=0; /* JCF: Stack size + */ +int aflag; /* Overlapping area warning flag + */ +int jflag; /* NoICE output flag + */ +int symflag; /* no$gmb .sym output flag + */ +int xflag; /* Map file radix type flag + */ +int pflag; /* print linker command file flag + */ +int uflag; /* Listing relocation flag + */ +int rflag; /* Extended linear address record flag. + */ +int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +int line; /* current line number + */ +int page; /* current page number + */ +int lop; /* current line number on page + */ +int pass; /* linker pass number + */ +int rtcnt; /* count of elements in the + * rtval[] and rtflg[] arrays + */ +Addr_T rtval[NTXT]; /* data associated with relocation + */ +int rtflg[NTXT]; /* indicates if rtval[] value is + * to be sent to the output file. + * (always set in this linker) + */ +int hilo; /* REL file byte ordering + */ +int gline; /* LST file relocation active + * for current line + */ +int gcntr; /* LST file relocation active + * counter + */ +Addr_T iram_size; /* internal ram size + */ +long xram_size=-1; /* external ram size + */ +long code_size=-1; /* code size + */ + +/* + * The structure lfile contains a pointer to a + * file specification string, the file type, and + * a link to the next lfile structure. + * + * struct lfile + * { + * struct lfile *f_flp; lfile link + * int f_type; File type + * char *f_idp; Pointer to file spec + * }; + */ +struct lfile *filep; /* The pointers (lfile *) filep, + * (lfile *) cfp, and (FILE *) sfp + * are used in conjunction with + * the routine lk_getline() to read + * asmlnk commands from + * (1) the standard input or + * (2) or a command file + * and to read the REL files + * sequentially as defined by the + * asmlnk input commands. + * + * The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + */ +struct lfile *cfp; /* The pointer *cfp points to the + * current lfile structure + */ +struct lfile *startp;/* asmlnk startup file structure + */ +struct lfile *linkp; /* pointer to first lfile structure + * containing an input REL file + * specification + */ +struct lfile *lfp; /* pointer to current lfile structure + * being processed by parse() + */ +FILE *ofp; /* Output file handle + * for word formats + */ +FILE *mfp; /* Map output file handle + */ +FILE *jfp; /* NoICE output file handle + */ +FILE *rfp; /* File handle for output + * address relocated ASxxxx + * listing file + */ +FILE *sfp; /* The file handle sfp points to the + * currently open file + */ +FILE *tfp; /* File handle for input + * ASxxxx listing file + */ +FILE *dfp = NULL ; /* + * File handle for debug + * information output file + */ +/* + * The structures of head, area, areax, and sym are created + * as the REL files are read during the first pass of the + * linker. The struct head is created upon encountering a + * H directive in the REL file. The structure contains a + * link to a link file structure (struct lfile) which describes + * the file containing the H directive, the number of data/code + * areas contained in this header segment, the number of + * symbols referenced/defined in this header segment, a pointer + * to an array of pointers to areax structures (struct areax) + * created as each A directive is read, and a pointer to an + * array of pointers to symbol structures (struct sym) for + * all referenced/defined symbols. As H directives are read + * from the REL files a linked list of head structures is + * created by placing a link to the new head structure + * in the previous head structure. + * + * struct head + * { + * struct head *h_hp; Header link + * struct lfile *h_lfile; Associated file + * int h_narea; # of areas + * struct areax **a_list; Area list + * int h_nglob; # of global symbols + * struct sym **s_list; Global symbol list + * char m_id[NCPS]; Module name + * }; + */ +struct head *headp; /* The pointer to the first + * head structure of a linked list + */ +struct head *hp; /* Pointer to the current + * head structure + */ + +/* + * A structure area is created for each 'unique' data/code + * area definition found as the REL files are read. The + * struct area contains the name of the area, a flag byte + * which contains the area attributes (REL/CON/OVR/ABS), + * an area subtype (not used in this assembler), and the + * area base address and total size which will be filled + * in at the end of the first pass through the REL files. + * As A directives are read from the REL files a linked + * list of unique area structures is created by placing a + * link to the new area structure in the previous area structure. + * + * struct area + * { + * struct area *a_ap; Area link + * struct areax *a_axp; Area extension link + * Addr_T a_addr; Beginning address of area + * Addr_T a_size; Total size of the area + * char a_type; Area subtype + * char a_flag; Flag byte + * char a_id[NCPS]; Name + * }; + */ +struct area *areap; /* The pointer to the first + * area structure of a linked list + */ +struct area *ap; /* Pointer to the current + * area structure + */ + +/* + * An areax structure is created for every A directive found + * while reading the REL files. The struct areax contains a + * link to the 'unique' area structure referenced by the A + * directive and to the head structure this area segment is + * a part of. The size of this area segment as read from the + * A directive is placed in the areax structure. The beginning + * address of this segment will be filled in at the end of the + * first pass through the REL files. As A directives are read + * from the REL files a linked list of areax structures is + * created for each unique area. The final areax linked + * list has at its head the 'unique' area structure linked + * to the linked areax structures (one areax structure for + * each A directive for this area). + * + * struct areax + * { + * struct areax *a_axp; Area extension link + * struct area *a_bap; Base area link + * struct head *a_bhp; Base header link + * Addr_T a_addr; Beginning address of section + * Addr_T a_size; Size of the area in section + * }; + */ +struct areax *axp; /* Pointer to the current + * areax structure + */ + +/* + * A sym structure is created for every unique symbol + * referenced/defined while reading the REL files. The + * struct sym contains the symbol's name, a flag value + * (not used in this linker), a symbol type denoting + * referenced/defined, and an address which is loaded + * with the relative address within the area in which + * the symbol was defined. The sym structure also + * contains a link to the area where the symbol was defined. + * The sym structures are linked into linked lists using + * the symbol link element. + * + * struct sym + * { + * struct sym *s_sp; Symbol link + * struct areax *s_axp; Symbol area link + * char s_type; Symbol subtype + * char s_flag; Flag byte + * Addr_T s_addr; Address + * char *s_id; Name (JLH) + * }; + */ +struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +/* + * The struct base contains a pointer to a + * base definition string and a link to the next + * base structure. + * + * struct base + * { + * struct base *b_base; Base link + * char *b_strp; String pointer + * }; + */ +struct base *basep; /* The pointer to the first + * base structure + */ +struct base *bsp; /* Pointer to the current + * base structure + */ + +/* + * The struct globl contains a pointer to a + * global definition string and a link to the next + * global structure. + * + * struct globl + * { + * struct globl *g_globl; Global link + * char *g_strp; String pointer + * }; + */ +struct globl *globlp;/* The pointer to the first + * globl structure + */ +struct globl *gsp; /* Pointer to the current + * globl structure + */ + +/* + * A structure sdp is created for each 'unique' paged + * area definition found as the REL files are read. + * As P directives are read from the REL files a linked + * list of unique sdp structures is created by placing a + * link to the new sdp structure in the previous area structure. + * + * struct sdp + * { + * struct area *s_area; Paged Area link + * struct areax *s_areax; Paged Area Extension Link + * Addr_T s_addr; Page address offset + * }; + */ +struct sdp sdp; /* Base Page Structure */ + +/* + * The structure rerr is loaded with the information + * required to report an error during the linking + * process. The structure contains an index value + * which selects the areax structure from the header + * areax structure list, a mode value which selects + * symbol or area relocation, the base address in the + * area section, an area/symbol list index value, and + * an area/symbol offset value. + * + * struct rerr + * { + * int aindex; Linking area + * int mode; Relocation mode + * Addr_T rtbase; Base address in section + * int rindex; Area/Symbol reloaction index + * Addr_T rval; Area/Symbol offset value + * }; + */ +struct rerr rerr; /* Structure containing the + * linker error information + */ + +/* + * The structure lbpath is created for each library + * path specification input by the -k option. The + * lbpath structures are linked into a list using + * the next link element. + * + * struct lbpath { + * struct lbpath *next; + * char *path; + * }; + */ +struct lbpath *lbphead; /* pointer to the first + * library path structure + */ + +/* + * The structure lbname is created for all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file. The element path points to + * the path string, element libfil points to the library + * file string, and the element libspc is the concatenation + * of the valid path and libfil strings. + * + * The lbpath structures are linked into a list + * using the next link element. + * + * Each library file contains a list of object files + * that are contained in the particular library. e.g.: + * + * \iolib\termio + * \inilib\termio + * + * Only one specification per line is allowed. + * + * struct lbname { + * struct lbname *next; + * char *path; + * char *libfil; + * char *libspc; + * }; + */ +struct lbname *lbnhead; /* pointer to the first + * library name structure + */ + +/* + * The function fndsym() searches through all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file for a symbol definition. + * + * The structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. + * + * The element libspc points to the library file path specification + * and element relfil points to the object file specification string. + * The element filspc is the complete path/file specification for + * the library file to be imported into the linker. The + * file specicifation may be formed in one of two ways: + * + * (1) If the library file contained an absolute + * path/file specification then this becomes filspc. + * (i.e. C:\...) + * + * (2) If the library file contains a relative path/file + * specification then the concatenation of the path + * and this file specification becomes filspc. + * (i.e. \...) + * + * The lbpath structures are linked into a list + * using the next link element. + * + * struct lbfile { + * struct lbfile *next; + * char *libspc; + * char *relfil; + * char *filspc; + * }; + */ +struct lbfile *lbfhead; /* pointer to the first + * library file structure + */ + +/* + * array of character types, one per + * ASCII character + */ +unsigned char ctype[128] = { +/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, +/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, +/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, +/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, +/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, +/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*X*/ LETTER, LETTER, LETTER, BINOP, ETC, ETC, BINOP, LETTER, +/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC +}; + +/* + * an array of characters which + * perform the case translation function + */ +#if CASE_SENSITIVE +#else +char ccase[128] = { +/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', +/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', +/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', +/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', +/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', +/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', +/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', +/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', +/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', +/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' +}; +#endif diff --git a/as/link/lkeval.c b/as/link/lkeval.c index 90df0031..230c40ba 100644 --- a/as/link/lkeval.c +++ b/as/link/lkeval.c @@ -302,6 +302,7 @@ term() return(symval(sp)); } } + /* Shouldn't get here. */ return(0); } diff --git a/as/link/lklex.c b/as/link/lklex.c index 73093ce9..bac4a3b7 100644 --- a/as/link/lklex.c +++ b/as/link/lklex.c @@ -507,23 +507,23 @@ loop: if (pflag && cfp && cfp->f_type == F_STD) sfp = afile(fid, "lnk", 0); } else if (ftype == F_REL) { - sfp = afile(fid, "rel", 0); + sfp = afile(fid, LKOBJEXT, 0); /* if a .cdb file exists then copy it over */ if (dflag && sfp && dfp && pass == 0) { - FILE *xfp = afile(fid,"adb",0); //JCF: Nov 30, 2002 - if (xfp) { - copyfile(dfp,xfp); - fclose(xfp); - } + 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); - tfp = NULL; - } - } + SaveLinkedFilePath(fid); //Save the linked path for aomf51 + if ((tfp = afile(fid, "lst", 0)) != NULL) { + if ((rfp = afile(fid, "rst", 1)) == NULL) { + fclose(tfp); + tfp = NULL; + } + } } gline = 1; } else { diff --git a/as/link/lklist.c b/as/link/lklist.c index 5325ec89..68d041c1 100644 --- a/as/link/lklist.c +++ b/as/link/lklist.c @@ -152,10 +152,8 @@ static int _cmpSymByAddr(const void *p1, const void *p2) * areax * oxp pointer to an area extension structure * int c character value * int i loop counter - * int j bubble sort update status * char * ptr pointer to an id string * int nmsym number of symbols in area - * Addr_T a0 temporary * Addr_T ai temporary * Addr_T aj temporary * sym * sp pointer to a symbol structure @@ -180,21 +178,39 @@ static int _cmpSymByAddr(const void *p1, const void *p2) */ VOID -lstarea(xp) -struct area *xp; +lstarea(struct area *xp) { register struct areax *oxp; register int i; - /* int j; */ register char *ptr; int nmsym; - /* Addr_T a0; */ Addr_T ai, aj; struct sym *sp; struct sym **p; int memPage; putc('\n', mfp); + + /* + * Find number of symbols in area + */ + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + if (nmsym == 0) { + return; + } + if (xflag == 0) { fprintf(mfp, "Hexadecimal\n\n"); } else @@ -265,27 +281,6 @@ struct area *xp; if (ai || aj) { fprintf(mfp, " Error"); } } - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - if (nmsym == 0) { - putc('\n', mfp); - return; - } - /* * Allocate space for an array of pointers to symbols * and load array. @@ -310,29 +305,7 @@ struct area *xp; oxp = oxp->a_axp; } -#if 0 - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } -#else qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr); -#endif /* * Symbol Table Output @@ -397,10 +370,8 @@ struct area *xp; * areax * oxp pointer to an area extension structure * int c character value * int i loop counter - * int j bubble sort update status * char * ptr pointer to an id string * int nmsym number of symbols in area - * Addr_T a0 temporary * Addr_T ai temporary * Addr_T aj temporary * sym * sp pointer to a symbol structure @@ -425,17 +396,16 @@ struct area *xp; */ VOID -lstarea(xp) -struct area *xp; +lstarea(struct area *xp) { register struct areax *oxp; - register c, i, j; + register int c, i; register char *ptr; int nmsym; - Addr_T a0, ai, aj; + Addr_T ai, aj; struct sym *sp; struct sym **p; - int page; + int page; putc('\n', mfp); slew(mfp); @@ -547,29 +517,7 @@ struct area *xp; oxp = oxp->a_axp; } -#if 0 - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } -#else qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr); -#endif /* * Symbol Table Output @@ -591,7 +539,7 @@ struct area *xp; fprintf(mfp, " %05u ", aj); } ptr = &sp->s_id[0]; - fprintf(mfp, "%s", ptr ); + fprintf(mfp, "%*s", NCPS, ptr ); /* NoICE output of symbol */ if (jflag) DefineNoICE( ptr, aj, memPage ); @@ -602,6 +550,91 @@ struct area *xp; } #endif +#ifdef SDK +VOID lstareatosym(struct area *xp) +{ + /* Output the current area symbols to a NO$GMB .sym file */ + register struct areax *oxp; + register int i; + int nmsym; + Addr_T a0; + struct sym *sp; + struct sym **p; + + /* + * Find number of symbols in area + */ + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + + /* + * Symbol Table Output + */ + if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { + /* Dont worry about any area information */ + fprintf(mfp, "; Area: %s\n", xp->a_id ); + if (nmsym>0) { + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) + == NULL) { + fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); + return; + } + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) { + p[nmsym++] = sp; + } + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + + qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr); + + i = 0; + while (i < nmsym) { + /* no$gmb requires the symbol names to be less than 32 chars long. Truncate. */ + char name[32]; + strncpy(name, p[i]->s_id, 31); + name[31] = '\0'; + if ((strncmp("l__", name, 3)!=0)&&(strchr(name,' ')==NULL)) { + a0=p[i]->s_addr + p[i]->s_axp->a_addr; + if (a0>0x7FFFU) { + /* Not inside the ROM, so treat as being in bank zero */ + fprintf(mfp, "00:%04X %s\n", a0, name); + } + else { + fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, name); + } + } + i++; + } + free(p); + } + } +} +#endif + /*)Function VOID lkulist(i) * * int i i # 0 process LST to RST file @@ -644,8 +677,7 @@ struct area *xp; */ VOID -lkulist(i) -int i; +lkulist(int i) { Addr_T pc; @@ -747,8 +779,7 @@ int i; */ VOID -lkalist(pc) -Addr_T pc; +lkalist(Addr_T pc) { char str[8]; int i; @@ -874,9 +905,7 @@ loop: if (tfp == NULL) */ VOID -lkglist(pc,v) -Addr_T pc; -int v; +lkglist(Addr_T pc, int v) { char str[8]; int i; @@ -1085,14 +1114,12 @@ loop: if (tfp == NULL) */ int -dgt(rdx, str, n) -int rdx, n; -char *str; +dgt(int rdx, char *str, int n) { int i; for (i=0; is_type & S_DEF && tsp->s_addr != i) { - fprintf(stderr, "Multiple definition of %8s\n", id); + fprintf(stderr, "Multiple definition of %s\n", id); lkerr++; } tsp->s_type |= S_DEF; @@ -160,7 +159,7 @@ newsym() tsp->s_addr = i; tsp->s_axp = axp; } else { - fprintf(stderr, "Invalid symbol type %c for %8s\n", c, id); + fprintf(stderr, "Invalid symbol type %c for %s\n", c, id); lkexit(1); } /* @@ -180,6 +179,8 @@ newsym() } fprintf(stderr, "Header symbol list overflow\n"); lkexit(1); + + /* Never reached */ return(0); } @@ -215,8 +216,7 @@ newsym() */ struct sym * -lkpsym(id, f) -char *id; +lkpsym(char *id, int f) { register struct sym *sp; register int h; @@ -259,8 +259,7 @@ char *id; */ Addr_T -symval(tsp) -register struct sym *tsp; +symval(register struct sym *tsp) { register Addr_T val; @@ -299,8 +298,7 @@ register struct sym *tsp; */ VOID -symdef(fp) -FILE *fp; +symdef(FILE *fp) { register struct sym *sp; register int i; @@ -348,25 +346,23 @@ FILE *fp; */ VOID -symmod(fp, tsp) -FILE *fp; -struct sym *tsp; +symmod(FILE *fp, struct sym *tsp) { register int i; struct sym **p; if ((hp = headp) != NULL) { - while(hp) { - p = hp->s_list; - for (i=0; ih_nglob; ++i) { - if (p[i] == tsp) { - fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id); - fprintf(fp, "referenced by module '%s'\n", hp->m_id); - lkerr++; - } + while(hp) { + p = hp->s_list; + for (i=0; ih_nglob; ++i) { + if (p[i] == tsp) { + fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id); + fprintf(fp, "referenced by module '%s'\n", hp->m_id); + lkerr++; + } + } + hp = hp->h_hp; } - hp = hp->h_hp; - } } } @@ -394,13 +390,12 @@ struct sym *tsp; */ int -symeq(p1, p2) -register char *p1, *p2; +symeq(register char *p1, register char *p2) { #if CASE_SENSITIVE - return (strcmp( p1, p2 ) == 0); + return (strncmp( p1, p2, NCPS ) == 0); #else - return (as_strcmpi( p1, p2 ) == 0); + return (as_strncmpi( p1, p2, NCPS ) == 0); #endif } @@ -428,21 +423,21 @@ register char *p1, *p2; */ int -hash(p) -register char *p; +hash(register char *p) { - register int h; + register int h, n; h = 0; - while (*p) { + n = NCPS; + while (*p && n--) { #if CASE_SENSITIVE h += *p++; #else - h += ccase[*p++]; + h += ccase[(unsigned char)(*p++)]; #endif - }; + } return (h&HMASK); } @@ -471,8 +466,7 @@ register char *p; */ VOID * -new(n) -unsigned int n; +new(unsigned int n) { register char *p; diff --git a/as/link/mcs51/Makefile.bcc b/as/link/mcs51/Makefile.bcc index 51c73f5d..b64ff7bb 100644 --- a/as/link/mcs51/Makefile.bcc +++ b/as/link/mcs51/Makefile.bcc @@ -4,10 +4,10 @@ PRJDIR = ../.. !include $(PRJDIR)/Bcc.inc -LKOBJECTS = lkmain.obj lkarea.obj lkdata.obj \ - lkrloc.obj \ - lklibr.obj lkihx.obj lks19.obj \ - lkmem.obj lkaomf51.obj \ +LKOBJECTS = lkmain.obj lkarea.obj lkihx.obj \ + lklibr.obj lkrloc.obj lks19.obj \ + lkmem.obj \ + ../lkaomf51.obj ../lkdata.obj \ ../lkeval.obj ../lkhead.obj ../lklex.obj ../lklist.obj \ ../lknoice.obj ../lkstore.obj ../lksym.obj \ ../../strcmpi.obj diff --git a/as/link/mcs51/Makefile.in b/as/link/mcs51/Makefile.in index 3782c404..c7fb2427 100644 --- a/as/link/mcs51/Makefile.in +++ b/as/link/mcs51/Makefile.in @@ -38,10 +38,10 @@ CFLAGS = @CFLAGS@ -Wall -DINDEXLIB M_OR_MM = @M_OR_MM@ LDFLAGS = @LDFLAGS@ -LKOBJECTS = lkmain.o lkarea.o lkdata.o \ - lkrloc.o \ - lklibr.o lkihx.o lks19.o \ - lkmem.o lkaomf51.o \ +LKOBJECTS = lkmain.o lkarea.o lkihx.o \ + lklibr.o lkrloc.o lks19.o \ + lkmem.o \ + ../lkaomf51.o ../lkdata.o \ ../lkeval.o ../lkhead.o ../lklex.o ../lklist.o \ ../lknoice.o ../lkstore.o ../lksym.o \ ../../strcmpi.o diff --git a/as/link/mcs51/aslink.dsp b/as/link/mcs51/aslink.dsp index b1c68f33..89d6927c 100644 --- a/as/link/mcs51/aslink.dsp +++ b/as/link/mcs51/aslink.dsp @@ -7,19 +7,19 @@ CFG=aslink - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "aslink.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "aslink.mak" CFG="aslink - Win32 Release" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "aslink - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE "aslink - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -77,7 +77,7 @@ LINK32=link.exe # ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept # ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept -!ENDIF +!ENDIF # Begin Target @@ -88,7 +88,7 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\lkaomf51.c +SOURCE=..\lkaomf51.c # End Source File # Begin Source File @@ -96,7 +96,7 @@ SOURCE=.\lkarea.c # End Source File # Begin Source File -SOURCE=.\lkdata.c +SOURCE=..\lkdata.c # End Source File # Begin Source File diff --git a/as/link/mcs51/lkaomf51.c b/as/link/mcs51/lkaomf51.c deleted file mode 100644 index 7e650317..00000000 --- a/as/link/mcs51/lkaomf51.c +++ /dev/null @@ -1,987 +0,0 @@ -/*------------------------------------------------------------------------- - 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 -#include "aslink.h" - -#define EQ(A,B) !strcmp((A),(B)) -#define MEMSIZE 0x10000 -//#define DODUMP 1 - -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; -#if 0 -typedef struct -{ - char * name; - int usage; -} -_UsageType; - -_UsageType UsageType[]= -{ - {"CSEG", 0}, - {"GSINIT", 0}, - {"GSINIT0", 0}, - {"GSINIT1", 0}, - {"GSINIT2", 0}, - {"GSINIT3", 0}, - {"GSINIT4", 0}, - {"GSINIT5", 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?*/ -}; -#endif -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) && (!rflag)) - { - 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); - - /*Check if this filename is already in*/ - for(j=0; j=0)?procedure[symbol[j].Procedure].name:"GLOBAL", - symbol[j].Address, - k<6?UsageTypeName[k]:"???"); - } - - 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); -} -#endif - -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); - lkexit(1); - } - - 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 (unsigned char hex_digit) -{ - if (isdigit (hex_digit)) - return hex_digit-'0'; - else - return toupper (hex_digit)-'A'+10; -} - -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; j -#include -#include "aslink.h" - -/*)Module lkdata.c - * - * The module lkdata contains the global variables - * and structures used in the linker aslink. - */ - -/* - * Definitions for all Global Variables - */ - -char *_abs_ = { ". .ABS." }; - -int lkerr; /* Linker error flag - */ -char *ip; /* Pointer into the REL file text line in ib[] - */ -char ib[NINPUT]; /* REL file text line - */ -char *rp; /* pointer into the LST file - * text line in rb[] - */ -char rb[NINPUT]; /* LST file text line being - * address relocated - */ - -char sdccopt[NINPUT]=""; -char sdccopt_module[NINPUT]=""; -char curr_module[NINPUT]=""; - -int dflag; /* Debug information output flag - */ -int oflag; /* Output file type flag - */ -int mflag; /* Map output flag - */ -int sflag; /* JCF: Memory usage output flag - */ -int packflag=0; /* JCF: Pack internal memory flag - */ -int stacksize=0; /* JCF: Stack size - */ -int aflag; /* Overlapping area warning flag - */ -int jflag; /* NoICE output flag - */ -int xflag; /* Map file radix type flag - */ -int pflag; /* print linker command file flag - */ -int uflag; /* Listing relocation flag - */ -int rflag; /* Extended linear address record flag. - */ -int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -int line; /* current line number - */ -int page; /* current page number - */ -int lop; /* current line number on page - */ -int pass; /* linker pass number - */ -int rtcnt; /* count of elements in the - * rtval[] and rtflg[] arrays - */ -Addr_T rtval[NTXT]; /* data associated with relocation - */ -int rtflg[NTXT]; /* indicates if rtval[] value is - * to be sent to the output file. - * (always set in this linker) - */ -int hilo; /* REL file byte ordering - */ -int gline; /* LST file relocation active - * for current line - */ -int gcntr; /* LST file relocation active - * counter - */ -Addr_T iram_size; /* internal ram size - */ -long xram_size=-1; /* external ram size - */ -long code_size=-1; /* code size - */ - -/* - * The structure lfile contains a pointer to a - * file specification string, the file type, and - * a link to the next lfile structure. - * - * struct lfile - * { - * struct lfile *f_flp; lfile link - * int f_type; File type - * char *f_idp; Pointer to file spec - * }; - */ -struct lfile *filep; /* The pointers (lfile *) filep, - * (lfile *) cfp, and (FILE *) sfp - * are used in conjunction with - * the routine lk_getline() to read - * asmlnk commands from - * (1) the standard input or - * (2) or a command file - * and to read the REL files - * sequentially as defined by the - * asmlnk input commands. - * - * The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - */ -struct lfile *cfp; /* The pointer *cfp points to the - * current lfile structure - */ -struct lfile *startp;/* asmlnk startup file structure - */ -struct lfile *linkp; /* pointer to first lfile structure - * containing an input REL file - * specification - */ -struct lfile *lfp; /* pointer to current lfile structure - * being processed by parse() - */ -FILE *ofp; /* Output file handle - * for word formats - */ -FILE *mfp; /* Map output file handle - */ -FILE *jfp; /* NoICE output file handle - */ -FILE *rfp; /* File handle for output - * address relocated ASxxxx - * listing file - */ -FILE *sfp; /* The file handle sfp points to the - * currently open file - */ -FILE *tfp; /* File handle for input - * ASxxxx listing file - */ -FILE *dfp = NULL ; /* - * File handle for debug - * information output file - */ -/* - * The structures of head, area, areax, and sym are created - * as the REL files are read during the first pass of the - * linker. The struct head is created upon encountering a - * H directive in the REL file. The structure contains a - * link to a link file structure (struct lfile) which describes - * the file containing the H directive, the number of data/code - * areas contained in this header segment, the number of - * symbols referenced/defined in this header segment, a pointer - * to an array of pointers to areax structures (struct areax) - * created as each A directive is read, and a pointer to an - * array of pointers to symbol structures (struct sym) for - * all referenced/defined symbols. As H directives are read - * from the REL files a linked list of head structures is - * created by placing a link to the new head structure - * in the previous head structure. - * - * struct head - * { - * struct head *h_hp; Header link - * struct lfile *h_lfile; Associated file - * int h_narea; # of areas - * struct areax **a_list; Area list - * int h_nglob; # of global symbols - * struct sym **s_list; Global symbol list - * char m_id[NCPS]; Module name - * }; - */ -struct head *headp; /* The pointer to the first - * head structure of a linked list - */ -struct head *hp; /* Pointer to the current - * head structure - */ - -/* - * A structure area is created for each 'unique' data/code - * area definition found as the REL files are read. The - * struct area contains the name of the area, a flag byte - * which contains the area attributes (REL/CON/OVR/ABS), - * an area subtype (not used in this assembler), and the - * area base address and total size which will be filled - * in at the end of the first pass through the REL files. - * As A directives are read from the REL files a linked - * list of unique area structures is created by placing a - * link to the new area structure in the previous area structure. - * - * struct area - * { - * struct area *a_ap; Area link - * struct areax *a_axp; Area extension link - * Addr_T a_addr; Beginning address of area - * Addr_T a_size; Total size of the area - * char a_type; Area subtype - * char a_flag; Flag byte - * char a_id[NCPS]; Name - * }; - */ -struct area *areap; /* The pointer to the first - * area structure of a linked list - */ -struct area *ap; /* Pointer to the current - * area structure - */ - -/* - * An areax structure is created for every A directive found - * while reading the REL files. The struct areax contains a - * link to the 'unique' area structure referenced by the A - * directive and to the head structure this area segment is - * a part of. The size of this area segment as read from the - * A directive is placed in the areax structure. The beginning - * address of this segment will be filled in at the end of the - * first pass through the REL files. As A directives are read - * from the REL files a linked list of areax structures is - * created for each unique area. The final areax linked - * list has at its head the 'unique' area structure linked - * to the linked areax structures (one areax structure for - * each A directive for this area). - * - * struct areax - * { - * struct areax *a_axp; Area extension link - * struct area *a_bap; Base area link - * struct head *a_bhp; Base header link - * Addr_T a_addr; Beginning address of section - * Addr_T a_size; Size of the area in section - * }; - */ -struct areax *axp; /* Pointer to the current - * areax structure - */ - -/* - * A sym structure is created for every unique symbol - * referenced/defined while reading the REL files. The - * struct sym contains the symbol's name, a flag value - * (not used in this linker), a symbol type denoting - * referenced/defined, and an address which is loaded - * with the relative address within the area in which - * the symbol was defined. The sym structure also - * contains a link to the area where the symbol was defined. - * The sym structures are linked into linked lists using - * the symbol link element. - * - * struct sym - * { - * struct sym *s_sp; Symbol link - * struct areax *s_axp; Symbol area link - * char s_type; Symbol subtype - * char s_flag; Flag byte - * Addr_T s_addr; Address - * char *s_id; Name (JLH) - * }; - */ -struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -/* - * The struct base contains a pointer to a - * base definition string and a link to the next - * base structure. - * - * struct base - * { - * struct base *b_base; Base link - * char *b_strp; String pointer - * }; - */ -struct base *basep; /* The pointer to the first - * base structure - */ -struct base *bsp; /* Pointer to the current - * base structure - */ - -/* - * The struct globl contains a pointer to a - * global definition string and a link to the next - * global structure. - * - * struct globl - * { - * struct globl *g_globl; Global link - * char *g_strp; String pointer - * }; - */ -struct globl *globlp;/* The pointer to the first - * globl structure - */ -struct globl *gsp; /* Pointer to the current - * globl structure - */ - -/* - * A structure sdp is created for each 'unique' paged - * area definition found as the REL files are read. - * As P directives are read from the REL files a linked - * list of unique sdp structures is created by placing a - * link to the new sdp structure in the previous area structure. - * - * struct sdp - * { - * struct area *s_area; Paged Area link - * struct areax *s_areax; Paged Area Extension Link - * Addr_T s_addr; Page address offset - * }; - */ -struct sdp sdp; /* Base Page Structure */ - -/* - * The structure rerr is loaded with the information - * required to report an error during the linking - * process. The structure contains an index value - * which selects the areax structure from the header - * areax structure list, a mode value which selects - * symbol or area relocation, the base address in the - * area section, an area/symbol list index value, and - * an area/symbol offset value. - * - * struct rerr - * { - * int aindex; Linking area - * int mode; Relocation mode - * Addr_T rtbase; Base address in section - * int rindex; Area/Symbol reloaction index - * Addr_T rval; Area/Symbol offset value - * }; - */ -struct rerr rerr; /* Structure containing the - * linker error information - */ - -/* - * The structure lbpath is created for each library - * path specification input by the -k option. The - * lbpath structures are linked into a list using - * the next link element. - * - * struct lbpath { - * struct lbpath *next; - * char *path; - * }; - */ -struct lbpath *lbphead; /* pointer to the first - * library path structure - */ - -/* - * The structure lbname is created for all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file. The element path points to - * the path string, element libfil points to the library - * file string, and the element libspc is the concatenation - * of the valid path and libfil strings. - * - * The lbpath structures are linked into a list - * using the next link element. - * - * Each library file contains a list of object files - * that are contained in the particular library. e.g.: - * - * \iolib\termio - * \inilib\termio - * - * Only one specification per line is allowed. - * - * struct lbname { - * struct lbname *next; - * char *path; - * char *libfil; - * char *libspc; - * }; - */ -struct lbname *lbnhead; /* pointer to the first - * library name structure - */ - -/* - * The function fndsym() searches through all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file for a symbol definition. - * - * The structure lbfile is created for the first library - * object file which contains the definition for the - * specified undefined symbol. - * - * The element libspc points to the library file path specification - * and element relfil points to the object file specification string. - * The element filspc is the complete path/file specification for - * the library file to be imported into the linker. The - * file specicifation may be formed in one of two ways: - * - * (1) If the library file contained an absolute - * path/file specification then this becomes filspc. - * (i.e. C:\...) - * - * (2) If the library file contains a relative path/file - * specification then the concatenation of the path - * and this file specification becomes filspc. - * (i.e. \...) - * - * The lbpath structures are linked into a list - * using the next link element. - * - * struct lbfile { - * struct lbfile *next; - * char *libspc; - * char *relfil; - * char *filspc; - * }; - */ -struct lbfile *lbfhead; /* pointer to the first - * library file structure - */ - -/* - * array of character types, one per - * ASCII character - */ -unsigned char ctype[128] = { -/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, -/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, -/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, -/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, -/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, -/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*X*/ LETTER, LETTER, LETTER, BINOP, ETC, ETC, BINOP, LETTER, -/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC -}; - -/* - * an array of characters which - * perform the case translation function - */ -#if CASE_SENSITIVE -#else -char ccase[128] = { -/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', -/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' -}; -#endif diff --git a/as/link/mcs51/lkmain.c b/as/link/mcs51/lkmain.c index 8448a6d3..3c2adc6d 100644 --- a/as/link/mcs51/lkmain.c +++ b/as/link/mcs51/lkmain.c @@ -1437,8 +1437,8 @@ VOID copyfile (dest,src) FILE *src,*dest ; { int ch; - while ((ch = fgetc(src)) != EOF) { - fputc(ch,dest); + while ((ch = fgetc(src)) != EOF) { + fputc(ch,dest); } } diff --git a/as/link/z80/Makefile.in b/as/link/z80/Makefile.in index b2ee6018..87519302 100644 --- a/as/link/z80/Makefile.in +++ b/as/link/z80/Makefile.in @@ -5,14 +5,17 @@ top_srcdir = @top_srcdir@ include $(top_builddir)/Makefile.common -OBJDIR = obj/$(EXT) +OBJDIR = obj$(EXT) SLIBSRC = NewAlloc.c -SRC = lkarea.c lkdata.c lkeval.c lkhead.c lkihx.c lklex.c \ - lklibr.c lklist.c lkmain.c lkrloc.c lks19.c lksym.c \ +SRC = lkmain.c lkarea.c lkihx.c \ + lklibr.c lkrloc.c lks19.c \ lkgb.c lkgg.c \ - ../lkstore.c + ../lkaomf51.c ../lkdata.c \ + ../lkeval.c ../lkhead.c ../lklex.c ../lklist.c \ + ../lknoice.c ../lkstore.c ../lksym.c \ + ../../strcmpi.c OBJS = $(SRC:%.c=$(OBJDIR)/%.o) SLIBOBJS = $(SLIBSRC:%.c=$(OBJDIR)/%.o) diff --git a/as/link/z80/linkgbz80.dsp b/as/link/z80/linkgbz80.dsp index f806a65b..6883df7b 100644 --- a/as/link/z80/linkgbz80.dsp +++ b/as/link/z80/linkgbz80.dsp @@ -89,17 +89,22 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=..\lkaomf51.c +# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" +# End Source File +# Begin Source File + SOURCE=.\lkarea.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # Begin Source File -SOURCE=.\lkdata.c +SOURCE=..\lkdata.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # Begin Source File -SOURCE=.\lkeval.c +SOURCE=..\lkeval.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # Begin Source File @@ -114,7 +119,7 @@ SOURCE=.\lkgg.c # End Source File # Begin Source File -SOURCE=.\lkhead.c +SOURCE=..\lkhead.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # Begin Source File @@ -124,7 +129,7 @@ SOURCE=.\lkihx.c # End Source File # Begin Source File -SOURCE=.\lklex.c +SOURCE=..\lklex.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # Begin Source File @@ -134,7 +139,12 @@ SOURCE=.\lklibr.c # End Source File # Begin Source File -SOURCE=.\lklist.c +SOURCE=..\lklist.c +# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" +# End Source File +# Begin Source File + +SOURCE=..\lknoice.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # Begin Source File @@ -159,7 +169,7 @@ SOURCE=..\lkstore.c # End Source File # Begin Source File -SOURCE=.\lksym.c +SOURCE=..\lksym.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File # End Group diff --git a/as/link/z80/linkz80.dsp b/as/link/z80/linkz80.dsp index 1f8d8b96..8900d510 100644 --- a/as/link/z80/linkz80.dsp +++ b/as/link/z80/linkz80.dsp @@ -89,17 +89,22 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=..\lkaomf51.c +# ADD CPP /D "SDK" /D "INDEXLIB" +# End Source File +# Begin Source File + SOURCE=.\lkarea.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # Begin Source File -SOURCE=.\lkdata.c +SOURCE=..\lkdata.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # Begin Source File -SOURCE=.\lkeval.c +SOURCE=..\lkeval.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # Begin Source File @@ -114,7 +119,7 @@ SOURCE=.\lkgg.c # End Source File # Begin Source File -SOURCE=.\lkhead.c +SOURCE=..\lkhead.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # Begin Source File @@ -124,7 +129,7 @@ SOURCE=.\lkihx.c # End Source File # Begin Source File -SOURCE=.\lklex.c +SOURCE=..\lklex.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # Begin Source File @@ -134,7 +139,12 @@ SOURCE=.\lklibr.c # End Source File # Begin Source File -SOURCE=.\lklist.c +SOURCE=..\lklist.c +# ADD CPP /D "SDK" /D "INDEXLIB" +# End Source File +# Begin Source File + +SOURCE=..\lknoice.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # Begin Source File @@ -159,7 +169,7 @@ SOURCE=..\lkstore.c # End Source File # Begin Source File -SOURCE=.\lksym.c +SOURCE=..\lksym.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File # End Group diff --git a/as/link/z80/lkdata.c b/as/link/z80/lkdata.c deleted file mode 100644 index bd1ed03e..00000000 --- a/as/link/z80/lkdata.c +++ /dev/null @@ -1,469 +0,0 @@ -/* lkdata.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -#include -#include -#include "aslink.h" - -/*)Module lkdata.c - * - * The module lkdata contains the global variables - * and structures used in the linker aslink. - */ - -/* - * Definitions for all Global Variables - */ - -char *_abs_ = { ". .ABS." }; - -int lkerr; /* Linker error flag - */ -char *ip; /* Pointer into the REL file text line in ib[] - */ -char ib[NINPUT]; /* REL file text line - */ -char *rp; /* pointer into the LST file - * text line in rb[] - */ -char rb[NINPUT]; /* LST file text line being - * address relocated - */ - -char sdccopt[NINPUT]=""; -char sdccopt_module[NINPUT]=""; -char curr_module[NINPUT]=""; - -int oflag; /* Output file type flag - */ -int mflag; /* Map output flag - */ -#ifdef SDK -int symflag; /* no$gmb .sym output flag - */ -#endif -int xflag; /* Map file radix type flag - */ -int pflag; /* print linker command file flag - */ -int uflag; /* Listing relocation flag - */ -int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -int line; /* current line number - */ -int page; /* current page number - */ -int lop; /* current line number on page - */ -int pass; /* linker pass number - */ -int rtcnt; /* count of elements in the - * rtval[] and rtflg[] arrays - */ -Addr_T rtval[NTXT]; /* data associated with relocation - */ -int rtflg[NTXT]; /* indicates if rtval[] value is - * to be sent to the output file. - * (always set in this linker) - */ -int hilo; /* REL file byte ordering - */ -int gline; /* LST file relocation active - * for current line - */ -int gcntr; /* LST file relocation active - * counter - */ - -/* - * The structure lfile contains a pointer to a - * file specification string, the file type, and - * a link to the next lfile structure. - * - * struct lfile - * { - * struct lfile *f_flp; lfile link - * int f_type; File type - * char *f_idp; Pointer to file spec - * }; - */ -struct lfile *filep; /* The pointers (lfile *) filep, - * (lfile *) cfp, and (FILE *) sfp - * are used in conjunction with - * the routine lk_getline() to read - * asmlnk commands from - * (1) the standard input or - * (2) or a command file - * and to read the REL files - * sequentially as defined by the - * asmlnk input commands. - * - * The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - */ -struct lfile *cfp; /* The pointer *cfp points to the - * current lfile structure - */ -struct lfile *startp;/* asmlnk startup file structure - */ -struct lfile *linkp; /* pointer to first lfile structure - * containing an input REL file - * specification - */ -struct lfile *lfp; /* pointer to current lfile structure - * being processed by parse() - */ -FILE *ofp; /* Output file handle - * for word formats - */ -FILE *mfp; /* Map output file handle - */ -FILE *rfp; /* File handle for output - * address relocated ASxxxx - * listing file - */ -FILE *sfp; /* The file handle sfp points to the - * currently open file - */ -FILE *tfp; /* File handle for input - * ASxxxx listing file - */ - -/* - * The structures of head, area, areax, and sym are created - * as the REL files are read during the first pass of the - * linker. The struct head is created upon encountering a - * H directive in the REL file. The structure contains a - * link to a link file structure (struct lfile) which describes - * the file containing the H directive, the number of data/code - * areas contained in this header segment, the number of - * symbols referenced/defined in this header segment, a pointer - * to an array of pointers to areax structures (struct areax) - * created as each A directive is read, and a pointer to an - * array of pointers to symbol structures (struct sym) for - * all referenced/defined symbols. As H directives are read - * from the REL files a linked list of head structures is - * created by placing a link to the new head structure - * in the previous head structure. - * - * struct head - * { - * struct head *h_hp; Header link - * struct lfile *h_lfile; Associated file - * int h_narea; # of areas - * struct areax **a_list; Area list - * int h_nglob; # of global symbols - * struct sym **s_list; Global symbol list - * char m_id[NCPS]; Module name - * }; - */ -struct head *headp; /* The pointer to the first - * head structure of a linked list - */ -struct head *hp; /* Pointer to the current - * head structure - */ - -/* - * A structure area is created for each 'unique' data/code - * area definition found as the REL files are read. The - * struct area contains the name of the area, a flag byte - * which contains the area attributes (REL/CON/OVR/ABS), - * an area subtype (not used in this assembler), and the - * area base address and total size which will be filled - * in at the end of the first pass through the REL files. - * As A directives are read from the REL files a linked - * list of unique area structures is created by placing a - * link to the new area structure in the previous area structure. - * - * struct area - * { - * struct area *a_ap; Area link - * struct areax *a_axp; Area extension link - * Addr_T a_addr; Beginning address of area - * Addr_T a_size; Total size of the area - * char a_type; Area subtype - * char a_flag; Flag byte - * char a_id[NCPS]; Name - * }; - */ -struct area *areap; /* The pointer to the first - * area structure of a linked list - */ -struct area *ap; /* Pointer to the current - * area structure - */ - -/* - * An areax structure is created for every A directive found - * while reading the REL files. The struct areax contains a - * link to the 'unique' area structure referenced by the A - * directive and to the head structure this area segment is - * a part of. The size of this area segment as read from the - * A directive is placed in the areax structure. The beginning - * address of this segment will be filled in at the end of the - * first pass through the REL files. As A directives are read - * from the REL files a linked list of areax structures is - * created for each unique area. The final areax linked - * list has at its head the 'unique' area structure linked - * to the linked areax structures (one areax structure for - * each A directive for this area). - * - * struct areax - * { - * struct areax *a_axp; Area extension link - * struct area *a_bap; Base area link - * struct head *a_bhp; Base header link - * Addr_T a_addr; Beginning address of section - * Addr_T a_size; Size of the area in section - * }; - */ -struct areax *axp; /* Pointer to the current - * areax structure - */ - -/* - * A sym structure is created for every unique symbol - * referenced/defined while reading the REL files. The - * struct sym contains the symbol's name, a flag value - * (not used in this linker), a symbol type denoting - * referenced/defined, and an address which is loaded - * with the relative address within the area in which - * the symbol was defined. The sym structure also - * contains a link to the area where the symbol was defined. - * The sym structures are linked into linked lists using - * the symbol link element. - * - * struct sym - * { - * struct sym *s_sp; Symbol link - * struct areax *s_axp; Symbol area link - * char s_type; Symbol subtype - * char s_flag; Flag byte - * Addr_T s_addr; Address - * char *s_id; Name (JLH) - * }; - */ -struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -/* - * The struct base contains a pointer to a - * base definition string and a link to the next - * base structure. - * - * struct base - * { - * struct base *b_base; Base link - * char *b_strp; String pointer - * }; - */ -struct base *basep; /* The pointer to the first - * base structure - */ -struct base *bsp; /* Pointer to the current - * base structure - */ - -/* - * The struct globl contains a pointer to a - * global definition string and a link to the next - * global structure. - * - * struct globl - * { - * struct globl *g_globl; Global link - * char *g_strp; String pointer - * }; - */ -struct globl *globlp;/* The pointer to the first - * globl structure - */ -struct globl *gsp; /* Pointer to the current - * globl structure - */ - -/* - * A structure sdp is created for each 'unique' paged - * area definition found as the REL files are read. - * As P directives are read from the REL files a linked - * list of unique sdp structures is created by placing a - * link to the new sdp structure in the previous area structure. - * - * struct sdp - * { - * struct area *s_area; Paged Area link - * struct areax *s_areax; Paged Area Extension Link - * Addr_T s_addr; Page address offset - * }; - */ -struct sdp sdp; /* Base Page Structure */ - -/* - * The structure rerr is loaded with the information - * required to report an error during the linking - * process. The structure contains an index value - * which selects the areax structure from the header - * areax structure list, a mode value which selects - * symbol or area relocation, the base address in the - * area section, an area/symbol list index value, and - * an area/symbol offset value. - * - * struct rerr - * { - * int aindex; Linking area - * int mode; Relocation mode - * Addr_T rtbase; Base address in section - * int rindex; Area/Symbol reloaction index - * Addr_T rval; Area/Symbol offset value - * }; - */ -struct rerr rerr; /* Structure containing the - * linker error information - */ - -/* - * The structure lbpath is created for each library - * path specification input by the -k option. The - * lbpath structures are linked into a list using - * the next link element. - * - * struct lbpath { - * struct lbpath *next; - * char *path; - * }; - */ -struct lbpath *lbphead; /* pointer to the first - * library path structure - */ - -/* - * The structure lbname is created for all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file. The element path points to - * the path string, element libfil points to the library - * file string, and the element libspc is the concatenation - * of the valid path and libfil strings. - * - * The lbpath structures are linked into a list - * using the next link element. - * - * Each library file contains a list of object files - * that are contained in the particular library. e.g.: - * - * \iolib\termio - * \inilib\termio - * - * Only one specification per line is allowed. - * - * struct lbname { - * struct lbname *next; - * char *path; - * char *libfil; - * char *libspc; - * }; - */ -struct lbname *lbnhead; /* pointer to the first - * library name structure - */ - -/* - * The function fndsym() searches through all combinations of the - * library path specifications (input by the -k option) and the - * library file specifications (input by the -l option) that - * lead to an existing file for a symbol definition. - * - * The structure lbfile is created for the first library - * object file which contains the definition for the - * specified undefined symbol. - * - * The element libspc points to the library file path specification - * and element relfil points to the object file specification string. - * The element filspc is the complete path/file specification for - * the library file to be imported into the linker. The - * file specicifation may be formed in one of two ways: - * - * (1) If the library file contained an absolute - * path/file specification then this becomes filspc. - * (i.e. C:\...) - * - * (2) If the library file contains a relative path/file - * specification then the concatenation of the path - * and this file specification becomes filspc. - * (i.e. \...) - * - * The lbpath structures are linked into a list - * using the next link element. - * - * struct lbfile { - * struct lbfile *next; - * char *libspc; - * char *relfil; - * char *filspc; - * }; - */ -struct lbfile *lbfhead; /* pointer to the first - * library file structure - */ - -/* - * array of character types, one per - * ASCII character - */ -unsigned char ctype[128] = { -/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, -/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, -/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, -/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, -/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, -/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, -/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC -}; - -/* - * an array of characters which - * perform the case translation function - */ -#if CASE_SENSITIVE -#else -char ccase[128] = { -/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', -/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' -}; -#endif diff --git a/as/link/z80/lkeval.c b/as/link/z80/lkeval.c deleted file mode 100644 index 14e9cf67..00000000 --- a/as/link/z80/lkeval.c +++ /dev/null @@ -1,397 +0,0 @@ -/* lkeval.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -#include -#include -#include "aslink.h" - -/*)Module lkeval.c - * - * The module lkeval.c contains the routines to evaluate - * arithmetic/numerical expressions. The functions in - * lkeval.c perform a recursive evaluation of the arithmetic - * expression read from the input text line. - * The expression may include binary/unary operators, brackets, - * symbols, labels, and constants in hexadecimal, decimal, octal - * and binary. Arithmetic operations are prioritized and - * evaluated by normal arithmetic conventions. - * - * lkeval.c contains the following functions: - * int digit() - * Addr_T eval() - * Addr_T expr() - * int oprio() - * Addr_T term() - * - * lkeval.c contains no local/static variables - */ - -/*)Function Addr_T eval() - * - * The function eval() evaluates a character string to a - * numerical value. - * - * local variables: - * int c character from input string - * int v value of character in current radix - * Addr_T n evaluation value - * - * global variables: - * int radix current number conversion radix - * - * functions called: - * int digit() lkeval.c - * char get() lklex.c - * char getnb() lklex.c - * VOID unget() lklex.c - * - * side effects: - * Input test is scanned and evaluated to a - * numerical value. - */ - -Addr_T -eval() -{ - register int c, v; - register Addr_T n; - - c = getnb(); - n = 0; - while ((v = digit(c, radix)) >= 0) { - n = n*radix + v; - c = get(); - } - unget(c); - return(n); -} - -/*)Function Addr_T expr(n) - * - * int n a firewall priority; all top - * level calls (from the user) - * should be made with n set to 0. - * - * The function expr() evaluates an expression and - * returns the value. - * - * local variables: - * int c current input text character - * int p current operator priority - * Addr_T v value returned by term() - * Addr_T ve value returned by a - * recursive call to expr() - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * int lkerr error flag - * FILE * stderr c_library - * - * functions called: - * VOID expr() lkeval.c - * int fprintf() c_library - * int getnb() lklex.c - * int oprio() lkeval.c - * VOID term() lkeval.c - * VOID unget() lklex.c - * - * - * side effects: - * An expression is evaluated by scanning the input - * text string. - */ - -Addr_T -expr (n) -{ - register int c, p; - register Addr_T v, ve; - - v = term(); - while (ctype[c = getnb()] & BINOP) { - if ((p = oprio(c)) <= n) - break; - if ((c == '>' || c == '<') && c != get()) { - fprintf(stderr, "Invalid expression"); - lkerr++; - return(v); - } - ve = expr(p); - if (c == '+') { - v += ve; - } else - if (c == '-') { - v -= ve; - } else { - switch (c) { - - case '*': - v *= ve; - break; - - case '/': - v /= ve; - break; - - case '&': - v &= ve; - break; - - case '|': - v |= ve; - break; - - case '%': - v %= ve; - break; - - case '^': - v ^= ve; - break; - - case '<': - v <<= ve; - break; - - case '>': - v >>= ve; - break; - } - } - } - unget(c); - return(v); -} - -/*)Function Addr_T term() - * - * The function term() evaluates a single constant - * or symbol value prefaced by any unary operator - * ( +, -, ~, ', ", >, or < ). - * - * local variables: - * int c current character - * char id[] symbol name - * int n value of digit in current radix - * int r current evaluation radix - * sym * sp pointer to a sym structure - * Addr_T v evaluation value - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * int lkerr error flag - * - * functions called: - * int digit() lkeval.c - * VOID expr() lkeval.c - * int fprintf() c_library - * int get() lklex.c - * VOID getid() lklex.c - * int getmap() lklex.c - * int getnb() lklex.c - * sym * lkpsym() lksym.c - * Addr_T symval() lksym.c - * VOID unget() lklex.c - * - * side effects: - * An arithmetic term is evaluated by scanning input text. - */ - -Addr_T -term() -{ - register int c, r, n; - register Addr_T v; - struct sym *sp; - char id[NCPS]; - - c = getnb(); - if (c == '#') { c = getnb(); } - if (c == '(') { - v = expr(0); - if (getnb() != ')') { - fprintf(stderr, "Missing delimiter"); - lkerr++; - } - return(v); - } - if (c == '-') { - return(0-expr(100)); - } - if (c == '~') { - return(~expr(100)); - } - if (c == '\'') { - return(getmap(-1)&0377); - } - if (c == '\"') { - if (hilo) { - v = (getmap(-1)&0377)<<8; - v |= getmap(-1)&0377; - } else { - v = getmap(-1)&0377; - v |= (getmap(-1)&0377)<<8; - } - return(v); - } - if (c == '>' || c == '<') { - v = expr(100); - if (c == '>') - v >>= 8; - return(v&0377); - } - if (ctype[c] & DIGIT) { - r = 10; - if (c == '0') { - c = get(); - switch (c) { - case 'b': - case 'B': - r = 2; - c = get(); - break; - case '@': - case 'o': - case 'O': - case 'q': - case 'Q': - r = 8; - c = get(); - break; - case 'd': - case 'D': - r = 10; - c = get(); - break; - case 'h': - case 'H': - case 'x': - case 'X': - r = 16; - c = get(); - break; - default: - break; - } - } - v = 0; - while ((n = digit(c, r)) >= 0) { - v = r*v + n; - c = get(); - } - unget(c); - return(v); - } - if (ctype[c] & LETTER) { - getid(id, c); - if ((sp = lkpsym(id, 0)) == NULL) { - fprintf(stderr, "Undefined symbol %8s\n", id); - lkerr++; - return(0); - } else { - return(symval(sp)); - } - } - /* Shouldn't get here. */ - return(0); -} - -/*)Function int digit(c, r) - * - * int c digit character - * int r current radix - * - * The function digit() returns the value of c - * in the current radix r. If the c value is not - * a number of the current radix then a -1 is returned. - * - * local variables: - * none - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * - * functions called: - * none - * - * side effects: - * none - */ - -int -digit(c, r) -register int c, r; -{ - if (r == 16) { - if (ctype[c] & RAD16) { - if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - return (c - '0'); - } - } else - if (r == 10) { - if (ctype[c] & RAD10) - return (c - '0'); - } else - if (r == 8) { - if (ctype[c] & RAD8) - return (c - '0'); - } else - if (r == 2) { - if (ctype[c] & RAD2) - return (c - '0'); - } - return (-1); -} - -/*)Function int oprio(c) - * - * int c operator character - * - * The function oprio() returns a relative priority - * for all valid unary and binary operators. - * - * local variables: - * none - * - * global variables: - * none - * - * functions called: - * none - * - * side effects: - * none - */ - -int -oprio(c) -register int c; -{ - if (c == '*' || c == '/' || c == '%') - return (10); - if (c == '+' || c == '-') - return (7); - if (c == '<' || c == '>') - return (5); - if (c == '^') - return (4); - if (c == '&') - return (3); - if (c == '|') - return (1); - return (0); -} diff --git a/as/link/z80/lkhead.c b/as/link/z80/lkhead.c deleted file mode 100644 index 41a5198c..00000000 --- a/as/link/z80/lkhead.c +++ /dev/null @@ -1,153 +0,0 @@ -/* lkhead.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -#include -#include -#include "aslink.h" - -/*Module lkhead.c - * - * The module lkhead.c contains the function newhead() which - * creates a head structure and the function module() which - * loads the module name into the current head structure. - * - * lkhead.c contains the following functions: - * VOID newhead() - * VOID module() - * - * lkhead.c contains no local variables. - */ - -/*)Function VOID newhead() - * - * The function newhead() creates a head structure. All head - * structures are linked to form a linked list of head structures - * with the current head structure at the tail of the list. - * - * local variables: - * int i evaluation value - * head * thp temporary pointer - * to a header structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * lfile *cfp The pointer *cfp points to the - * current lfile structure - * head *headp The pointer to the first - * head structure of a linked list - * head *hp Pointer to the current - * head structure - * - * functions called: - * Addr_T expr() lkeval.c - * VOID * new() lksym.c - * VOID lkparea() lkarea.c - * - * side effects: - * A new head structure is created and linked to any - * existing linked head structure. The head structure - * parameters of file handle, number of areas, and number - * of global symbols are loaded into the structure. - * The default area "_abs_" is created when the first - * head structure is created and an areax structure is - * created for every head structure called. - */ - -/* - * Create a new header entry. - * - * H n areas n global symbols - * | | - * | `---- hp->h_nglob - * `------------ hp->h_narea - * - */ -VOID -newhead() -{ - register int i; - struct head *thp; - - hp = (struct head *) new (sizeof(struct head)); - if (headp == NULL) { - headp = hp; - } else { - thp = headp; - while (thp->h_hp) - thp = thp->h_hp; - thp->h_hp = hp; - } - /* - * Set file pointer - */ - hp->h_lfile = cfp; - /* - * Evaluate and build Area pointer list - */ - i = hp->h_narea = eval(); - if (i) - hp->a_list = (struct areax **) new (i*sizeof(struct areax *)); - /* - * Evaluate and build Global symbol pointer list - */ - skip(-1); - i = hp->h_nglob = eval(); - if (i) - hp->s_list = (struct sym **) new (i*sizeof(struct sym *)); - /* - * Setup Absolute DEF linkage. - */ - lkparea(_abs_); - ap->a_flag = A_ABS; -} - -/*)Function VOID module() - * - * The function module() copies the module name into - * the current head structure. - * - * local variables: - * char id[] module id string - * - * global variables: - * head *headp The pointer to the first - * head structure of a linked list - * head *hp Pointer to the current - * head structure - * int lkerr error flag - * FILE * stderr c_library - * - * functions called: - * int fprintf() c_library - * VOID getid() lklex.c - * char * strncpy() c_library - * - * side effects: - * The module name is copied into the head structure. - */ - -/* - * Module Name - */ -VOID -module() -{ - char id[NCPS]; - - if (headp) { - getid(id, -1); - strncpy(hp->m_id, id, NCPS); - } else { - fprintf(stderr, "No header defined\n"); - lkerr++; - } -} diff --git a/as/link/z80/lklex.c b/as/link/z80/lklex.c deleted file mode 100644 index 642062dc..00000000 --- a/as/link/z80/lklex.c +++ /dev/null @@ -1,659 +0,0 @@ -/* lklex.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -/* - * Extensions: P. Felber, M. Hope - */ - -#include -#include -#include "aslink.h" - -/*)Module lklex.c - * - * The module lklex.c contains the general lexical analysis - * functions used to scan the text lines from the .rel files. - * - * lklex.c contains the fllowing functions: - * char endline() - * char get() - * VOID getfid() - * VOID getid() - * VOID getSid() - * int lk_getline() - * int getmap() - * char getnb() - * int more() - * VOID skip() - * VOID unget() - * - * lklex.c contains no local variables. - */ - -/*)Function VOID getid(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space - * - * The function getid() scans the current input text line - * from the current position copying the next LETTER | DIGIT string - * into the external string buffer (id). The string ends when a non - * LETTER or DIGIT character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() lklex.c - * char getnb() lklex.c - * VOID unget() lklex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip the position in the current - * input text line. - */ - -VOID -getid(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (LETTER|DIGIT)); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function VOID getSid (char *id) - * - * char * id a pointer to a string of - * maximum length NCPS - * - * getSid is derived from getid. It is called from newsym() - * in lksym.c, when an S-record has to be scanned. getSid accepts - * much more characters than getid, which is necessary for SDCC. - * - * The function getSid() scans the current input text line - * from the current position copying the next string - * into the external string buffer (id). The string ends when a space - * character (space, tab, \0) is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * Intervening white space (SPACES and TABS) are skipped. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() lklex.c - * char getnb() lklex.c - * VOID unget() lklex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip the position in the current - * input text line. - */ - -VOID -getSid (char *id) -{ - register int c; - register char *p; - - c = getnb(); - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - c = get(); - } while (c != '\0' && c != ' ' && c != '\t'); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function VOID getfid(fid,c) - * - * char * str a pointer to a string of - * maximum length PATH_MAX - * int c this is first character to - * copy to the string buffer - * - * The function getfid() scans the current input text line - * from the current position copying the next string - * into the external string buffer (str). The string ends when a - * non SPACE type character is found. The maximum number of - * characters copied is FILSPC. If the input string is larger than - * PATH_MAX characters then the string is truncated, if the input string - * is shorter than FILSPC characters then the string is NULL filled. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() lklex.c - * - * side effects: - * use of get() updates the global pointer ip - * the position in the current input text line. - */ - -VOID -getfid(str, c) -register int c; -char *str; -{ - register char *p; - - p = str; - do - { - if (p < &str[PATH_MAX-1]) - *p++ = c; - c = get(); - if (c == ';') - while (c) - c = get(); -#ifdef SDK - } while (c); -#else /* SDK */ - } while (c && (ctype[c] != SPACE)); -#endif /* SDK */ - while (p < &str[PATH_MAX]) - *p++ = 0; -} - -/*)Function char getnb() - * - * The function getnb() scans the current input text - * line returning the first character not a SPACE or TAB. - * - * local variables: - * int c current character from input - * - * global variables: - * none - * - * called functions: - * char get() lklex.c - * - * side effects: - * use of get() updates the global pointer ip, the position - * in the current input text line - */ - -char -getnb() -{ - register int c; - - while ((c=get())==' ' || c=='\t') - ; - return (c); -} - -/*)Function VOID skip() - * - * The function skip() scans the input text skipping all - * letters and digits. - * - * local variables: - * none - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * - * functions called: - * char get() lklex.c - * char getnb() lklex.c - * VOID unget() lklex.c - * - * side effects: - * Input letters and digits are skipped. - */ - -VOID -skip(c) -register int c; -{ - if (c < 0) - c = getnb(); - while (ctype[c=get()] & (LETTER|DIGIT)) { ; } - unget(c); -} - -/*)Function char get() - * - * The function get() returns the next character in the - * input text line, at the end of the line a - * NULL character is returned. - * - * local variables: - * int c current character from - * input text line - * - * global variables: - * char * ip pointer into the current - * input text line - * - * called functions: - * none - * - * side effects: - * updates ip to the next character position in the - * input text line. If ip is at the end of the - * line, ip is not updated. - */ - -char -get() -{ - register int c; - - if ((c = *ip) != 0) - ++ip; - return (c); -} - -/*)Function VOID unget(c) - * - * int c value of last character - * read from input text line - * - * If (c) is not a NULL character then the global pointer ip - * is updated to point to the preceeding character in the - * input text line. - * - * NOTE: This function does not push the character (c) - * back into the input text line, only - * the pointer ip is changed. - * - * local variables: - * int c last character read - * from input text line - * - * global variables: - * char * ip position into the current - * input text line - * - * called functions: - * none - * - * side effects: - * ip decremented by 1 character position - */ - -VOID -unget(c) -{ - if (c != 0) - --ip; -} - -/*)Function int getmap(d) - * - * int d value to compare with the - * input text line character - * - * The function getmap() converts the 'C' style characters \b, \f, - * \n, \r, and \t to their equivalent ascii values and also - * converts 'C' style octal constants '\123' to their equivalent - * numeric values. If the first character is equivalent to (d) then - * a (-1) is returned, if the end of the line is detected then - * a 'q' error terminates the parse for this line, or if the first - * character is not a \ then the character value is returned. - * - * local variables: - * int c value of character - * from input text line - * int n looping counter - * int v current value of numeric conversion - * - * global variables: - * none - * - * called functions: - * char get() lklex.c - * VOID unget() lklex.c - * - * side effects: - * use of get() updates the global pointer ip the position - * in the current input text line - */ - -int -getmap(d) -{ - register int c, n, v; - - if ((c = get()) == '\0') - return (-1); - if (c == d) - return (-1); - if (c == '\\') { - c = get(); - switch (c) { - - case 'b': - c = '\b'; - break; - - case 'f': - c = '\f'; - break; - - case 'n': - c = '\n'; - break; - - case 'r': - c = '\r'; - break; - - case 't': - c = '\t'; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - n = 0; - v = 0; - while (++n<=3 && c>='0' && c<='7') { - v = (v<<3) + c - '0'; - c = get(); - } - unget(c); - c = v; - break; - } - } - return (c); -} - -/*)Function int lk_getline() - * - * The function lk_getline() reads a line of input text from a - * .rel source text file, a .lnk command file or from stdin. - * Lines of text are processed from a single .lnk file or - * multiple .rel files until all files have been read. - * The input text line is copied into the global string ib[] - * and converted to a NULL terminated string. The function - * lk_getline() returns a (1) after succesfully reading a line - * or a (0) if all files have been read. - * This function also opens each input .lst file and output - * .rst file as each .rel file is processed. - * - * local variables: - * int i string length - * int ftype file type - * char * fid file name - * - * global variables: - * lfile *cfp The pointer *cfp points to the - * current lfile structure - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * int gline get a line from the LST file - * to translate for the RST file - * char ib[NINPUT] REL file text line - * int pass linker pass number - * int pflag print linker command file flag - * FILE *rfp The file handle to the current - * output RST file - * FILE *sfp The file handle sfp points to the - * currently open file - * FILE * stdin c_library - * FILE * stdout c_library - * FILE *tfp The file handle to the current - * LST file being scanned - * int uflag update listing flag - * - * called functions: - * FILE * afile() lkmain.c - * int fclose() c_library - * char * fgets() c_library - * int fprintf() c_library - * VOID lkulist() lklist.c - * VOID lkexit() lkmain.c - * int strlen() c_library - * - * side effects: - * The input stream is scanned. The .rel files will be - * opened and closed sequentially scanning each in turn. - */ - -int -lk_getline() -{ - register int ftype; - register char *fid; - -loop: if (pflag && cfp && cfp->f_type == F_STD) - fprintf(stdout, "ASlink >> "); - -#ifdef SDK - if(cfp == NULL && filep != NULL && filep->f_type == F_CMD) { - char **argv = (char **)filep->f_idp; - if(argv[0] != NULL && strlen(argv[0]) < sizeof ib) { - strcpy(ib, argv[0]); - filep->f_idp = (char *)&argv[1]; - } else { - filep = NULL; - return(0); - } - } else -#endif /* SDK */ - if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) { - if (sfp) { - fclose(sfp); -#ifdef SDK - sfp = NULL; -#endif /* SDK */ - lkulist(0); - } - if (cfp == NULL) { - cfp = filep; - } else { - cfp = cfp->f_flp; - } - if (cfp) { - ftype = cfp->f_type; - fid = cfp->f_idp; - if (ftype == F_STD) { - sfp = stdin; - } else - if (ftype == F_LNK) { -#ifdef SDK - sfp = afile(fid, "lnk", 0); -#else /* SDK */ - sfp = afile(fid, "LNK", 0); -#endif /* SDK */ - } else - if (ftype == F_REL) { -#ifdef SDK - sfp = afile(fid, "", 0); - if (uflag && pass != 0) { - if ((tfp = afile(fid, "lst", 0)) != NULL) { - if ((rfp = afile(fid, "rst", 1)) == NULL) { -#else /* SDK */ - sfp = afile(fid, "REL", 0); - if (uflag && pass != 0) { - if ((tfp = afile(fid, "LST", 0)) != NULL) { - if ((rfp = afile(fid, "RST", 1)) == NULL) { -#endif /* SDK */ - fclose(tfp); - tfp = NULL; - } - } - } - gline = 1; - } else { - fprintf(stderr, "Invalid file type\n"); - lkexit(1); - } - if (sfp == NULL) { - lkexit(1); - } - goto loop; - } else { - filep = NULL; - return(0); - } - } - chop_crlf(ib); - return (1); -} - -/*)Function int more() - * - * The function more() scans the input text line - * skipping white space (SPACES and TABS) and returns a (0) - * if the end of the line or a comment delimeter (;) is found, - * or a (1) if their are additional characters in the line. - * - * local variables: - * int c next character from - * the input text line - * - * global variables: - * none - * - * called functions: - * char getnb() lklex.c - * VOID unget() lklex.c - * - * side effects: - * use of getnb() and unget() updates the global pointer ip - * the position in the current input text line - */ - -int -more() -{ - register int c; - - c = getnb(); - unget(c); - return( (c == '\0' || c == ';') ? 0 : 1 ); -} - -/*)Function char endline() - * - * The function endline() scans the input text line - * skipping white space (SPACES and TABS) and returns the next - * character or a (0) if the end of the line is found or a - * comment delimiter (;) is found. - * - * local variables: - * int c next character from - * the input text line - * - * global variables: - * none - * - * called functions: - * char getnb() lklex.c - * - * side effects: - * Use of getnb() updates the global pointer ip the - * position in the current input text line. - */ - -char -endline() -{ - register int c; - - c = getnb(); - return( (c == '\0' || c == ';') ? 0 : c ); -} - -/*)Function VOID chop_crlf(str) - * - * char *str string to chop - * - * The function chop_crlf() removes trailing LF or CR/LF from - * str, if present. - * - * local variables: - * int i string length - * - * global variables: - * none - * - * functions called: - * none - * - * side effects: - * none - */ - -VOID -chop_crlf(str) -char *str; -{ - register int i; - - i = strlen(str); - if (i >= 1 && str[i-1] == '\n') str[i-1] = 0; - if (i >= 2 && str[i-2] == '\r') str[i-2] = 0; -} diff --git a/as/link/z80/lklibr.c b/as/link/z80/lklibr.c index 0fb575c9..c6d17d0e 100644 --- a/as/link/z80/lklibr.c +++ b/as/link/z80/lklibr.c @@ -42,12 +42,6 @@ #endif /* SDK */ #endif -#ifdef SDK - #define LKOBJEXT "o" -#else /* SDK */ - #define LKOBJEXT "rel" -#endif /* SDK */ - /*)Module lklibr.c * * The module lklibr.c contains the functions which diff --git a/as/link/z80/lklist.c b/as/link/z80/lklist.c deleted file mode 100644 index 30d21091..00000000 --- a/as/link/z80/lklist.c +++ /dev/null @@ -1,1233 +0,0 @@ -/* lklist.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -#include -#include -#include -#include "aslink.h" - -/*)Module lklist.c - * - * The module lklist.c contains the functions which - * output the linker .map file and produce a relocated - * listing .rst file. - * - * lklist.c contains the following functions: - * int dgt() - * VOID lstarea() - * VOID lkulist() - * VOID lkalist() - * VOID lkglist() - * VOID newpag() - * VOID slew() - * - * lklist.c contains no local variables. - */ - -/*)Function VOID slew(fp) - * - * FILE * fp output file handle - * - * The function slew() increments the page line counter. - * If the number of lines exceeds the maximum number of - * lines per page then a page skip and a page header are - * output. - * - * local variables: - * int i loop counter - * - * global variables: - * int lop current line number on page - * int xflag Map file radix type flag - * - * functions called: - * int fprintf() c_library - * VOID newpag() lklist.c - * - * side effects: - * The page line and the page count may be updated. - */ - -VOID -slew(fp) -FILE *fp; -{ - register int i; - - if (lop++ >= NLPP) { - newpag(fp); - if (xflag == 0) { - fprintf(fp, "Hexadecimal\n\n"); - } else - if (xflag == 1) { - fprintf(fp, "Octal\n\n"); - } else - if (xflag == 2) { - fprintf(fp, "Decimal\n\n"); - } - fprintf(fp, "Area Addr Size"); - fprintf(fp, " Decimal Bytes (Attributes)\n"); - for(i=0;i<4;++i) - fprintf(fp, " Value--Global"); - fprintf(fp, "\n\n"); - lop += 6; - } -} - -/*)Function VOID newpag() - * - * The function newpag() outputs a page skip, writes the - * first page header line, sets the line count to 1, and - * increments the page counter. - * - * local variables: - * none - * - * global variables: - * int lop current line number on page - * int page current page number - * - * functions called: - * int fprintf() c_library - * - * side effects: - * The page and line counters are updated. - */ - -VOID -newpag(fp) -FILE *fp; -{ - fprintf(fp, "\fASxxxx Linker %s, page %u.\n", VERSION, ++page); - lop = 1; -} - -#if (NCPS==8) || !defined (MLH_MAP) -/* Used for qsort call in lstarea */ -static int _cmpSymByAddr(const void *p1, const void *p2) -{ - struct sym **s1 = (struct sym **)(p1); - struct sym **s2 = (struct sym **)(p2); - int delta = ((*s1)->s_addr + (*s1)->s_axp->a_addr) - - ((*s2)->s_addr + (*s2)->s_axp->a_addr); - - /* Sort first by address, then by name. */ - if (delta) - { - return delta; - } - return strcmp((*s1)->s_id,(*s2)->s_id); -} -#endif - -#if NCPS-8 - -/* NCPS != 8 */ -/*)Function VOID lstarea(xp) - * - * area * xp pointer to an area structure - * - * The function lstarea() creates the linker map output for - * the area specified by pointer xp. The generated output - * area header includes the area name, starting address, - * size of area, number of words (in decimal), and the - * area attributes. The symbols defined in this area are - * sorted by ascending address and output one per line - * in the selected radix. - * - * local variables: - * areax * oxp pointer to an area extension structure - * int c character value - * int i loop counter - * int j bubble sort update status - * char * ptr pointer to an id string - * int nmsym number of symbols in area - * Addr_T a0 temporary - * Addr_T ai temporary - * Addr_T aj temporary - * sym * sp pointer to a symbol structure - * sym ** p pointer to an array of - * pointers to symbol structures - * - * global variables: - * FILE *mfp Map output file handle - * sym *symhash[NHASH] array of pointers to NHASH - * linked symbol lists - * int xflag Map file radix type flag - * - * functions called: - * int fprintf() c_library - * VOID free() c_library - * char * malloc() c_library - * char putc() c_library - * VOID slew() lklist.c - * - * side effects: - * Map output generated. - */ - -#ifndef MLH_MAP -VOID -lstarea(xp) -struct area *xp; -{ - register struct areax *oxp; - register int i; - register char *ptr; - int nmsym; - Addr_T ai, aj; - struct sym *sp; - struct sym **p; - - putc('\n', mfp); - if (xflag == 0) { - fprintf(mfp, "Hexadecimal\n\n"); - } else - if (xflag == 1) { - fprintf(mfp, "Octal\n\n"); - } else - if (xflag == 2) { - fprintf(mfp, "Decimal\n\n"); - } - fprintf(mfp, "Area "); - fprintf(mfp, "Addr Size Decimal Bytes (Attributes)\n"); - fprintf(mfp, "-------------------------------- "); - fprintf(mfp, "---- ---- ------- ----- ------------\n"); - /* - * Output Area Header - */ - ptr = &xp->a_id[0]; - fprintf(mfp, "%-32s", ptr ); /* JLH: width matches --- above */ - ai = xp->a_addr; - aj = xp->a_size; - if (xflag == 0) { - fprintf(mfp, " %04X %04X", ai, aj); - } else - if (xflag == 1) { - fprintf(mfp, " %06o %06o", ai, aj); - } else - if (xflag == 2) { - fprintf(mfp, " %05u %05u", ai, aj); - } - fprintf(mfp, " = %6u. bytes ", aj); - if (xp->a_flag & A_ABS) { - fprintf(mfp, "(ABS"); - } else { - fprintf(mfp, "(REL"); - } - if (xp->a_flag & A_OVR) { - fprintf(mfp, ",OVR"); - } else { - fprintf(mfp, ",CON"); - } - if (xp->a_flag & A_PAG) { - fprintf(mfp, ",PAG"); - } - fprintf(mfp, ")"); - if (xp->a_flag & A_PAG) { - ai = (ai & 0xFF); - aj = (aj > 256); - if (ai || aj) { fprintf(mfp, " "); } - if (ai) { fprintf(mfp, " Boundary"); } - if (ai & aj) { fprintf(mfp, " /"); } - if (aj) { fprintf(mfp, " Length"); } - if (ai || aj) { fprintf(mfp, " Error"); } - } - - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - if (nmsym == 0) { - putc('\n', mfp); - return; - } - - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - - qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr); - - /* - * Symbol Table Output - */ - i = 0; - fprintf(mfp, "\n\n"); - fprintf(mfp, " Value Global\n"); - fprintf(mfp, " ----- --------------------------------"); - while (i < nmsym) { - fprintf(mfp, "\n"); - fprintf(mfp, " "); - - sp = p[i]; - aj = sp->s_addr + sp->s_axp->a_addr; - if (xflag == 0) { - fprintf(mfp, " %04X ", aj); - } else - if (xflag == 1) { - fprintf(mfp, "%06o ", aj); - } else - if (xflag == 2) { - fprintf(mfp, " %05u ", aj); - } - ptr = &sp->s_id[0]; - fprintf(mfp, "%s", ptr ); - i++; - } - putc('\n', mfp); - free(p); -} -#else -VOID lstarea(struct area *xp) -{ - register struct areax *oxp; - register int i, j; - int nmsym; - Addr_T a0, ai = 0, aj = 0; - struct sym *sp; - struct sym **p; - - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - - /* - * Symbol Table Output - */ - if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { - fprintf(mfp, "AREA %s\n", xp->a_id ); - switch (xflag) { - case 1: - fprintf(mfp, "\tRADIX OCTAL\n" ); - break; - case 2: - fprintf(mfp, "\tRADIX DEC\n" ); - break; - default: - fprintf(mfp, "\tRADIX HEX\n" ); - break; - } - fprintf( mfp, "\tBASE %04X\n" - "\tSIZE %04X\n" - "\tATTRIB " - , xp->a_addr, xp->a_size ); - if (xp->a_flag & A_ABS) { - fprintf(mfp, "ABS"); - } else { - fprintf(mfp, "REL"); - } - if (xp->a_flag & A_OVR) { - fprintf(mfp, " OVR"); - } else { - fprintf(mfp, " CON"); - } - if (xp->a_flag & A_PAG) { - fprintf(mfp, " PAG"); - } - if (xp->a_flag & A_PAG) { - ai = (ai & 0xFF); - aj = (aj > 256); - if (ai || aj) { fprintf(mfp, " "); } - if (ai) { fprintf(mfp, " Boundary"); } - if (ai & aj) { fprintf(mfp, " /"); } - if (aj) { fprintf(mfp, " Length"); } - if (ai || aj) { fprintf(mfp, " Error"); } - } - - fprintf( mfp,"\n"); - if (nmsym>0) { - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } - - fprintf( mfp, "\tGLOBALS\n"); - i = 0; - while (i < nmsym) { - fprintf(mfp, "\t\t%s\t%04X\n", p[i]->s_id, p[i]->s_addr + p[i]->s_axp->a_addr ); - i++; - } - free(p); - } - } -} -#endif /* MLH_MAP */ -#else - -/* NCPS == 8 */ -/*)Function VOID lstarea(xp) - * - * area * xp pointer to an area structure - * - * The function lstarea() creates the linker map output for - * the area specified by pointer xp. The generated output - * area header includes the area name, starting address, - * size of area, number of words (in decimal), and the - * area attributes. The symbols defined in this area are - * sorted by ascending address and output four per line - * in the selected radix. - * - * local variables: - * areax * oxp pointer to an area extension structure - * int c character value - * int i loop counter - * int j bubble sort update status - * char * ptr pointer to an id string - * int nmsym number of symbols in area - * Addr_T a0 temporary - * Addr_T ai temporary - * Addr_T aj temporary - * sym * sp pointer to a symbol structure - * sym ** p pointer to an array of - * pointers to symbol structures - * - * global variables: - * FILE *mfp Map output file handle - * sym *symhash[NHASH] array of pointers to NHASH - * linked symbol lists - * int xflag Map file radix type flag - * - * functions called: - * int fprintf() c_library - * VOID free() c_library - * char * malloc() c_library - * char putc() c_library - * VOID slew() lklist.c - * - * side effects: - * Map output generated. - */ - -VOID -lstarea(xp) -struct area *xp; -{ - register struct areax *oxp; - register c, i, j; - register char *ptr; - int nmsym; - Addr_T a0, ai, aj; - struct sym *sp; - struct sym **p; - - putc('\n', mfp); - slew(mfp); - /* - * Output Area Header - */ - ptr = &xp->a_id[0]; - while (ptr < &xp->a_id[NCPS]) { - if ((c = *ptr++) != 0) { - putc(c, mfp); - } else { - putc(' ', mfp); - } - } - ai = xp->a_addr; - aj = xp->a_size; - if (xflag == 0) { - fprintf(mfp, " %04X %04X", ai, aj); - } else - if (xflag == 1) { - fprintf(mfp, " %06o %06o", ai, aj); - } else - if (xflag == 2) { - fprintf(mfp, " %05u %05u", ai, aj); - } - fprintf(mfp, " = %6u. bytes ", aj); - if (xp->a_flag & A_ABS) { - fprintf(mfp, "(ABS"); - } else { - fprintf(mfp, "(REL"); - } - if (xp->a_flag & A_OVR) { - fprintf(mfp, ",OVR"); - } else { - fprintf(mfp, ",CON"); - } - if (xp->a_flag & A_PAG) { - fprintf(mfp, ",PAG"); - } - fprintf(mfp, ")"); - if (xp->a_flag & A_PAG) { - ai = (ai & 0xFF); - aj = (aj > 256); - if (ai || aj) { fprintf(mfp, " "); } - if (ai) { fprintf(mfp, " Boundary"); } - if (ai & aj) { fprintf(mfp, " /"); } - if (aj) { fprintf(mfp, " Length"); } - if (ai || aj) { fprintf(mfp, " Error"); } - } - - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - if (nmsym == 0) { - putc('\n', mfp); - slew(mfp); - return; - } - - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - slew(mfp); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - - qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr); - - /* - * Symbol Table Output - */ - i = 0; - while (i < nmsym) { - if (i % 4 == 0) { - fprintf(mfp, "\n"); - slew(mfp); - fprintf(mfp, " "); - } - sp = p[i]; - aj = sp->s_addr + sp->s_axp->a_addr; - if (xflag == 0) { - fprintf(mfp, " %04X ", aj); - } else - if (xflag == 1) { - fprintf(mfp, "%06o ", aj); - } else - if (xflag == 2) { - fprintf(mfp, " %05u ", aj); - } - ptr = &sp->s_id[0]; - fprintf(mfp, "%*s", NCPS, ptr ); - if (++i < nmsym) - if (i % 4 != 0) - fprintf(mfp, " | "); - } - putc('\n', mfp); - free(p); - slew(mfp); -} -#endif - -#ifdef SDK -VOID lstareatosym(struct area *xp) -{ - /* Output the current area symbols to a NO$GMB .sym file */ - register struct areax *oxp; - register int i, j; - int nmsym; - Addr_T a0, ai; - struct sym *sp; - struct sym **p; - - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - - /* - * Symbol Table Output - */ - if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { - /* Dont worry about any area information */ - fprintf(mfp, "; Area: %s\n", xp->a_id ); - if (nmsym>0) { - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } - i = 0; - while (i < nmsym) { - /* no$gmb requires the symbol names to be less than 32 chars long. Truncate. */ - char name[32]; - strncpy(name, p[i]->s_id, 31); - name[31] = '\0'; - if ((strncmp("l__", name, 3)!=0)&&(strchr(name,' ')==NULL)) { - a0=p[i]->s_addr + p[i]->s_axp->a_addr; - if (a0>0x7FFFU) { - /* Not inside the ROM, so treat as being in bank zero */ - fprintf(mfp, "00:%04X %s\n", a0, name); - } - else { - fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, name); - } - } - i++; - } - free(p); - } - } -} -#endif - -/*)Function VOID lkulist(i) - * - * int i i # 0 process LST to RST file - * i = 0 copy remainder of LST file - * to RST file and close files - * - * The function lkulist() creates a relocated listing (.rst) - * output file from the ASxxxx assembler listing (.lst) - * files. The .lst file's program address and code bytes - * are changed to reflect the changes made by ASlink as - * the .rel files are combined into a single relocated - * output file. - * - * local variables: - * Addr_T pc current program counter address - * - * global variables: - * int hilo byte order - * int gline get a line from the LST file - * to translate for the RST file - * char rb[] read listing file text line - * FILE *rfp The file handle to the current - * output RST file - * int rtcnt count of data words - * int rtflg[] output the data flag - * Addr_T rtval[] relocated data - * FILE *tfp The file handle to the current - * LST file being scanned - * - * functions called: - * int fclose() c_library - * int fgets() c_library - * int fprintf() c_library - * VOID lkalist() lklist.c - * VOID lkglist() lklist.c - * - * side effects: - * A .rst file is created for each available .lst - * file associated with a .rel file. - */ - -VOID -lkulist(i) -int i; -{ - Addr_T pc; - - /* - * Exit if listing file is not open - */ - if (tfp == NULL) - return; - - /* - * Normal processing of LST to RST - */ - if (i) { - /* - * Evaluate current code address - */ - if (hilo == 0) { - pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF); - } else { - pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF); - } - - /* - * Line with only address - */ - if (rtcnt == 2) { - lkalist(pc); - - /* - * Line with address and code - */ - } else { - for (i=2; i < rtcnt; i++) { - if (rtflg[i]) { - lkglist(pc++, rtval[i] & 0xFF); - } - } - } - - /* - * Copy remainder of LST to RST - */ - } else { - if (gline == 0) - fprintf(rfp, "%s", rb); - - while (fgets(rb, sizeof(rb), tfp) != 0) { - fprintf(rfp, "%s", rb); - } - fclose(tfp); - tfp = NULL; - fclose(rfp); - rfp = NULL; - } -} - -/*)Function VOID lkalist(pc) - * - * int pc current program counter value - * - * The function lkalist() performs the following functions: - * - * (1) if the value of gline = 0 then the current listing - * file line is copied to the relocated listing file output. - * - * (2) the listing file is read line by line and copied to - * the relocated listing file until a valid source - * line number and a program counter value of the correct - * radix is found. The new relocated pc value is substituted - * and the line is written to the RST file. - * - * local variables: - * int i loop counter - * char str[] temporary string - * - * global variables: - * int gcntr data byte counter - * int gline get a line from the LST file - * to translate for the RST file - * char rb[] read listing file text line - * char *rp pointer to listing file text line - * FILE *rfp The file handle to the current - * output RST file - * FILE *tfp The file handle to the current - * LST file being scanned - * - * functions called: - * int dgt() lklist.c - * int fclose() c_library - * int fgets() c_library - * int fprintf() c_library - * int sprintf() c_library - * char * strncpy() c_library - * - * side effects: - * Lines of the LST file are copied to the RST file, - * the last line copied has the code address - * updated to reflect the program relocation. - */ - -VOID -lkalist(pc) -Addr_T pc; -{ - char str[8]; - int i; - - /* - * Exit if listing file is not open - */ -loop: if (tfp == NULL) - return; - - /* - * Copy current LST to RST - */ - if (gline == 0) { - fprintf(rfp, "%s", rb); - gline = 1; - } - - /* - * Clear text line buffer - */ - for (i=0,rp=rb; i -#include -#include -#include "aslink.h" - -/*)Module lksym.c - * - * The module lksym.c contains the functions that operate - * on the symbol structures. - * - * lksym.c contains the following functions: - * int hash() - * sym * lkpsym() - * VOID * new() - * sym * newsym() - * VOID symdef() - * int symeq() - * VOID syminit() - * VOID symmod() - * Addr_T symval() - * - * lksym.c contains no local/static variables. - */ - -/*)Function VOID syminit() - * - * The function syminit() is called to clear the hashtable. - * - * local variables: - * int h computed hash value - * sym ** spp pointer to an array of - * sym structure pointers - * - * global variables: - * sym * symhash[] array of pointers to NHASH - * linked symbol lists - * - * functions called: - * none - * - * side effects: - * (1) The symbol hash tables are cleared - */ - -VOID -syminit() -{ - struct sym **spp; - - spp = &symhash[0]; - while (spp < &symhash[NHASH]) - *spp++ = NULL; -} - -/*)Function sym * newsym() - * - * The function newsym() is called to evaluate the symbol - * definition/reference directive from the .rel file(s). - * If the symbol is not found in the symbol table a new - * symbol structure is created. Evaluation of the - * directive determines if this is a reference or a definition. - * Multiple definitions of the same variable will be flagged - * as an error if the values are not identical. A symbol - * definition places the symbol value and area extension - * into the symbols data structure. And finally, a pointer - * to the symbol structure is placed into the head structure - * symbol list. Refer to the description of the header, symbol, - * area, and areax structures in lkdata.c for structure and - * linkage details. - * - * local variables: - * int c character from input text - * int i evaluation value - * char id[] symbol name - * int nglob number of symbols in this header - * sym * tsp pointer to symbol structure - * sym ** s list of pointers to symbol structures - * - * global variables: - * areax *axp Pointer to the current - * areax structure - * head *headp The pointer to the first - * head structure of a linked list - * int lkerr error flag - * - * functions called: - * Addr_T eval() lkeval.c - * VOID exit() c_library - * int fprintf() c_library - * char getSid() lklex.c - * char get() lklex.c - * char getnb() lklex.c - * sym * lkpsym() lksym.c - * - * side effects: - * A symbol structure is created and/or modified. - * If structure space allocation fails linker will abort. - * Several severe errors (these are internal errors - * indicating a corrupted .rel file or corrupted - * assembler or linker) will terminated the linker. - */ - -/* - * Find/Create a global symbol entry. - * - * S xxxxxx Defnnnn - * | | | - * | | `-- sp->s_addr - * | `----- sp->s_type - * `------------ sp->s_id - * - */ -struct sym * -newsym() -{ - register unsigned i ; - register unsigned nglob ; - register int c ; - struct sym *tsp; - struct sym **s; - char id[NCPS]; - - getSid(id); // old: getid(id, -1); - tsp = lkpsym(id, 1); - c = getnb();get();get(); - if (c == 'R') { - tsp->s_type |= S_REF; - if (eval()) { - fprintf(stderr, "Non zero S_REF\n"); - lkerr++; - } - } else - if (c == 'D') { - i = eval(); - if (tsp->s_type & S_DEF && tsp->s_addr != i) { -#ifdef SDK - fprintf(stderr, "Multiple definition of %s\n", id); -#else - fprintf(stderr, "Multiple definition of %.8s\n", id); -#endif - lkerr++; - } - tsp->s_type |= S_DEF; - /* - * Set value and area extension link. - */ - tsp->s_addr = i; - tsp->s_axp = axp; - } else { - fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id); - lkexit(1); - } - /* - * Place pointer in header symbol list - */ - if (headp == NULL) { - fprintf(stderr, "No header defined\n"); - lkexit(1); - } - nglob = hp->h_nglob; - s = hp->s_list; - for (i=0; i < nglob ;++i) { - if (s[i] == NULL) { - s[i] = tsp; - return(tsp); - } - } - fprintf(stderr, "Header symbol list overflow\n"); - lkexit(1); - - /* Never reached */ - return(0); -} - -/*)Function sym * lkpsym(id,f) - * - * char * id symbol name string - * int f f == 0, lookup only - * f != 0, create if not found - * - * The function lookup() searches the symbol hash tables for - * a symbol name match returning a pointer to the sym structure. - * If the symbol is not found then a sym structure is created, - * initialized, and linked to the appropriate hash table if f != 0. - * A pointer to this new sym structure is returned or a NULL - * pointer is returned if f == 0. - * - * local variables: - * int h computed hash value - * sym * sp pointer to a sym structure - * - * global varaibles: - * sym * symhash[] array of pointers to NHASH - * linked symbol lists - * - * functions called: - * int hash() lksym.c - * VOID * new() lksym.c - * int symeq() lksym.c - * - * side effects: - * If the function new() fails to allocate space - * for the new sym structure the linker terminates. - */ - -struct sym * -lkpsym(id, f) -char *id; -{ - register struct sym *sp; - register int h; - - h = hash(id); - sp = symhash[h]; - while (sp != NULL) { - if (symeq(id, sp->s_id)) - return (sp); - sp = sp->s_sp; - } - if (f == 0) - return (NULL); - sp = (struct sym *) new (sizeof(struct sym)); - sp->s_sp = symhash[h]; - symhash[h] = sp; - sp->s_id = StoreString( id ); /* JLH */ - return (sp); -} - -/*)Function Addr_T symval(tsp) - * - * sym * tsp pointer to a symbol structure - * - * The function symval() returns the value of the - * relocated symbol by adding the variable definition - * value to the areax base address. - * - * local variables: - * Addr_T val relocated address value - * - * global variables: - * none - * - * functions called: - * none - * - * side effects: - * none - */ - -Addr_T -symval(tsp) -register struct sym *tsp; -{ - register Addr_T val; - - val = tsp->s_addr; - if (tsp->s_axp) { - val += tsp->s_axp->a_addr; - } - return(val); -} - -/*)Function VOID symdef(fp) - * - * FILE * fp file handle for output - * - * The function symdef() scans the hashed symbol table - * searching for variables referenced but not defined. - * Undefined variables are linked to the default - * area "_CODE" and reported as referenced by the - * appropriate module. - * - * local variables: - * int i hash table index loop variable - * sym * sp pointer to linked symbol structure - * - * global variables: - * area *areap The pointer to the first - * area structure of a linked list - * sym *symhash[NHASH] array of pointers to NHASH - * linked symbol lists - * - * functions called: - * symmod() lksym.c - * - * side effects: - * Undefined variables have their areas set to "_CODE". - */ - -VOID -symdef(fp) -FILE *fp; -{ - register struct sym *sp; - register int i; - - for (i=0; is_axp == NULL) - sp->s_axp = areap->a_axp; - if ((sp->s_type & S_DEF) == 0) - symmod(fp, sp); - sp = sp->s_sp; - } - } -} - -/*)Function VOID symmod(fp,tsp) - * - * FILE * fp output file handle - * sym * tsp pointer to a symbol structure - * - * The function symmod() scans the header structures - * searching for a reference to the symbol structure - * pointer to by tsp. The function then generates an error - * message whichs names the module having referenced the - * undefined variable. - * - * local variables: - * int i loop counter - * sym ** p pointer to a list of pointers - * to symbol structures - * - * global variables: - * head *headp The pointer to the first - * head structure of a linked list - * head *hp Pointer to the current - * head structure - * int lkerr error flag - * - * functions called: - * int fprintf() c_library - * - * side effects: - * Error output generated. - */ - -VOID -symmod(fp, tsp) -FILE *fp; -struct sym *tsp; -{ - register int i; - struct sym **p; - - if ((hp = headp) != NULL) { - while(hp) { - p = hp->s_list; - for (i=0; ih_nglob; ++i) { - if (p[i] == tsp) { - fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id); - fprintf(fp, "referenced by module '%s'\n", hp->m_id); - lkerr++; - } - } - hp = hp->h_hp; - } - } -} - -/*)Function int symeq(p1, p2) - * - * char * p1 name string - * char * p2 name string - * - * The function symeq() compares the two name strings for a match. - * The return value is 1 for a match and 0 for no match. - * - * local variables: - * int h loop counter - * - * global variables: - * char ccase[] an array of characters which - * perform the case translation function - * - * functions called: - * none - * - * side effects: - * none - * - */ - -int -symeq(p1, p2) -register char *p1, *p2; -{ -#if CASE_SENSITIVE - return (strncmp( p1, p2, NCPS ) == 0); -#else - return (as_strncmpi( p1, p2, NCPS ) == 0); -#endif -} - -/*)Function int hash(p) - * - * char * p pointer to string to hash - * - * The function hash() computes a hash code using the sum - * of all characters mod table size algorithm. - * - * local variables: - * int h accumulated character sum - * int n loop counter - * - * global variables: - * char ccase[] an array of characters which - * perform the case translation function - * - * functions called: - * none - * - * side effects: - * none - * - */ - -int -hash(p) -register char *p; -{ - register int h, n; - - h = 0; - n = NCPS; - do { - -#if CASE_SENSITIVE - h += *p++; -#else - h += ccase[(unsigned char)(*p++)]; -#endif - - } while (--n); - return (h&HMASK); -} - -/*)Function VOID * new(n) - * - * unsigned int n allocation size in bytes - * - * The function new() allocates n bytes of space and returns - * a pointer to this memory. If no space is available the - * linker is terminated. - * - * local variables: - * char * p a general pointer - * char * q a general pointer - * - * global variables: - * none - * - * functions called: - * int fprintf() c_library - * VOID * malloc() c_library - * - * side effects: - * Memory is allocated, if allocation fails - * the linker is terminated. - */ - -VOID * -new(n) -unsigned int n; -{ - register char *p; - - if ((p = (char *) calloc(n, 1)) == NULL) { - fprintf(stderr, "Out of space!\n"); - lkexit(1); - } - return (p); -}