+2007-03-14 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * 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 <jesusc at ece.ubc.ca>
* device/include/mcs51/P89LPC925.h: Added missing P1_6 and P1_7.
2007-03-13 Borut Razem <borut.razem AT siol.net>
- * 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:
#endif
#endif
+#ifdef SDK
+ #define LKOBJEXT "o"
+#else /* SDK */
+ #define LKOBJEXT "rel"
+#endif /* SDK */
+
/*
* This file defines the format of the
* relocatable binary file.
!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
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)
CFG=link_hc08 - Win32 Debug\r
!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE NMAKE /f "link_hc08.mak".\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE You can specify a configuration when running NMAKE\r
!MESSAGE by defining the macro CFG on the command line. For example:\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE NMAKE /f "link_hc08.mak" CFG="link_hc08 - Win32 Debug"\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE "link_hc08 - Win32 Release" (based on "Win32 (x86) Console Application")\r
!MESSAGE "link_hc08 - Win32 Debug" (based on "Win32 (x86) Console Application")\r
-!MESSAGE \r
+!MESSAGE\r
\r
# Begin Project\r
# PROP AllowPerConfigDependencies 0\r
# 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\r
# 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\r
\r
-!ENDIF \r
+!ENDIF\r
\r
# Begin Target\r
\r
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
-SOURCE=.\lkaomf51.c\r
+SOURCE=..\lkaomf51.c\r
# End Source File\r
# Begin Source File\r
\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkdata.c\r
+SOURCE=..\lkdata.c\r
# End Source File\r
# Begin Source File\r
\r
+++ /dev/null
-/*-------------------------------------------------------------------------
- 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 <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#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<numin; j++)
- {
- if(EQ(infn[numin].PathName, infn[j].PathName)) break;
- }
- if(j==numin) numin++;
- }
-}
-
-void FreeAll(void)
-{
- if(infn!=NULL)
- {
- free(infn);
- numin=0;
- infn=NULL;
- }
-
- if(symbol!=NULL)
- {
- free(symbol);
- numsym=0;
- symbol=NULL;
- }
-
- if(procedure!=NULL)
- {
- free(procedure);
- numproc=0;
- procedure=NULL;
-
- }
- if(linenum!=NULL)
- {
- free(linenum);
- numlinenum=0;
- linenum=NULL;
- }
-
- if(ihxBuff!=NULL)
- {
- free(ihxBuff);
- ihxBuff=NULL;
- }
-}
-
-void OutputByte(unsigned char value)
-{
- GlobalChkSum+=value;
- fwrite( &value, 1, 1, aomf51out );
-}
-
-void OutputWord(int value)
-{
- OutputByte((unsigned char)(value%0x100));
- OutputByte((unsigned char)(value/0x100));
-}
-
-void OutputName(char * name)
-{
- int k;
- OutputByte((unsigned char)strlen(name));
- for(k=0; name[k]!=0; k++)
- OutputByte((unsigned char)toupper(name[k]));
-}
-
-void OutputChkSum(void)
-{
- OutputByte((unsigned char)(0x100-(GlobalChkSum%0x100)));
- GlobalChkSum=0;
-}
-
-#ifdef DODUMP
-void DumpForDebug (void)
-{
- char DumpFileName[PATH_MAX];
- FILE * DumpFile;
- int j, k;
-
- strcpy(DumpFileName, infn[0].PathName);
- strcat(DumpFileName, ".d51");
-
- DumpFile=fopen(DumpFileName, "wb");
- if(DumpFile==NULL)
- {
- printf("Couldn't create file %s\n", DumpFileName);
- return;
- }
-
- fprintf(DumpFile,"SYMBOLS:\n");
-
- for(j=0; j<numsym; j++)
- {
- k=symbol[j].UsageType&0xf;
- fprintf(DumpFile, "%s, %s, %s, 0x%04x, %s\n",
- symbol[j].name,
- infn[symbol[j].FileNameNumber].PathName,
- (symbol[j].Procedure>=0)?procedure[symbol[j].Procedure].name:"GLOBAL",
- symbol[j].Address,
- k<6?UsageTypeName[k]:"???");
- }
-
- fprintf(DumpFile,"\nPROCEDURES:\n");
- for(j=0; j<numproc; j++)
- {
- fprintf(DumpFile, "%s, %s, 0x%04x-0x%04x\n",
- procedure[j].name,
- infn[procedure[j].FileNameNumber].PathName,
- procedure[j].BeginAdd,
- procedure[j].EndAdd);
- }
-
- fprintf(DumpFile,"\nLINE NUMBERS:\n");
- for(j=0; j<numlinenum; j++)
- {
- fprintf(DumpFile, "%d:0x%04x, %s -> %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; j<numin; j++)
- {
- GetName(infn[j].PathName, Mname);
-
- /*Scope Definition record: begin module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x00);/*BLK TYP: module block*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
-
- /*Public symbols defined in this module*/
- recsize=2;
- for(k=0; k<numsym; k++)/*Compute the record length*/
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==-1) ) recsize+=((strlen(symbol[k].name)+1)+5);
-
- if(recsize>2) /*If there are any symbols*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x01); /*DEF TYPE: Public symbols*/
- for(k=0; k<numsym; k++)
- {
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==-1) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
- OutputWord(symbol[k].Address);/*Offset*/
- OutputByte(0x00);
- OutputName(symbol[k].name);/*Symbol name*/
- }
- }
- OutputChkSum();
- }
-
- /*Local symbols defined in this module*/
- recsize=2;
- for(k=0; k<numsym; k++)/*Compute the record length*/
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==j) ) recsize+=((strlen(symbol[k].name)+1)+5);
-
- if(recsize>2) /*If there are any symbols*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x00); /*DEF TYPE: Local symbols*/
- for(k=0; k<numsym; k++)
- {
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==j) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
- OutputWord(symbol[k].Address);/*Offset*/
- OutputByte(0x00);
- OutputName(symbol[k].name);/*Symbol name*/
- }
- }
- OutputChkSum();
- }
-
- /*Output the procedures of this module*/
-
- for(k=0; k<numproc; k++)
- {
- if(procedure[k].FileNameNumber==j)
- {
- /*Scope Definition record: begin PROCEDURE block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
- OutputByte(0x02);/*BLK TYP: PROCEDURE block*/
- OutputName(procedure[k].name);/*Module Name*/
- OutputChkSum();
-
- /*Content Record*/
- OutputByte(0x06);/*REC TYPE*/
- if(procedure[k].EndAdd==-1) procedure[k].EndAdd=HexSize;
- recsize=procedure[k].EndAdd-procedure[k].BeginAdd+1+4;
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x00);/*SEG ID*/
- OutputWord(procedure[k].BeginAdd); /*Offset*/
- for(i=procedure[k].BeginAdd; i<=procedure[k].EndAdd; i++)
- OutputByte(ihxBuff[i]);
- OutputChkSum();
-
- /*Local Symbols*/
-
- recsize=2;
- for(i=0; i<numsym; i++)/*Get the record length*/
- if(symbol[i].Procedure==k)
- recsize+=((strlen(symbol[i].name)+1)+5);
-
- if(recsize>2) /*If there are any symbols*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x00); /*DEF TYPE: Local symbols*/
- for(i=0; i<numsym; i++)
- {
- if ( (symbol[i].Procedure==k) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputByte((unsigned char)symbol[i].UsageType);/*SYM INFO*/
- OutputWord(symbol[i].Address);/*Offset*/
- OutputByte(0x00);
- OutputName(symbol[i].name);/*Symbol name*/
- }
- }
- OutputChkSum();
- }
-
- /*Line Numbers*/
- recsize=2;
- for(i=0; i<numlinenum; i++)/*Get the record length*/
- if(linenum[i].Procedure==k) recsize+=5;
-
- if(recsize>2) /*If there are any line numbers*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x03); /*DEF TYPE: Line numbers*/
- for(i=0; i<numlinenum; i++)
- {
- if ( (linenum[i].Procedure==k) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputWord(linenum[i].Address);/*Offset*/
- OutputWord(linenum[i].Number);/*Line Number*/
- }
- }
- OutputChkSum();
- }
-
- /*Scope Definition record: end PROCEDURE block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
- OutputByte(0x05);/*BLK TYP: PROCEDURE end block*/
- OutputName(procedure[k].name);/*Module Name*/
- OutputChkSum();
- }
- }
-
- /*Scope Definition record: end module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x03);/*BLK TYP: module end*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
- }
-
- /*Content records for everything that is not in the above procedures*/
- strcpy(Mname, "OTHER_SDCC_STUF");
-
- /*Scope Definition record: begin module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x00);/*BLK TYP: module block*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
-
- for(j=-1; j<numproc; j++)
- {
- if(numproc)
- {
- if(j==-1)
- {
- i=HexBegin;
- k=procedure[0].BeginAdd;
- }
- else if(j==(numproc-1))
- {
- i=procedure[j].EndAdd+1;
- k=HexSize;
- }
- else
- {
- i=procedure[j].EndAdd+1;
- k=procedure[j+1].BeginAdd;
- }
- }
- else /*What, no procedures??? Ok, here it is the whole hex file*/
- {
- i=HexBegin;
- k=HexSize;
- }
-
- if(i<k)
- {
- /*Content Record*/
- OutputByte(0x06);/*REC TYPE*/
- OutputWord(k-i+4);/*Record Length*/
- OutputByte(0x00);/*SEG ID*/
- OutputWord(i); /*Offset*/
- for(; i<k; i++) OutputByte(ihxBuff[i]);
- OutputChkSum();
- }
- }
-
- /*Scope Definition record: end module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x03);/*BLK TYP: module end*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
-
- /*Module end record*/
- OutputByte(0x04);/*REC TYPE*/
- OutputWord((strlen(MHRname)+1)+5);/*Record Length*/
- OutputName(MHRname);/*Module Name*/
- OutputWord(0x00);
- OutputByte(0x0f);/*REG MSK: All the register banks?*/
- OutputByte(0x00);
- OutputChkSum();
-
- fclose(aomf51out);
-}
-
-void CollectInfoFromCDB(void)
-{
- int i, j, k, CurrentModule;
- FILE * CDBin;
- char buff[0x1000];
- char SourceName[PATH_MAX];
-
- //"S:{G|F<filename>|L<functionName>}$<name>$<level>$<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>"
- 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<numin; j++)
- if(EQ(infn[j].ModuleName, name)) break;
- if(j<numin) CurrentModule=j;
- break;
-
- /* Example:
- "S:G$actual$0$0({7}ST__00010000:S),E,0,0"
- "S:Lmain$j$1$1({2}SI:S),E,0,0"
- "S:G$DS1306_Reset_SPI$0$0({2}DF,SV:S),C,0,0"
- "S:G$main$0$0({2}DF,SV:S),C,0,0"
- */
-
- case 'S':
- sscanf(buff, Sfmt,
- scope, &c,
- name, &c,
- level, &c,
- block);
-
- /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>*/
- 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<numproc; j++)
- {
- if(EQ(&scope[3], procedure[j].name)) break;
- }
- if(j<numproc) k=j; /*Local symbol*/
- break;
- case 'F': /*Local symbol to a module*/
- for(j=0; j<numin; j++)
- {
- if(EQ(&scope[3], infn[j].ModuleName)) break;
- }
- if(j<numin) i=j;
- break;
- }
-
- /*This symbol may have been already defined*/
- for(j=0; j<numsym; j++)
- {
- if( EQ(name, symbol[j].name) &&
- (symbol[j].Procedure==k) &&
- (symbol[j].Static==i) ) break;
- }
- if(j==numsym) /*New symbol*/
- {
- symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
- symbol[numsym].FileNameNumber=CurrentModule;
- strcpy(symbol[numsym].name, name);
- symbol[numsym].Procedure=k;
- symbol[numsym].Static=i;
- symbol[numsym].Address=-1;/*Collected later*/
-
- switch(AddressSpace)
- {
- case 'C': /*Code*/
- case 'D': /*Code/static segment*/
- case 'Z': /*Functions and undefined code space*/
- symbol[numsym].UsageType=0x40;
- break;
-
- case 'F': /*External ram*/
- case 'A': /*External stack*/
- symbol[numsym].UsageType=0x41;
- break;
-
- case 'E': /*Internal ram (lower 128) bytes*/
- case 'I': /*SFR space*/
- case 'R': /*Register Space*/
- symbol[numsym].UsageType=0x42;
- break;
-
- case 'B': /*Internal stack*/
- case 'G': /*Internal ram*/
- symbol[numsym].UsageType=0x43;
- break;
-
- case 'H': /*Bit addressable*/
- case 'J': /*SBIT space*/
- symbol[numsym].UsageType=0x44;
- break;
-
- default:
- printf("Unknown scope information for: %s, AddressSpace:%c\n", symbol[numsym].name, AddressSpace);
- break;
- }
- numsym++;
- }
- break;
-
- /*Examples:
- F:G$AsciiToHex$0$0({2}DF,SC:U),C,0,0,0,0,0
- F:G$main$0$0({2}DF,SV:S),C,0,0,0,0,0 */
-
- case 'F':
- sscanf(buff, "%[^$] %c %[^$]", scope, &c, name);
- /*The same may have been already defined */
- for(j=0; j<numproc; j++)
- {
- if(EQ(name, procedure[j].name)) break;
- }
- if(j==numproc)
- {
- procedure=realloc(procedure, sizeof(_procedure)*(numproc+1));
- strcpy(procedure[numproc].name, name);
- procedure[numproc].FileNameNumber=CurrentModule;
- procedure[numproc].BeginAdd=-1;/*To be collected latter*/
- procedure[numproc].EndAdd=-1;/*To be collected latter*/
- numproc++;
- }
-
- /*This function name is also a global symbol*/
- for(j=0; j<numsym; j++)/*A global symbol may have been already defined*/
- {
- if( EQ(name, symbol[j].name) && (symbol[j].Procedure==-1) ) break;
- }
- if(j==numsym)
- {
- symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
- symbol[numsym].FileNameNumber=CurrentModule;
- strcpy(symbol[numsym].name, name);
- symbol[numsym].UsageType=0x00;/*A procedure name symbol*/
- symbol[numsym].Procedure=-1; /*Global symbol*/
- symbol[numsym].Address=-1;/*Collected later*/
- numsym++;
- }
- break;
-
- case 'L':
- switch(buff[2])
- {
- case 'G': /*Example L:G$P0$0$0:80*/
- sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(j=0; j<numsym; j++)
- {
- if(EQ(symbol[j].name, name))
- {
- if( (symbol[j].Address==-1) && (symbol[j].Procedure==-1) )
- {
- symbol[j].Address=Address;
- }
-
- /*If the symbol is the name of a procedure, the address is also
- the begining of such procedure*/
- if((symbol[j].UsageType&0x0f)==0x00)
- {
- for(k=0; k<numproc; k++)
- {
- if(EQ(symbol[j].name, procedure[k].name))
- {
- if(procedure[k].BeginAdd==-1)
- procedure[k].BeginAdd=Address;
- break;
- }
- }
- }
-
- break;
- }
- }
- break;
-
- case 'F': /*Example L:Fadq$_str_2$0$0:57A*/
- sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(j=0; j<numsym; j++)
- {
- if(EQ(symbol[j].name, name))
- {
- if( (symbol[j].Address==-1) ) symbol[j].Address=Address;
- break;
- }
- }
-
- /*It could be also a static function*/
- for(j=0; j<numproc; j++)
- {
- if(EQ(procedure[j].name, name))
- {
- if( (procedure[j].BeginAdd==-1) ) procedure[j].BeginAdd=Address;
- break;
- }
- }
-
- break;
-
- case 'L': /*Example L:Lmain$j$1$1:29*/
-
- /*
- L:LDS1306_Write$Value$1$1:34
- L:LDS1306_Burst_Read$count$1$1:35
- L:LDS1306_Burst_Read$address$1$1:36
- L:LDS1306_Burst_Write$count$1$1:37
- L:LDS1306_Burst_Write$address$1$1:38
- */
- sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(k=0; k<numproc; k++)
- {
- if(EQ(procedure[k].name, scope)) break;
- }
-
- if(k<numproc) for(j=0; j<numsym; j++)
- {
- if( EQ(symbol[j].name, name) && (symbol[j].Procedure==k) )
- {
- if(symbol[j].Address==-1) symbol[j].Address=Address;
- break;
- }
- }
- break;
-
- /*Line Numbers*/
- case 'C': /*Example L:C$adq.c$38$1$1:3E*/ /*L:C$hwinit.c$29$1$1:7AD*/
- sscanf(&buff[4], "%[^.] %[^$] %c %d %[^:] %c %x",
- name, level, &c, &CLine, level, &c, &Address);
-
- for(j=0; j<numin; j++)
- if(EQ(infn[j].ModuleName, name)) break;
- if(j<numin)
- {
- /*Check if this line is already defined*/
- for(k=0; k<numlinenum; k++)
- {
- if( (linenum[k].Number==CLine) &&
- (linenum[k].FileNameNumber==j) )break;
- }
- if(k==numlinenum) /*New line number*/
- {
- linenum=realloc(linenum, sizeof(_linenum)*(numlinenum+1));
- linenum[numlinenum].Number=CLine;
- linenum[numlinenum].FileNameNumber=j;
- linenum[numlinenum].Procedure=-1;/*To be asigned later*/
- linenum[numlinenum].Address=Address;
- numlinenum++;
- }
- }
- break;
-
- case 'A': /*Example L:A$adq$424:40*/
- /*No use for this one*/
- break;
-
- /*The end of a procedure*/
- case 'X': /*Example L:XG$AsciiToHex$0$0:88*/
- sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(k=0; k<numproc; k++)
- {
- if(EQ(procedure[k].name, name))
- {
- if(procedure[k].EndAdd==-1) procedure[k].EndAdd=Address;
- break;
- }
- }
- break;
- }
- break;
-
- default:
- break;
- }
- }
-
- /*Make sure each procedure has an end*/
- for(k=0; k<(numproc-1); k++)
- {
- if (procedure[k].EndAdd==-1) procedure[k].EndAdd=procedure[k+1].BeginAdd-1;
- }
- /*Asign each line number to a procedure*/
- for(j=0; j<numlinenum; j++)
- {
- for(k=0; k<numproc; k++)
- {
- if ( (linenum[j].Address>=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<MEMSIZE; j++) ihxBuff[j]=0xff;
-
- while(1)
- {
- if(fgets(buffer, sizeof(buffer), filein)==NULL)
- {
- printf("Error reading file '%s'\n", ihxFileName);
- break;
- }
- if(buffer[0]==':')
- {
- linesize = GetByte(&buffer[1]);
- address = GetWord(&buffer[3]);
- recordtype = GetByte(&buffer[7]);
- rchksum = GetByte(&buffer[9]+(linesize*2));
- chksum=linesize+(address/0x100)+(address%0x100)+recordtype+rchksum;
-
- if (recordtype==1) break; /*End of record*/
-
- for(j=0; j<linesize; j++)
- {
- value=GetByte(&buffer[9]+(j*2));
- chksum+=value;
- ihxBuff[address+j]=value;
- }
- if(MaxAddress<(address+linesize-1)) MaxAddress=(address+linesize-1);
- if(address<*Begin) *Begin=address;
-
- if((chksum%0x100)!=0)
- {
- printf("ERROR: Bad checksum in file %s\n", ihxFileName);
- fclose(filein);
- return -1;
- }
- }
- }
- fclose(filein);
-
- return MaxAddress;
-}
-
-void CreateAOMF51(void)
-{
- if((dflag) && (!rflag))
- {
- CollectInfoFromCDB();
- #ifdef DODUMP
- DumpForDebug();
- #endif
- HexSize=ReadHexFile(&HexBegin)+1;
- OutputAOEMF51();
- FreeAll();
- }
-}
+++ /dev/null
-/* lkdata.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- *
- * 28-Oct-97 JLH:
- * - change s_id from [NCPS] to pointer (comment)
- * 31-Oct-97 JLH:
- * - add jflag and jfp for NoICE output
- */
-
-#include <stdio.h>
-#include <string.h>
-#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
*
* 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
*/
ip=rel[j];
link_main();
}
-
+
/*Set the start address of the default areas:*/
for(ap=areap; ap; ap=ap->a_ap)
{
case 'F':
startp->f_type = F_LNK;
break;
-
+
case 'n':
case 'N':
pflag = 0;
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);
}
filep = linkp;
hp = NULL;
radix = 10;
-
+
Areas51(); /*JCF: Create the default 8051 areas in the right order*/
while (lk_getline()) {
case 'z':
case 'Z':
- dflag = 1;
+ dflag = 1;
return(0);
default:
fprintf(stderr, "Invalid option\n");
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
char fb[PATH_MAX];
char *omode;
int i;
-
+
switch (wf) {
case 0: omode = "r"; break;
case 1: omode = "w"; break;
strcat(fb, ".");
strcat(fb, strlen(ft)?ft:"rel");
}
-
+
fp = fopen(fb, omode);
if (fp==NULL)
{
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);
}
}
--- /dev/null
+/*-------------------------------------------------------------------------
+ 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 <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#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<numin; j++)
+ {
+ if(EQ(infn[numin].PathName, infn[j].PathName)) break;
+ }
+ if(j==numin) numin++;
+ }
+}
+
+void FreeAll(void)
+{
+ if(infn!=NULL)
+ {
+ free(infn);
+ numin=0;
+ infn=NULL;
+ }
+
+ if(symbol!=NULL)
+ {
+ free(symbol);
+ numsym=0;
+ symbol=NULL;
+ }
+
+ if(procedure!=NULL)
+ {
+ free(procedure);
+ numproc=0;
+ procedure=NULL;
+
+ }
+ if(linenum!=NULL)
+ {
+ free(linenum);
+ numlinenum=0;
+ linenum=NULL;
+ }
+
+ if(ihxBuff!=NULL)
+ {
+ free(ihxBuff);
+ ihxBuff=NULL;
+ }
+}
+
+void OutputByte(unsigned char value)
+{
+ GlobalChkSum+=value;
+ fwrite( &value, 1, 1, aomf51out );
+}
+
+void OutputWord(int value)
+{
+ OutputByte((unsigned char)(value%0x100));
+ OutputByte((unsigned char)(value/0x100));
+}
+
+void OutputName(char * name)
+{
+ int k;
+ OutputByte((unsigned char)strlen(name));
+ for(k=0; name[k]!=0; k++)
+ OutputByte((unsigned char)toupper(name[k]));
+}
+
+void OutputChkSum(void)
+{
+ OutputByte((unsigned char)(0x100-(GlobalChkSum%0x100)));
+ GlobalChkSum=0;
+}
+
+#ifdef DODUMP
+void DumpForDebug (void)
+{
+ char DumpFileName[PATH_MAX];
+ FILE * DumpFile;
+ int j, k;
+
+ strcpy(DumpFileName, infn[0].PathName);
+ strcat(DumpFileName, ".d51");
+
+ DumpFile=fopen(DumpFileName, "wb");
+ if(DumpFile==NULL)
+ {
+ printf("Couldn't create file %s\n", DumpFileName);
+ return;
+ }
+
+ fprintf(DumpFile,"SYMBOLS:\n");
+
+ for(j=0; j<numsym; j++)
+ {
+ k=symbol[j].UsageType&0xf;
+ fprintf(DumpFile, "%s, %s, %s, 0x%04x, %s\n",
+ symbol[j].name,
+ infn[symbol[j].FileNameNumber].PathName,
+ (symbol[j].Procedure>=0)?procedure[symbol[j].Procedure].name:"GLOBAL",
+ symbol[j].Address,
+ k<6?UsageTypeName[k]:"???");
+ }
+
+ fprintf(DumpFile,"\nPROCEDURES:\n");
+ for(j=0; j<numproc; j++)
+ {
+ fprintf(DumpFile, "%s, %s, 0x%04x-0x%04x\n",
+ procedure[j].name,
+ infn[procedure[j].FileNameNumber].PathName,
+ procedure[j].BeginAdd,
+ procedure[j].EndAdd);
+ }
+
+ fprintf(DumpFile,"\nLINE NUMBERS:\n");
+ for(j=0; j<numlinenum; j++)
+ {
+ fprintf(DumpFile, "%d:0x%04x, %s -> %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; j<numin; j++)
+ {
+ GetName(infn[j].PathName, Mname);
+
+ /*Scope Definition record: begin module block*/
+ OutputByte(0x10);/*REC TYPE*/
+ OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+ OutputByte(0x00);/*BLK TYP: module block*/
+ OutputName(Mname);/*Module Name*/
+ OutputChkSum();
+
+ /*Public symbols defined in this module*/
+ recsize=2;
+ for(k=0; k<numsym; k++)/*Compute the record length*/
+ if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+ (symbol[k].Procedure==-1) &&
+ (symbol[k].Static==-1) ) recsize+=((strlen(symbol[k].name)+1)+5);
+
+ if(recsize>2) /*If there are any symbols*/
+ {
+ OutputByte(0x12); /*REC TYPE*/
+ OutputWord(recsize);/*Record Length*/
+ OutputByte(0x01); /*DEF TYPE: Public symbols*/
+ for(k=0; k<numsym; k++)
+ {
+ if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+ (symbol[k].Procedure==-1) &&
+ (symbol[k].Static==-1) )
+ {
+ OutputByte(0x00);/*SEG ID*/
+ OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
+ OutputWord(symbol[k].Address);/*Offset*/
+ OutputByte(0x00);
+ OutputName(symbol[k].name);/*Symbol name*/
+ }
+ }
+ OutputChkSum();
+ }
+
+ /*Local symbols defined in this module*/
+ recsize=2;
+ for(k=0; k<numsym; k++)/*Compute the record length*/
+ if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+ (symbol[k].Procedure==-1) &&
+ (symbol[k].Static==j) ) recsize+=((strlen(symbol[k].name)+1)+5);
+
+ if(recsize>2) /*If there are any symbols*/
+ {
+ OutputByte(0x12); /*REC TYPE*/
+ OutputWord(recsize);/*Record Length*/
+ OutputByte(0x00); /*DEF TYPE: Local symbols*/
+ for(k=0; k<numsym; k++)
+ {
+ if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+ (symbol[k].Procedure==-1) &&
+ (symbol[k].Static==j) )
+ {
+ OutputByte(0x00);/*SEG ID*/
+ OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
+ OutputWord(symbol[k].Address);/*Offset*/
+ OutputByte(0x00);
+ OutputName(symbol[k].name);/*Symbol name*/
+ }
+ }
+ OutputChkSum();
+ }
+
+ /*Output the procedures of this module*/
+
+ for(k=0; k<numproc; k++)
+ {
+ if(procedure[k].FileNameNumber==j)
+ {
+ /*Scope Definition record: begin PROCEDURE block*/
+ OutputByte(0x10);/*REC TYPE*/
+ OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
+ OutputByte(0x02);/*BLK TYP: PROCEDURE block*/
+ OutputName(procedure[k].name);/*Module Name*/
+ OutputChkSum();
+
+ /*Content Record*/
+ OutputByte(0x06);/*REC TYPE*/
+ if(procedure[k].EndAdd==-1) procedure[k].EndAdd=HexSize;
+ recsize=procedure[k].EndAdd-procedure[k].BeginAdd+1+4;
+ OutputWord(recsize);/*Record Length*/
+ OutputByte(0x00);/*SEG ID*/
+ OutputWord(procedure[k].BeginAdd); /*Offset*/
+ for(i=procedure[k].BeginAdd; i<=procedure[k].EndAdd; i++)
+ OutputByte(ihxBuff[i]);
+ OutputChkSum();
+
+ /*Local Symbols*/
+
+ recsize=2;
+ for(i=0; i<numsym; i++)/*Get the record length*/
+ if(symbol[i].Procedure==k)
+ recsize+=((strlen(symbol[i].name)+1)+5);
+
+ if(recsize>2) /*If there are any symbols*/
+ {
+ OutputByte(0x12); /*REC TYPE*/
+ OutputWord(recsize);/*Record Length*/
+ OutputByte(0x00); /*DEF TYPE: Local symbols*/
+ for(i=0; i<numsym; i++)
+ {
+ if ( (symbol[i].Procedure==k) )
+ {
+ OutputByte(0x00);/*SEG ID*/
+ OutputByte((unsigned char)symbol[i].UsageType);/*SYM INFO*/
+ OutputWord(symbol[i].Address);/*Offset*/
+ OutputByte(0x00);
+ OutputName(symbol[i].name);/*Symbol name*/
+ }
+ }
+ OutputChkSum();
+ }
+
+ /*Line Numbers*/
+ recsize=2;
+ for(i=0; i<numlinenum; i++)/*Get the record length*/
+ if(linenum[i].Procedure==k) recsize+=5;
+
+ if(recsize>2) /*If there are any line numbers*/
+ {
+ OutputByte(0x12); /*REC TYPE*/
+ OutputWord(recsize);/*Record Length*/
+ OutputByte(0x03); /*DEF TYPE: Line numbers*/
+ for(i=0; i<numlinenum; i++)
+ {
+ if ( (linenum[i].Procedure==k) )
+ {
+ OutputByte(0x00);/*SEG ID*/
+ OutputWord(linenum[i].Address);/*Offset*/
+ OutputWord(linenum[i].Number);/*Line Number*/
+ }
+ }
+ OutputChkSum();
+ }
+
+ /*Scope Definition record: end PROCEDURE block*/
+ OutputByte(0x10);/*REC TYPE*/
+ OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
+ OutputByte(0x05);/*BLK TYP: PROCEDURE end block*/
+ OutputName(procedure[k].name);/*Module Name*/
+ OutputChkSum();
+ }
+ }
+
+ /*Scope Definition record: end module block*/
+ OutputByte(0x10);/*REC TYPE*/
+ OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+ OutputByte(0x03);/*BLK TYP: module end*/
+ OutputName(Mname);/*Module Name*/
+ OutputChkSum();
+ }
+
+ /*Content records for everything that is not in the above procedures*/
+ strcpy(Mname, "OTHER_SDCC_STUF");
+
+ /*Scope Definition record: begin module block*/
+ OutputByte(0x10);/*REC TYPE*/
+ OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+ OutputByte(0x00);/*BLK TYP: module block*/
+ OutputName(Mname);/*Module Name*/
+ OutputChkSum();
+
+ for(j=-1; j<numproc; j++)
+ {
+ if(numproc)
+ {
+ if(j==-1)
+ {
+ i=HexBegin;
+ k=procedure[0].BeginAdd;
+ }
+ else if(j==(numproc-1))
+ {
+ i=procedure[j].EndAdd+1;
+ k=HexSize;
+ }
+ else
+ {
+ i=procedure[j].EndAdd+1;
+ k=procedure[j+1].BeginAdd;
+ }
+ }
+ else /*What, no procedures??? Ok, here it is the whole hex file*/
+ {
+ i=HexBegin;
+ k=HexSize;
+ }
+
+ if(i<k)
+ {
+ /*Content Record*/
+ OutputByte(0x06);/*REC TYPE*/
+ OutputWord(k-i+4);/*Record Length*/
+ OutputByte(0x00);/*SEG ID*/
+ OutputWord(i); /*Offset*/
+ for(; i<k; i++) OutputByte(ihxBuff[i]);
+ OutputChkSum();
+ }
+ }
+
+ /*Scope Definition record: end module block*/
+ OutputByte(0x10);/*REC TYPE*/
+ OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+ OutputByte(0x03);/*BLK TYP: module end*/
+ OutputName(Mname);/*Module Name*/
+ OutputChkSum();
+
+ /*Module end record*/
+ OutputByte(0x04);/*REC TYPE*/
+ OutputWord((strlen(MHRname)+1)+5);/*Record Length*/
+ OutputName(MHRname);/*Module Name*/
+ OutputWord(0x00);
+ OutputByte(0x0f);/*REG MSK: All the register banks?*/
+ OutputByte(0x00);
+ OutputChkSum();
+
+ fclose(aomf51out);
+}
+
+void CollectInfoFromCDB(void)
+{
+ int i, j, k, CurrentModule;
+ FILE * CDBin;
+ char buff[0x1000];
+ char SourceName[PATH_MAX];
+
+ //"S:{G|F<filename>|L<functionName>}$<name>$<level>$<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>"
+ 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<numin; j++)
+ if(EQ(infn[j].ModuleName, name)) break;
+ if(j<numin) CurrentModule=j;
+ break;
+
+ /* Example:
+ "S:G$actual$0$0({7}ST__00010000:S),E,0,0"
+ "S:Lmain$j$1$1({2}SI:S),E,0,0"
+ "S:G$DS1306_Reset_SPI$0$0({2}DF,SV:S),C,0,0"
+ "S:G$main$0$0({2}DF,SV:S),C,0,0"
+ */
+
+ case 'S':
+ sscanf(buff, Sfmt,
+ scope, &c,
+ name, &c,
+ level, &c,
+ block);
+
+ /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>*/
+ 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<numproc; j++)
+ {
+ if(EQ(&scope[3], procedure[j].name)) break;
+ }
+ if(j<numproc) k=j; /*Local symbol*/
+ break;
+ case 'F': /*Local symbol to a module*/
+ for(j=0; j<numin; j++)
+ {
+ if(EQ(&scope[3], infn[j].ModuleName)) break;
+ }
+ if(j<numin) i=j;
+ break;
+ }
+
+ /*This symbol may have been already defined*/
+ for(j=0; j<numsym; j++)
+ {
+ if( EQ(name, symbol[j].name) &&
+ (symbol[j].Procedure==k) &&
+ (symbol[j].Static==i) ) break;
+ }
+ if(j==numsym) /*New symbol*/
+ {
+ symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
+ symbol[numsym].FileNameNumber=CurrentModule;
+ strcpy(symbol[numsym].name, name);
+ symbol[numsym].Procedure=k;
+ symbol[numsym].Static=i;
+ symbol[numsym].Address=-1;/*Collected later*/
+
+ switch(AddressSpace)
+ {
+ case 'C': /*Code*/
+ case 'D': /*Code/static segment*/
+ case 'Z': /*Functions and undefined code space*/
+ symbol[numsym].UsageType=0x40;
+ break;
+
+ case 'F': /*External ram*/
+ case 'A': /*External stack*/
+ symbol[numsym].UsageType=0x41;
+ break;
+
+ case 'E': /*Internal ram (lower 128) bytes*/
+ case 'I': /*SFR space*/
+ case 'R': /*Register Space*/
+ symbol[numsym].UsageType=0x42;
+ break;
+
+ case 'B': /*Internal stack*/
+ case 'G': /*Internal ram*/
+ symbol[numsym].UsageType=0x43;
+ break;
+
+ case 'H': /*Bit addressable*/
+ case 'J': /*SBIT space*/
+ symbol[numsym].UsageType=0x44;
+ break;
+
+ default:
+ printf("Unknown scope information for: %s, AddressSpace:%c\n", symbol[numsym].name, AddressSpace);
+ break;
+ }
+ numsym++;
+ }
+ break;
+
+ /*Examples:
+ F:G$AsciiToHex$0$0({2}DF,SC:U),C,0,0,0,0,0
+ F:G$main$0$0({2}DF,SV:S),C,0,0,0,0,0 */
+
+ case 'F':
+ sscanf(buff, "%[^$] %c %[^$]", scope, &c, name);
+ /*The same may have been already defined */
+ for(j=0; j<numproc; j++)
+ {
+ if(EQ(name, procedure[j].name)) break;
+ }
+ if(j==numproc)
+ {
+ procedure=realloc(procedure, sizeof(_procedure)*(numproc+1));
+ strcpy(procedure[numproc].name, name);
+ procedure[numproc].FileNameNumber=CurrentModule;
+ procedure[numproc].BeginAdd=-1;/*To be collected latter*/
+ procedure[numproc].EndAdd=-1;/*To be collected latter*/
+ numproc++;
+ }
+
+ /*This function name is also a global symbol*/
+ for(j=0; j<numsym; j++)/*A global symbol may have been already defined*/
+ {
+ if( EQ(name, symbol[j].name) && (symbol[j].Procedure==-1) ) break;
+ }
+ if(j==numsym)
+ {
+ symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
+ symbol[numsym].FileNameNumber=CurrentModule;
+ strcpy(symbol[numsym].name, name);
+ symbol[numsym].UsageType=0x00;/*A procedure name symbol*/
+ symbol[numsym].Procedure=-1; /*Global symbol*/
+ symbol[numsym].Address=-1;/*Collected later*/
+ symbol[numsym].Static=-1; // o_gloom
+ numsym++;
+ }
+ break;
+
+ case 'L':
+ switch(buff[2])
+ {
+ case 'G': /*Example L:G$P0$0$0:80*/
+ sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
+ scope, &c, name, &c, level, &c, &Address);
+
+ for(j=0; j<numsym; j++)
+ {
+ if(EQ(symbol[j].name, name))
+ {
+ if( (symbol[j].Address==-1) && (symbol[j].Procedure==-1) )
+ {
+ symbol[j].Address=Address;
+ }
+
+ /*If the symbol is the name of a procedure, the address is also
+ the begining of such procedure*/
+ if((symbol[j].UsageType&0x0f)==0x00)
+ {
+ for(k=0; k<numproc; k++)
+ {
+ if(EQ(symbol[j].name, procedure[k].name))
+ {
+ if(procedure[k].BeginAdd==-1)
+ procedure[k].BeginAdd=Address;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ break;
+
+ case 'F': /*Example L:Fadq$_str_2$0$0:57A*/
+ sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
+ scope, &c, name, &c, level, &c, &Address);
+
+ for(j=0; j<numsym; j++)
+ {
+ if(EQ(symbol[j].name, name))
+ {
+ if( (symbol[j].Address==-1) ) symbol[j].Address=Address;
+ break;
+ }
+ }
+
+ /*It could be also a static function*/
+ for(j=0; j<numproc; j++)
+ {
+ if(EQ(procedure[j].name, name))
+ {
+ if( (procedure[j].BeginAdd==-1) ) procedure[j].BeginAdd=Address;
+ break;
+ }
+ }
+
+ break;
+
+ case 'L': /*Example L:Lmain$j$1$1:29*/
+
+ /*
+ L:LDS1306_Write$Value$1$1:34
+ L:LDS1306_Burst_Read$count$1$1:35
+ L:LDS1306_Burst_Read$address$1$1:36
+ L:LDS1306_Burst_Write$count$1$1:37
+ L:LDS1306_Burst_Write$address$1$1:38
+ */
+ sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
+ scope, &c, name, &c, level, &c, &Address);
+
+ for(k=0; k<numproc; k++)
+ {
+ if(EQ(procedure[k].name, scope)) break;
+ }
+
+ if(k<numproc) for(j=0; j<numsym; j++)
+ {
+ if( EQ(symbol[j].name, name) && (symbol[j].Procedure==k) )
+ {
+ if(symbol[j].Address==-1) symbol[j].Address=Address;
+ break;
+ }
+ }
+ break;
+
+ /*Line Numbers*/
+ case 'C': /*Example L:C$adq.c$38$1$1:3E*/ /*L:C$hwinit.c$29$1$1:7AD*/
+ sscanf(&buff[4], "%[^.] %[^$] %c %d %[^:] %c %x",
+ name, level, &c, &CLine, level, &c, &Address);
+
+ for(j=0; j<numin; j++)
+ if(EQ(infn[j].ModuleName, name)) break;
+ if(j<numin)
+ {
+ /*Check if this line is already defined*/
+ for(k=0; k<numlinenum; k++)
+ {
+ if( (linenum[k].Number==CLine) &&
+ (linenum[k].FileNameNumber==j) )break;
+ }
+ if(k==numlinenum) /*New line number*/
+ {
+ linenum=realloc(linenum, sizeof(_linenum)*(numlinenum+1));
+ linenum[numlinenum].Number=CLine;
+ linenum[numlinenum].FileNameNumber=j;
+ linenum[numlinenum].Procedure=-1;/*To be asigned later*/
+ linenum[numlinenum].Address=Address;
+ numlinenum++;
+ }
+ }
+ break;
+
+ case 'A': /*Example L:A$adq$424:40*/
+ /*No use for this one*/
+ break;
+
+ /*The end of a procedure*/
+ case 'X': /*Example L:XG$AsciiToHex$0$0:88*/
+ sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
+ scope, &c, name, &c, level, &c, &Address);
+
+ for(k=0; k<numproc; k++)
+ {
+ if(EQ(procedure[k].name, name))
+ {
+ if(procedure[k].EndAdd==-1) procedure[k].EndAdd=Address;
+ break;
+ }
+ }
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /*Make sure each procedure has an end*/
+ for(k=0; k<(numproc-1); k++)
+ {
+ if (procedure[k].EndAdd==-1) procedure[k].EndAdd=procedure[k+1].BeginAdd-1;
+ }
+ /*Asign each line number to a procedure*/
+ for(j=0; j<numlinenum; j++)
+ {
+ for(k=0; k<numproc; k++)
+ {
+ if ( (linenum[j].Address>=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<MEMSIZE; j++) ihxBuff[j]=0xff;
+
+ while(1)
+ {
+ if(fgets(buffer, sizeof(buffer), filein)==NULL)
+ {
+ printf("Error reading file '%s'\n", ihxFileName);
+ break;
+ }
+ if(buffer[0]==':')
+ {
+ linesize = GetByte(&buffer[1]);
+ address = GetWord(&buffer[3]);
+ recordtype = GetByte(&buffer[7]);
+ rchksum = GetByte(&buffer[9]+(linesize*2));
+ chksum=linesize+(address/0x100)+(address%0x100)+recordtype+rchksum;
+
+ if (recordtype==1) break; /*End of record*/
+
+ for(j=0; j<linesize; j++)
+ {
+ value=GetByte(&buffer[9]+(j*2));
+ chksum+=value;
+ ihxBuff[address+j]=value;
+ }
+ if(MaxAddress<(address+linesize-1)) MaxAddress=(address+linesize-1);
+ if(address<*Begin) *Begin=address;
+
+ if((chksum%0x100)!=0)
+ {
+ printf("ERROR: Bad checksum in file %s\n", ihxFileName);
+ fclose(filein);
+ return -1;
+ }
+ }
+ }
+ fclose(filein);
+
+ return MaxAddress;
+}
+
+void CreateAOMF51(void)
+{
+ if((dflag) && (!rflag))
+ {
+ CollectInfoFromCDB();
+ #ifdef DODUMP
+ DumpForDebug();
+ #endif
+ HexSize=ReadHexFile(&HexBegin)+1;
+ OutputAOEMF51();
+ FreeAll();
+ }
+}
--- /dev/null
+/* lkdata.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio 44240
+ *
+ * 28-Oct-97 JLH:
+ * - change s_id from [NCPS] to pointer (comment)
+ * 31-Oct-97 JLH:
+ * - add jflag and jfp for NoICE output
+ */
+
+#include <stdio.h>
+#include <string.h>
+#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
return(symval(sp));
}
}
+ /* Shouldn't get here. */
return(0);
}
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 {
* 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
*/
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; i<NHASH; i++) {
+ sp = symhash[i];
+ while (sp != NULL) {
+ if (oxp == sp->s_axp)
+ ++nmsym;
+ sp = sp->s_sp;
+ }
+ }
+ oxp = oxp->a_axp;
+ }
+ if (nmsym == 0) {
+ return;
+ }
+
if (xflag == 0) {
fprintf(mfp, "Hexadecimal\n\n");
} else
if (ai || aj) { fprintf(mfp, " Error"); }
}
- /*
- * Find number of symbols in area
- */
- nmsym = 0;
- oxp = xp->a_axp;
- while (oxp) {
- for (i=0; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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.
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; i<nmsym; ++i) {
- sp = p[i];
- ai = sp->s_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
* 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
*/
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);
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; i<nmsym; ++i) {
- sp = p[i];
- ai = sp->s_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
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 );
}
#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; i<NHASH; i++) {
+ sp = symhash[i];
+ while (sp != NULL) {
+ if (oxp == sp->s_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; i<NHASH; i++) {
+ sp = symhash[i];
+ while (sp != NULL) {
+ if (oxp == sp->s_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
*/
VOID
-lkulist(i)
-int i;
+lkulist(int i)
{
Addr_T pc;
*/
VOID
-lkalist(pc)
-Addr_T pc;
+lkalist(Addr_T pc)
{
char str[8];
int i;
*/
VOID
-lkglist(pc,v)
-Addr_T pc;
-int v;
+lkglist(Addr_T pc, int v)
{
char str[8];
int i;
*/
int
-dgt(rdx, str, n)
-int rdx, n;
-char *str;
+dgt(int rdx, char *str, int n)
{
int i;
for (i=0; i<n; i++) {
- if ((ctype[(int)*str++] & rdx) == 0)
+ if ((ctype[(unsigned char)(*str++)] & rdx) == 0)
return(0);
}
return(1);
*/
VOID
-syminit()
+syminit(void)
{
- // register int h;
struct sym **spp;
spp = &symhash[0];
*
*/
struct sym *
-newsym()
+newsym(void)
{
register unsigned i ;
register unsigned nglob ;
if (c == 'D') {
i = eval();
if (tsp->s_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;
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);
}
/*
}
fprintf(stderr, "Header symbol list overflow\n");
lkexit(1);
+
+ /* Never reached */
return(0);
}
*/
struct sym *
-lkpsym(id, f)
-char *id;
+lkpsym(char *id, int f)
{
register struct sym *sp;
register int h;
*/
Addr_T
-symval(tsp)
-register struct sym *tsp;
+symval(register struct sym *tsp)
{
register Addr_T val;
*/
VOID
-symdef(fp)
-FILE *fp;
+symdef(FILE *fp)
{
register struct sym *sp;
register int i;
*/
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; i<hp->h_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; i<hp->h_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;
- }
}
}
*/
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
}
*/
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);
}
*/
VOID *
-new(n)
-unsigned int n;
+new(unsigned int n)
{
register char *p;
!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
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
CFG=aslink - Win32 Release\r
!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE NMAKE /f "aslink.mak".\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE You can specify a configuration when running NMAKE\r
!MESSAGE by defining the macro CFG on the command line. For example:\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE NMAKE /f "aslink.mak" CFG="aslink - Win32 Release"\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
+!MESSAGE\r
!MESSAGE "aslink - Win32 Debug" (based on "Win32 (x86) Console Application")\r
!MESSAGE "aslink - Win32 Release" (based on "Win32 (x86) Console Application")\r
-!MESSAGE \r
+!MESSAGE\r
\r
# Begin Project\r
# PROP AllowPerConfigDependencies 0\r
# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept\r
# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept\r
\r
-!ENDIF \r
+!ENDIF\r
\r
# Begin Target\r
\r
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
-SOURCE=.\lkaomf51.c\r
+SOURCE=..\lkaomf51.c\r
# End Source File\r
# Begin Source File\r
\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkdata.c\r
+SOURCE=..\lkdata.c\r
# End Source File\r
# Begin Source File\r
\r
+++ /dev/null
-/*-------------------------------------------------------------------------
- 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 <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#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<numin; j++)
- {
- if(EQ(infn[numin].PathName, infn[j].PathName)) break;
- }
- if(j==numin) numin++;
- }
-}
-
-void FreeAll(void)
-{
- if(infn!=NULL)
- {
- free(infn);
- numin=0;
- infn=NULL;
- }
-
- if(symbol!=NULL)
- {
- free(symbol);
- numsym=0;
- symbol=NULL;
- }
-
- if(procedure!=NULL)
- {
- free(procedure);
- numproc=0;
- procedure=NULL;
-
- }
- if(linenum!=NULL)
- {
- free(linenum);
- numlinenum=0;
- linenum=NULL;
- }
-
- if(ihxBuff!=NULL)
- {
- free(ihxBuff);
- ihxBuff=NULL;
- }
-}
-
-void OutputByte(unsigned char value)
-{
- GlobalChkSum+=value;
- fwrite( &value, 1, 1, aomf51out );
-}
-
-void OutputWord(int value)
-{
- OutputByte((unsigned char)(value%0x100));
- OutputByte((unsigned char)(value/0x100));
-}
-
-void OutputName(char * name)
-{
- int k;
- OutputByte((unsigned char)strlen(name));
- for(k=0; name[k]!=0; k++)
- OutputByte((unsigned char)toupper(name[k]));
-}
-
-void OutputChkSum(void)
-{
- OutputByte((unsigned char)(0x100-(GlobalChkSum%0x100)));
- GlobalChkSum=0;
-}
-
-#ifdef DODUMP
-void DumpForDebug (void)
-{
- char DumpFileName[PATH_MAX];
- FILE * DumpFile;
- int j, k;
-
- strcpy(DumpFileName, infn[0].PathName);
- strcat(DumpFileName, ".d51");
-
- DumpFile=fopen(DumpFileName, "wb");
- if(DumpFile==NULL)
- {
- printf("Couldn't create file %s\n", DumpFileName);
- return;
- }
-
- fprintf(DumpFile,"SYMBOLS:\n");
-
- for(j=0; j<numsym; j++)
- {
- k=symbol[j].UsageType&0xf;
- fprintf(DumpFile, "%s, %s, %s, 0x%04x, %s\n",
- symbol[j].name,
- infn[symbol[j].FileNameNumber].PathName,
- (symbol[j].Procedure>=0)?procedure[symbol[j].Procedure].name:"GLOBAL",
- symbol[j].Address,
- k<6?UsageTypeName[k]:"???");
- }
-
- fprintf(DumpFile,"\nPROCEDURES:\n");
- for(j=0; j<numproc; j++)
- {
- fprintf(DumpFile, "%s, %s, 0x%04x-0x%04x\n",
- procedure[j].name,
- infn[procedure[j].FileNameNumber].PathName,
- procedure[j].BeginAdd,
- procedure[j].EndAdd);
- }
-
- fprintf(DumpFile,"\nLINE NUMBERS:\n");
- for(j=0; j<numlinenum; j++)
- {
- fprintf(DumpFile, "%d:0x%04x, %s -> %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; j<numin; j++)
- {
- GetName(infn[j].PathName, Mname);
-
- /*Scope Definition record: begin module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x00);/*BLK TYP: module block*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
-
- /*Public symbols defined in this module*/
- recsize=2;
- for(k=0; k<numsym; k++)/*Compute the record length*/
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==-1) ) recsize+=((strlen(symbol[k].name)+1)+5);
-
- if(recsize>2) /*If there are any symbols*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x01); /*DEF TYPE: Public symbols*/
- for(k=0; k<numsym; k++)
- {
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==-1) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
- OutputWord(symbol[k].Address);/*Offset*/
- OutputByte(0x00);
- OutputName(symbol[k].name);/*Symbol name*/
- }
- }
- OutputChkSum();
- }
-
- /*Local symbols defined in this module*/
- recsize=2;
- for(k=0; k<numsym; k++)/*Compute the record length*/
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==j) ) recsize+=((strlen(symbol[k].name)+1)+5);
-
- if(recsize>2) /*If there are any symbols*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x00); /*DEF TYPE: Local symbols*/
- for(k=0; k<numsym; k++)
- {
- if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
- (symbol[k].Procedure==-1) &&
- (symbol[k].Static==j) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
- OutputWord(symbol[k].Address);/*Offset*/
- OutputByte(0x00);
- OutputName(symbol[k].name);/*Symbol name*/
- }
- }
- OutputChkSum();
- }
-
- /*Output the procedures of this module*/
-
- for(k=0; k<numproc; k++)
- {
- if(procedure[k].FileNameNumber==j)
- {
- /*Scope Definition record: begin PROCEDURE block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
- OutputByte(0x02);/*BLK TYP: PROCEDURE block*/
- OutputName(procedure[k].name);/*Module Name*/
- OutputChkSum();
-
- /*Content Record*/
- OutputByte(0x06);/*REC TYPE*/
- if(procedure[k].EndAdd==-1) procedure[k].EndAdd=HexSize;
- recsize=procedure[k].EndAdd-procedure[k].BeginAdd+1+4;
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x00);/*SEG ID*/
- OutputWord(procedure[k].BeginAdd); /*Offset*/
- for(i=procedure[k].BeginAdd; i<=procedure[k].EndAdd; i++)
- OutputByte(ihxBuff[i]);
- OutputChkSum();
-
- /*Local Symbols*/
-
- recsize=2;
- for(i=0; i<numsym; i++)/*Get the record length*/
- if(symbol[i].Procedure==k)
- recsize+=((strlen(symbol[i].name)+1)+5);
-
- if(recsize>2) /*If there are any symbols*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x00); /*DEF TYPE: Local symbols*/
- for(i=0; i<numsym; i++)
- {
- if ( (symbol[i].Procedure==k) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputByte((unsigned char)symbol[i].UsageType);/*SYM INFO*/
- OutputWord(symbol[i].Address);/*Offset*/
- OutputByte(0x00);
- OutputName(symbol[i].name);/*Symbol name*/
- }
- }
- OutputChkSum();
- }
-
- /*Line Numbers*/
- recsize=2;
- for(i=0; i<numlinenum; i++)/*Get the record length*/
- if(linenum[i].Procedure==k) recsize+=5;
-
- if(recsize>2) /*If there are any line numbers*/
- {
- OutputByte(0x12); /*REC TYPE*/
- OutputWord(recsize);/*Record Length*/
- OutputByte(0x03); /*DEF TYPE: Line numbers*/
- for(i=0; i<numlinenum; i++)
- {
- if ( (linenum[i].Procedure==k) )
- {
- OutputByte(0x00);/*SEG ID*/
- OutputWord(linenum[i].Address);/*Offset*/
- OutputWord(linenum[i].Number);/*Line Number*/
- }
- }
- OutputChkSum();
- }
-
- /*Scope Definition record: end PROCEDURE block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
- OutputByte(0x05);/*BLK TYP: PROCEDURE end block*/
- OutputName(procedure[k].name);/*Module Name*/
- OutputChkSum();
- }
- }
-
- /*Scope Definition record: end module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x03);/*BLK TYP: module end*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
- }
-
- /*Content records for everything that is not in the above procedures*/
- strcpy(Mname, "OTHER_SDCC_STUF");
-
- /*Scope Definition record: begin module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x00);/*BLK TYP: module block*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
-
- for(j=-1; j<numproc; j++)
- {
- if(numproc)
- {
- if(j==-1)
- {
- i=HexBegin;
- k=procedure[0].BeginAdd;
- }
- else if(j==(numproc-1))
- {
- i=procedure[j].EndAdd+1;
- k=HexSize;
- }
- else
- {
- i=procedure[j].EndAdd+1;
- k=procedure[j+1].BeginAdd;
- }
- }
- else /*What, no procedures??? Ok, here it is the whole hex file*/
- {
- i=HexBegin;
- k=HexSize;
- }
-
- if(i<k)
- {
- /*Content Record*/
- OutputByte(0x06);/*REC TYPE*/
- OutputWord(k-i+4);/*Record Length*/
- OutputByte(0x00);/*SEG ID*/
- OutputWord(i); /*Offset*/
- for(; i<k; i++) OutputByte(ihxBuff[i]);
- OutputChkSum();
- }
- }
-
- /*Scope Definition record: end module block*/
- OutputByte(0x10);/*REC TYPE*/
- OutputWord((strlen(Mname)+1)+2);/*Record Length*/
- OutputByte(0x03);/*BLK TYP: module end*/
- OutputName(Mname);/*Module Name*/
- OutputChkSum();
-
- /*Module end record*/
- OutputByte(0x04);/*REC TYPE*/
- OutputWord((strlen(MHRname)+1)+5);/*Record Length*/
- OutputName(MHRname);/*Module Name*/
- OutputWord(0x00);
- OutputByte(0x0f);/*REG MSK: All the register banks?*/
- OutputByte(0x00);
- OutputChkSum();
-
- fclose(aomf51out);
-}
-
-void CollectInfoFromCDB(void)
-{
- int i, j, k, CurrentModule;
- FILE * CDBin;
- char buff[0x1000];
- char SourceName[PATH_MAX];
-
- //"S:{G|F<filename>|L<functionName>}$<name>$<level>$<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>"
- 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<numin; j++)
- if(EQ(infn[j].ModuleName, name)) break;
- if(j<numin) CurrentModule=j;
- break;
-
- /* Example:
- "S:G$actual$0$0({7}ST__00010000:S),E,0,0"
- "S:Lmain$j$1$1({2}SI:S),E,0,0"
- "S:G$DS1306_Reset_SPI$0$0({2}DF,SV:S),C,0,0"
- "S:G$main$0$0({2}DF,SV:S),C,0,0"
- */
-
- case 'S':
- sscanf(buff, Sfmt,
- scope, &c,
- name, &c,
- level, &c,
- block);
-
- /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>*/
- 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<numproc; j++)
- {
- if(EQ(&scope[3], procedure[j].name)) break;
- }
- if(j<numproc) k=j; /*Local symbol*/
- break;
- case 'F': /*Local symbol to a module*/
- for(j=0; j<numin; j++)
- {
- if(EQ(&scope[3], infn[j].ModuleName)) break;
- }
- if(j<numin) i=j;
- break;
- }
-
- /*This symbol may have been already defined*/
- for(j=0; j<numsym; j++)
- {
- if( EQ(name, symbol[j].name) &&
- (symbol[j].Procedure==k) &&
- (symbol[j].Static==i) ) break;
- }
- if(j==numsym) /*New symbol*/
- {
- symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
- symbol[numsym].FileNameNumber=CurrentModule;
- strcpy(symbol[numsym].name, name);
- symbol[numsym].Procedure=k;
- symbol[numsym].Static=i;
- symbol[numsym].Address=-1;/*Collected later*/
-
- switch(AddressSpace)
- {
- case 'C': /*Code*/
- case 'D': /*Code/static segment*/
- case 'Z': /*Functions and undefined code space*/
- symbol[numsym].UsageType=0x40;
- break;
-
- case 'F': /*External ram*/
- case 'A': /*External stack*/
- symbol[numsym].UsageType=0x41;
- break;
-
- case 'E': /*Internal ram (lower 128) bytes*/
- case 'I': /*SFR space*/
- case 'R': /*Register Space*/
- symbol[numsym].UsageType=0x42;
- break;
-
- case 'B': /*Internal stack*/
- case 'G': /*Internal ram*/
- symbol[numsym].UsageType=0x43;
- break;
-
- case 'H': /*Bit addressable*/
- case 'J': /*SBIT space*/
- symbol[numsym].UsageType=0x44;
- break;
-
- default:
- printf("Unknown scope information for: %s, AddressSpace:%c\n", symbol[numsym].name, AddressSpace);
- break;
- }
- numsym++;
- }
- break;
-
- /*Examples:
- F:G$AsciiToHex$0$0({2}DF,SC:U),C,0,0,0,0,0
- F:G$main$0$0({2}DF,SV:S),C,0,0,0,0,0 */
-
- case 'F':
- sscanf(buff, "%[^$] %c %[^$]", scope, &c, name);
- /*The same may have been already defined */
- for(j=0; j<numproc; j++)
- {
- if(EQ(name, procedure[j].name)) break;
- }
- if(j==numproc)
- {
- procedure=realloc(procedure, sizeof(_procedure)*(numproc+1));
- strcpy(procedure[numproc].name, name);
- procedure[numproc].FileNameNumber=CurrentModule;
- procedure[numproc].BeginAdd=-1;/*To be collected latter*/
- procedure[numproc].EndAdd=-1;/*To be collected latter*/
- numproc++;
- }
-
- /*This function name is also a global symbol*/
- for(j=0; j<numsym; j++)/*A global symbol may have been already defined*/
- {
- if( EQ(name, symbol[j].name) && (symbol[j].Procedure==-1) ) break;
- }
- if(j==numsym)
- {
- symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
- symbol[numsym].FileNameNumber=CurrentModule;
- strcpy(symbol[numsym].name, name);
- symbol[numsym].UsageType=0x00;/*A procedure name symbol*/
- symbol[numsym].Procedure=-1; /*Global symbol*/
- symbol[numsym].Address=-1;/*Collected later*/
- symbol[numsym].Static=-1; // o_gloom
- numsym++;
- }
- break;
-
- case 'L':
- switch(buff[2])
- {
- case 'G': /*Example L:G$P0$0$0:80*/
- sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(j=0; j<numsym; j++)
- {
- if(EQ(symbol[j].name, name))
- {
- if( (symbol[j].Address==-1) && (symbol[j].Procedure==-1) )
- {
- symbol[j].Address=Address;
- }
-
- /*If the symbol is the name of a procedure, the address is also
- the begining of such procedure*/
- if((symbol[j].UsageType&0x0f)==0x00)
- {
- for(k=0; k<numproc; k++)
- {
- if(EQ(symbol[j].name, procedure[k].name))
- {
- if(procedure[k].BeginAdd==-1)
- procedure[k].BeginAdd=Address;
- break;
- }
- }
- }
-
- break;
- }
- }
- break;
-
- case 'F': /*Example L:Fadq$_str_2$0$0:57A*/
- sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(j=0; j<numsym; j++)
- {
- if(EQ(symbol[j].name, name))
- {
- if( (symbol[j].Address==-1) ) symbol[j].Address=Address;
- break;
- }
- }
-
- /*It could be also a static function*/
- for(j=0; j<numproc; j++)
- {
- if(EQ(procedure[j].name, name))
- {
- if( (procedure[j].BeginAdd==-1) ) procedure[j].BeginAdd=Address;
- break;
- }
- }
-
- break;
-
- case 'L': /*Example L:Lmain$j$1$1:29*/
-
- /*
- L:LDS1306_Write$Value$1$1:34
- L:LDS1306_Burst_Read$count$1$1:35
- L:LDS1306_Burst_Read$address$1$1:36
- L:LDS1306_Burst_Write$count$1$1:37
- L:LDS1306_Burst_Write$address$1$1:38
- */
- sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(k=0; k<numproc; k++)
- {
- if(EQ(procedure[k].name, scope)) break;
- }
-
- if(k<numproc) for(j=0; j<numsym; j++)
- {
- if( EQ(symbol[j].name, name) && (symbol[j].Procedure==k) )
- {
- if(symbol[j].Address==-1) symbol[j].Address=Address;
- break;
- }
- }
- break;
-
- /*Line Numbers*/
- case 'C': /*Example L:C$adq.c$38$1$1:3E*/ /*L:C$hwinit.c$29$1$1:7AD*/
- sscanf(&buff[4], "%[^.] %[^$] %c %d %[^:] %c %x",
- name, level, &c, &CLine, level, &c, &Address);
-
- for(j=0; j<numin; j++)
- if(EQ(infn[j].ModuleName, name)) break;
- if(j<numin)
- {
- /*Check if this line is already defined*/
- for(k=0; k<numlinenum; k++)
- {
- if( (linenum[k].Number==CLine) &&
- (linenum[k].FileNameNumber==j) )break;
- }
- if(k==numlinenum) /*New line number*/
- {
- linenum=realloc(linenum, sizeof(_linenum)*(numlinenum+1));
- linenum[numlinenum].Number=CLine;
- linenum[numlinenum].FileNameNumber=j;
- linenum[numlinenum].Procedure=-1;/*To be asigned later*/
- linenum[numlinenum].Address=Address;
- numlinenum++;
- }
- }
- break;
-
- case 'A': /*Example L:A$adq$424:40*/
- /*No use for this one*/
- break;
-
- /*The end of a procedure*/
- case 'X': /*Example L:XG$AsciiToHex$0$0:88*/
- sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
- scope, &c, name, &c, level, &c, &Address);
-
- for(k=0; k<numproc; k++)
- {
- if(EQ(procedure[k].name, name))
- {
- if(procedure[k].EndAdd==-1) procedure[k].EndAdd=Address;
- break;
- }
- }
- break;
- }
- break;
-
- default:
- break;
- }
- }
-
- /*Make sure each procedure has an end*/
- for(k=0; k<(numproc-1); k++)
- {
- if (procedure[k].EndAdd==-1) procedure[k].EndAdd=procedure[k+1].BeginAdd-1;
- }
- /*Asign each line number to a procedure*/
- for(j=0; j<numlinenum; j++)
- {
- for(k=0; k<numproc; k++)
- {
- if ( (linenum[j].Address>=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<MEMSIZE; j++) ihxBuff[j]=0xff;
-
- while(1)
- {
- if(fgets(buffer, sizeof(buffer), filein)==NULL)
- {
- printf("Error reading file '%s'\n", ihxFileName);
- break;
- }
- if(buffer[0]==':')
- {
- linesize = GetByte(&buffer[1]);
- address = GetWord(&buffer[3]);
- recordtype = GetByte(&buffer[7]);
- rchksum = GetByte(&buffer[9]+(linesize*2));
- chksum=linesize+(address/0x100)+(address%0x100)+recordtype+rchksum;
-
- if (recordtype==1) break; /*End of record*/
-
- for(j=0; j<linesize; j++)
- {
- value=GetByte(&buffer[9]+(j*2));
- chksum+=value;
- ihxBuff[address+j]=value;
- }
- if(MaxAddress<(address+linesize-1)) MaxAddress=(address+linesize-1);
- if(address<*Begin) *Begin=address;
-
- if((chksum%0x100)!=0)
- {
- printf("ERROR: Bad checksum in file %s\n", ihxFileName);
- fclose(filein);
- return -1;
- }
- }
- }
- fclose(filein);
-
- return MaxAddress;
-}
-
-void CreateAOMF51(void)
-{
- if((dflag) && (!rflag))
- {
- CollectInfoFromCDB();
- #ifdef DODUMP
- DumpForDebug();
- #endif
- HexSize=ReadHexFile(&HexBegin)+1;
- OutputAOEMF51();
- FreeAll();
- }
-}
+++ /dev/null
-/* lkdata.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- *
- * 28-Oct-97 JLH:
- * - change s_id from [NCPS] to pointer (comment)
- * 31-Oct-97 JLH:
- * - add jflag and jfp for NoICE output
- */
-
-#include <stdio.h>
-#include <string.h>
-#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
FILE *src,*dest ;
{
int ch;
- while ((ch = fgetc(src)) != EOF) {
- fputc(ch,dest);
+ while ((ch = fgetc(src)) != EOF) {
+ fputc(ch,dest);
}
}
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)
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
+SOURCE=..\lkaomf51.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\lkarea.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkdata.c\r
+SOURCE=..\lkdata.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkeval.c\r
+SOURCE=..\lkeval.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkhead.c\r
+SOURCE=..\lkhead.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lklex.c\r
+SOURCE=..\lklex.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lklist.c\r
+SOURCE=..\lklist.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\lknoice.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lksym.c\r
+SOURCE=..\lksym.c\r
# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
# End Source File\r
# End Group\r
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
+SOURCE=..\lkaomf51.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\lkarea.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkdata.c\r
+SOURCE=..\lkdata.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkeval.c\r
+SOURCE=..\lkeval.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lkhead.c\r
+SOURCE=..\lkhead.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lklex.c\r
+SOURCE=..\lklex.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lklist.c\r
+SOURCE=..\lklist.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\lknoice.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\lksym.c\r
+SOURCE=..\lksym.c\r
# ADD CPP /D "SDK" /D "INDEXLIB"\r
# End Source File\r
# End Group\r
+++ /dev/null
-/* lkdata.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#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
+++ /dev/null
-/* lkeval.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#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);
-}
+++ /dev/null
-/* lkhead.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#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++;
- }
-}
+++ /dev/null
-/* lklex.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
-/*
- * Extensions: P. Felber, M. Hope
- */
-
-#include <stdio.h>
-#include <string.h>
-#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;
-}
#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
+++ /dev/null
-/* lklist.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<nmsym; ++i) {
- sp = p[i];
- ai = sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<NHASH; i++) {
- sp = symhash[i];
- while (sp != NULL) {
- if (oxp == sp->s_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; i<nmsym; ++i) {
- sp = p[i];
- ai = sp->s_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<sizeof(rb); i++) {
- *rp++ = 0;
- }
-
- /*
- * Get next LST text line
- */
- if (fgets(rb, sizeof(rb), tfp) == NULL) {
- fclose(tfp);
- tfp = NULL;
- fclose(rfp);
- rfp = NULL;
- return;
- }
-
- /*
- * Must have an ASxxxx Listing line number
- */
- if (!dgt(RAD10, &rb[30], 1)) {
- fprintf(rfp, "%s", rb);
- goto loop;
- }
-
- /*
- * Must have an address in the expected radix
- */
- if (radix == 16) {
- if (!dgt(RAD16, &rb[3], 4)) {
- fprintf(rfp, "%s", rb);
- goto loop;
- }
- sprintf(str, "%04X", pc);
- strncpy(&rb[3], str, 4);
- } else
- if (radix == 10) {
- if (!dgt(RAD10, &rb[3], 5)) {
- fprintf(rfp, "%s", rb);
- goto loop;
- }
- sprintf(str, "%05d", pc);
- strncpy(&rb[3], str, 5);
- } else
- if (radix == 8) {
- if (!dgt(RAD8, &rb[3], 6)) {
- fprintf(rfp, "%s", rb);
- goto loop;
- }
- sprintf(str, "%06o", pc);
- strncpy(&rb[3], str, 6);
- }
-
- /*
- * Copy updated LST text line to RST
- */
- fprintf(rfp, "%s", rb);
- gcntr = 0;
-}
-
-/*)Function VOID lkglist(pc,v)
- *
- * int pc current program counter value
- * int v value of byte at this address
- *
- * The function lkglist() performs the following functions:
- *
- * (1) if the value of gline = 1 then 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.
- *
- * (2) The new relocated values and code address are
- * substituted and the line may be written to the RST file.
- *
- * local variables:
- * int i loop counter
- * char str[] temporary string
- *
- * global variables:
- * int gcntr data byte counter
- * set to -1 for a continuation line
- * 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
- * with updated data values and code addresses.
- */
-
-VOID
-lkglist(pc,v)
-Addr_T pc;
-int v;
-{
- char str[8];
- int i;
-
- /*
- * Exit if listing file is not open
- */
-loop: if (tfp == NULL)
- return;
-
- /*
- * Get next LST text line
- */
- if (gline) {
- /*
- * Clear text line buffer
- */
- for (i=0,rp=rb; i<sizeof(rb); i++) {
- *rp++ = 0;
- }
-
- /*
- * Get next LST text line
- */
- if (fgets(rb, sizeof(rb), tfp) == NULL) {
- fclose(tfp);
- tfp = NULL;
- fclose(rfp);
- rfp = NULL;
- return;
- }
-
- /*
- * Check for a listing line number if required
- */
- if (gcntr != -1) {
- if (!dgt(RAD10, &rb[30], 1)) {
- fprintf(rfp, "%s", rb);
- goto loop;
- }
- gcntr = 0;
- }
- gline = 0;
- }
-
- /*
- * Hex Listing
- */
- if (radix == 16) {
- /*
- * Data Byte Pointer
- */
- if (gcntr == -1) {
- rp = &rb[8];
- } else {
- rp = &rb[8 + (3 * gcntr)];
- }
- /*
- * Number must be of proper radix
- */
- if (!dgt(RAD16, rp, 2)) {
- fprintf(rfp, "%s", rb);
- gline = 1;
- goto loop;
- }
- /*
- * Output new data value, overwrite relocation codes
- */
- sprintf(str, " %02X", v);
- strncpy(rp-1, str, 3);
- if (gcntr == -1) {
- gcntr = 0;
- }
- /*
- * Output relocated code address
- */
- if (gcntr == 0) {
- if (dgt(RAD16, &rb[3], 4)) {
- sprintf(str, "%04X", pc);
- strncpy(&rb[3], str, 4);
- }
- }
- /*
- * Output text line when updates finished
- */
- if (++gcntr == 6) {
- fprintf(rfp, "%s", rb);
- gline = 1;
- gcntr = -1;
- }
- } else
- /*
- * Decimal Listing
- */
- if (radix == 10) {
- /*
- * Data Byte Pointer
- */
- if (gcntr == -1) {
- rp = &rb[9];
- } else {
- rp = &rb[9 + (3 * gcntr)];
- }
- /*
- * Number must be of proper radix
- */
- if (!dgt(RAD10, rp, 3)) {
- fprintf(rfp, "%s", rb);
- gline = 1;
- goto loop;
- }
- /*
- * Output new data value, overwrite relocation codes
- */
- sprintf(str, " %03d", v);
- strncpy(rp-1, str, 4);
- if (gcntr == -1) {
- gcntr = 0;
- }
- /*
- * Output relocated code address
- */
- if (gcntr == 0) {
- if (dgt(RAD10, &rb[3], 5)) {
- sprintf(str, "%05d", pc);
- strncpy(&rb[3], str, 5);
- }
- }
- /*
- * Output text line when updates finished
- */
- if (++gcntr == 4) {
- fprintf(rfp, "%s", rb);
- gline = 1;
- gcntr = -1;
- }
- } else
- /*
- * Octal Listing
- */
- if (radix == 8) {
- /*
- * Data Byte Pointer
- */
- if (gcntr == -1) {
- rp = &rb[10];
- } else {
- rp = &rb[10 + (3 * gcntr)];
- }
- /*
- * Number must be of proper radix
- */
- if (!dgt(RAD8, rp, 3)) {
- fprintf(rfp, "%s", rb);
- gline = 1;
- goto loop;
- }
- /*
- * Output new data value, overwrite relocation codes
- */
- sprintf(str, " %03o", v);
- strncpy(rp-1, str, 4);
- if (gcntr == -1) {
- gcntr = 0;
- }
- /*
- * Output relocated code address
- */
- if (gcntr == 0) {
- if (dgt(RAD8, &rb[3], 6)) {
- sprintf(str, "%06o", pc);
- strncpy(&rb[3], str, 6);
- }
- }
- /*
- * Output text line when updates finished
- */
- if (++gcntr == 4) {
- fprintf(rfp, "%s", rb);
- gline = 1;
- gcntr = -1;
- }
- }
-}
-
-/*)Function int dgt(rdx,str,n)
- *
- * int rdx radix bit code
- * char *str pointer to the test string
- * int n number of characters to check
- *
- * The function dgt() verifies that the string under test
- * is of the specified radix.
- *
- * local variables:
- * int i loop counter
- *
- * global variables:
- * ctype[] array of character types
- *
- * functions called:
- * none
- *
- * side effects:
- * none
- */
-
-int
-dgt(rdx, str, n)
-int rdx, n;
-char *str;
-{
- int i;
-
- for (i=0; i<n; i++) {
- if ((ctype[(unsigned char)(*str++)] & rdx) == 0)
- return(0);
- }
- return(1);
-}
fprintf(stderr, "%s\n", *dp);
lkexit(1);
}
+
+/*)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
+ *
+ * side effects:
+ * none
+ */
+VOID copyfile (dest,src)
+FILE *src,*dest ;
+{
+ int ch;
+
+ while ((ch = fgetc(src)) != EOF) {
+ fputc(ch,dest);
+ }
+}
+++ /dev/null
-/* lksym.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio 44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#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; i<NHASH; ++i) {
- sp = symhash[i];
- while (sp) {
- if (sp->s_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; i<hp->h_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);
-}