From e05b6df8fb31fa9db84b15f720fd6a4488dec130 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Sun, 17 Sep 2006 16:00:23 +0000 Subject: [PATCH] * as/link/aslink.h, * as/link/mcs51/aslink.h, * as/link/z80/aslink.h: merged and moved to as/link/ * as/link/lkstore.c, * as/link/mcs51/lkstore.c: moved to as/link/ * as/link/clean.mk: remove *.o * as/link/mcs51/alloc.h: deleted * as/link/mcs51/lkarea.c: added lnksect prototype * as/link/mcs51/lkdata.c, * as/link/mcs51/lklex.c, * as/link/mcs51/lkmain.c: renamed as_getline to lk_getline * as/link/mcs51/lkmem.c, * as/link/mcs51/lknoice.c: removed include strcmpi.h * as/link/mcs51/lksym.c: include stdlib.h instead of malloc.h or alloc.h * as/link/mcs51/aslink.dsp, * as/link/mcs51/Makefile.aslink, * as/link/mcs51/Makefile.bcc, * as/link/mcs51/Makefile.in: updated for moved files * as/link/z80/lkarea.c, * as/link/z80/lkhead.c, * as/link/z80/lklex.c, * as/link/z80/lklibr.c, * as/link/z80/lklist.c, * as/link/z80/lkmain.c, * as/link/z80/lkrloc.c, * as/link/z80/lksym.c: synced with mcs51 * as/link/z80/lkdata.c, * as/link/z80/lkeval.c, * as/link/z80/lkihx.c, * as/link/z80/lks19.c: cosmetic changes * as/link/z80/Makefile.in, * as/link/z80/linkgbz80.dsp, * as/link/z80/linkz80.dsp: updated for moved files git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4381 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 36 + as/link/{mcs51 => }/aslink.h | 79 +- as/link/clean.mk | 4 + as/link/{mcs51 => }/lkstore.c | 0 as/link/mcs51/Makefile.aslink | 12 +- as/link/mcs51/Makefile.bcc | 4 +- as/link/mcs51/Makefile.in | 8 +- as/link/mcs51/alloc.h | 4 - as/link/mcs51/aslink.dsp | 26 +- as/link/mcs51/lkarea.c | 1 + as/link/mcs51/lkdata.c | 2 +- as/link/mcs51/lklex.c | 21 +- as/link/mcs51/lkmain.c | 8 +- as/link/mcs51/lkmem.c | 1 - as/link/mcs51/lknoice.c | 1 - as/link/mcs51/lksym.c | 6 +- as/link/z80/Makefile.in | 4 +- as/link/z80/aslink.h | 737 ---------- as/link/z80/linkgbz80.dsp | 25 +- as/link/z80/linkz80.dsp | 25 +- as/link/z80/lkarea.c | 196 ++- as/link/z80/lkdata.c | 3 +- as/link/z80/lkeval.c | 3 +- as/link/z80/lkhead.c | 3 +- as/link/z80/lkihx.c | 3 +- as/link/z80/lklex.c | 76 +- as/link/z80/lklibr.c | 1608 +++++++++++----------- as/link/z80/lklist.c | 2117 ++++++++++++++-------------- as/link/z80/lkmain.c | 2444 ++++++++++++++++----------------- as/link/z80/lkrloc.c | 1818 ++++++++++++------------ as/link/z80/lks19.c | 1 - as/link/z80/lksym.c | 33 +- 32 files changed, 4426 insertions(+), 4883 deletions(-) rename as/link/{mcs51 => }/aslink.h (93%) rename as/link/{mcs51 => }/lkstore.c (100%) delete mode 100644 as/link/mcs51/alloc.h delete mode 100644 as/link/z80/aslink.h diff --git a/ChangeLog b/ChangeLog index aa11c5f9..60b1c210 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,39 @@ +2006-09-17 Maarten Brock + + * as/link/aslink.h, + * as/link/mcs51/aslink.h, + * as/link/z80/aslink.h: merged and moved to as/link/ + * as/link/lkstore.c, + * as/link/mcs51/lkstore.c: moved to as/link/ + * as/link/clean.mk: remove *.o + * as/link/mcs51/alloc.h: deleted + * as/link/mcs51/lkarea.c: added lnksect prototype + * as/link/mcs51/lkdata.c, + * as/link/mcs51/lklex.c, + * as/link/mcs51/lkmain.c: renamed as_getline to lk_getline + * as/link/mcs51/lkmem.c, + * as/link/mcs51/lknoice.c: removed include strcmpi.h + * as/link/mcs51/lksym.c: include stdlib.h instead of malloc.h or alloc.h + * as/link/mcs51/aslink.dsp, + * as/link/mcs51/Makefile.aslink, + * as/link/mcs51/Makefile.bcc, + * as/link/mcs51/Makefile.in: updated for moved files + * as/link/z80/lkarea.c, + * as/link/z80/lkhead.c, + * as/link/z80/lklex.c, + * as/link/z80/lklibr.c, + * as/link/z80/lklist.c, + * as/link/z80/lkmain.c, + * as/link/z80/lkrloc.c, + * as/link/z80/lksym.c: synced with mcs51 + * as/link/z80/lkdata.c, + * as/link/z80/lkeval.c, + * as/link/z80/lkihx.c, + * as/link/z80/lks19.c: cosmetic changes + * as/link/z80/Makefile.in, + * as/link/z80/linkgbz80.dsp, + * as/link/z80/linkz80.dsp: updated for moved files + 2006-09-16 Borut Razem * debugger/mcs51/sdcdb.c: partially fixed diff --git a/as/link/mcs51/aslink.h b/as/link/aslink.h similarity index 93% rename from as/link/mcs51/aslink.h rename to as/link/aslink.h index bcd921d9..15796382 100644 --- a/as/link/mcs51/aslink.h +++ b/as/link/aslink.h @@ -1,7 +1,7 @@ /* aslink.h */ /* - * (C) Copyright 1989-1995 + * (C) Copyright 1989-1996 * All Rights Reserved * * Alan R. Baldwin @@ -18,9 +18,11 @@ * - add jflag and jfp for NoICE output * 30-Jan-98 JLH: * - add memory space flags to a_flag for 8051 + * + * Extensions: P. Felber */ -#define VERSION "V01.70 + NoICE + SDCC Feb 1999" +#define VERSION "V01.75 + NoICE + SDCC Feb 1999" /* * Case Sensitivity Flag @@ -177,25 +179,51 @@ /* * Area type flags */ -#define A_CON 0000 /* concatenate */ -#define A_OVR 0004 /* overlay */ -#define A_REL 0000 /* relocatable */ -#define A_ABS 0010 /* absolute */ -#define A_NOPAG 0000 /* non-paged */ -#define A_PAG 0020 /* paged */ +#define A_CON 0000 /* concatenate */ +#define A_OVR 0004 /* overlay */ +#define A_REL 0000 /* relocatable */ +#define A_ABS 0010 /* absolute */ +#define A_NOPAG 0000 /* non-paged */ +#define A_PAG 0020 /* paged */ /* Additional flags for 8051 address spaces */ -#define A_DATA 0000 /* data space (default)*/ -#define A_CODE 0040 /* code space */ -#define A_XDATA 0100 /* external data space */ -#define A_BIT 0200 /* bit addressable space */ +#define A_DATA 0000 /* data space (default)*/ +#define A_CODE 0040 /* code space */ +#define A_XDATA 0100 /* external data space */ +#define A_BIT 0200 /* bit addressable space */ + +/* Additional flags for hc08 */ +#define A_NOLOAD 0400 /* nonloadable */ +#define A_LOAD 0000 /* loadable (default) */ /* * File types */ +#define F_INV 0 /* invalid */ #define F_STD 1 /* stdin */ #define F_LNK 2 /* File.lnk */ #define F_REL 3 /* File.rel */ +#define F_CMD 4 /* Command line */ + +#ifdef GAMEBOY +/* + * Multiple banks support + */ +extern int nb_rom_banks; +extern int nb_ram_banks; +extern int current_rom_bank; +extern int mbc_type; +extern char cart_name[]; +/* + * ROM patching support + */ +typedef struct _patch { + unsigned int addr; + unsigned char value; + struct _patch *next; +} patch; +extern patch* patches; +#endif /* GAMEBOY */ /* * General assembler address type @@ -248,7 +276,7 @@ struct area struct areax *a_axp; /* Area extension link */ Addr_T a_addr; /* Beginning address of area */ Addr_T a_size; /* Total size of the area */ - Addr_T a_unaloc; /* Total number of unalocated bytes, for error reporting */ + Addr_T a_unaloc; /* Total number of unallocated bytes, for error reporting */ char a_type; /* Area subtype */ char a_flag; /* Flag byte */ char a_id[NCPS]; /* Name */ @@ -497,7 +525,7 @@ extern char ccase[]; /* an array of characters which extern struct lfile *filep; /* The pointers (lfile *) filep, * (lfile *) cfp, and (FILE *) sfp * are used in conjunction with - * the routine as_getline() to read + * the routine lk_getline() to read * asmlnk commands from * (1) the standard input or * (2) or a command file @@ -588,6 +616,8 @@ extern int stacksize; /* Pack data memory flag */ extern int jflag; /* NoICE output flag */ +extern int symflag; /* no$gmb .sym output flag + */ extern int xflag; /* Map file radix type flag */ extern int pflag; /* print linker command file flag @@ -671,6 +701,7 @@ extern VOID link_main(); extern VOID lkexit(); extern int main(); extern VOID map(); +extern VOID sym(); extern int parse(); extern VOID setbas(); extern VOID setgbl(); @@ -682,8 +713,8 @@ extern char endline(); extern char get(); extern VOID getfid(); extern VOID getid(); -extern VOID getSid(); -extern int as_getline(); +extern VOID getSid(char *id); +extern int lk_getline(); extern int getmap(); extern char getnb(); extern int more(); @@ -695,7 +726,6 @@ extern VOID chop_crlf(); extern VOID lkparea(); extern VOID lnkarea(); extern VOID lnkarea2(); -extern VOID lnksect(); extern VOID newarea(); /* lkhead.c */ @@ -774,10 +804,13 @@ extern VOID ihxEntendedLinearAddress(Addr_T); extern VOID newArea(); /* lkstore.c */ -extern char *StoreString( char *str ); +extern char * StoreString( char *str ); /* lknoice.c */ -extern void DefineNoICE( char *name, Addr_T value, int page ); +extern void DefineNoICE( char *name, Addr_T value, int page ); + +/* EEP: lkelf.c */ +extern VOID elf(); /* JCF: lkmem.c */ extern int summary(struct area * xp); @@ -786,3 +819,11 @@ extern int summary2(struct area * xp); /* JCF: lkaomf51.c */ extern void SaveLinkedFilePath(char * filepath); extern void CreateAOMF51(void); + +/* lkgb.h */ +VOID gb(int in); +VOID gg(int in); + +/* strcmpi.h */ +extern int as_strcmpi(const char *s1, const char *s2); +extern int as_strncmpi(const char *s1, const char *s2, size_t n); diff --git a/as/link/clean.mk b/as/link/clean.mk index e8435817..f573a002 100644 --- a/as/link/clean.mk +++ b/as/link/clean.mk @@ -1,5 +1,9 @@ clean: $(MAKE) -C z80 clean + rm -f *core *[%~] *.[oa] + rm -f .[a-z]*~ + rm -f *.dep + rm -rf obj distclean: clean $(MAKE) -C z80 distclean diff --git a/as/link/mcs51/lkstore.c b/as/link/lkstore.c similarity index 100% rename from as/link/mcs51/lkstore.c rename to as/link/lkstore.c diff --git a/as/link/mcs51/Makefile.aslink b/as/link/mcs51/Makefile.aslink index 0aebe56e..d9b44fc8 100644 --- a/as/link/mcs51/Makefile.aslink +++ b/as/link/mcs51/Makefile.aslink @@ -1,13 +1,15 @@ CC=gcc LEX=flex YACC=bison -INCROOT=. +INCROOT=.. CFLAGS=-ggdb -O2 -I $(INCROOT) TARGETS=$(SDCCDIR)/bin/aslink -ALLOBJECTS= lkmain.o lkhead.o lkarea.o lkdata.o\ +ALLOBJECTS= lkmain.o lkhead.o lkarea.o lkdata.o\ lkeval.o lklex.o lksym.o lkrloc.o\ lklibr.o lklist.o lkihx.o lks19.o\ - lkstore.o lknoice.o lkmem.o lkaomf51.o strcmpi.o + lknoice.o lkmem.o lkaomf51.o\ + ../lkstore.o\ + strcmpi.o all:: $(TARGETS) clean:: @@ -50,7 +52,7 @@ lks19.o : lks19.c aslink.h $(CC) $(CFLAGS) $(LDFLAGS) -c -o lks19.o lks19.c lkstore.o : lkstore.c aslink.h - $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkstore.o lkstore.c + $(CC) $(CFLAGS) $(LDFLAGS) -c -o ../lkstore.o ../lkstore.c lknoice.o : lknoice.c aslink.h $(CC) $(CFLAGS) $(LDFLAGS) -c -o lknoice.o lknoice.c @@ -65,4 +67,4 @@ lkaomf51.o : lkaomf51.c aslink.h $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkaomf51.o lkaomf51.c $(TARGETS): $(ALLOBJECTS) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(ALLOBJECTS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(ALLOBJECTS) diff --git a/as/link/mcs51/Makefile.bcc b/as/link/mcs51/Makefile.bcc index a61786ee..a087b1d2 100644 --- a/as/link/mcs51/Makefile.bcc +++ b/as/link/mcs51/Makefile.bcc @@ -7,7 +7,9 @@ PRJDIR = ../.. LKOBJECTS = lkmain.obj lkhead.obj lkarea.obj lkdata.obj \ lkeval.obj lklex.obj lksym.obj lkrloc.obj \ lklibr.obj lklist.obj lkihx.obj lks19.obj \ - lkstore.obj lknoice.obj lkmem.obj lkaomf51.obj strcmpi.obj + lknoice.obj lkmem.obj lkaomf51.obj \ + ../lkstore.obj \ + strcmpi.obj ASLINK = $(PRJDIR)/bin/aslink.exe diff --git a/as/link/mcs51/Makefile.in b/as/link/mcs51/Makefile.in index 90d52bd7..71e3d331 100644 --- a/as/link/mcs51/Makefile.in +++ b/as/link/mcs51/Makefile.in @@ -32,7 +32,7 @@ EXEEXT = @EXEEXT@ VPATH = @srcdir@ -CPPFLAGS = @CPPFLAGS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ -I.. -I$(srcdir) CFLAGS = @CFLAGS@ -Wall -DINDEXLIB M_OR_MM = @M_OR_MM@ LDFLAGS = @LDFLAGS@ @@ -40,7 +40,9 @@ LDFLAGS = @LDFLAGS@ LKOBJECTS = lkmain.o lkhead.o lkarea.o lkdata.o \ lkeval.o lklex.o lksym.o lkrloc.o \ lklibr.o lklist.o lkihx.o lks19.o \ - lkstore.o lknoice.o lkmem.o lkaomf51.o strcmpi.o + lknoice.o lkmem.o lkaomf51.o \ + ../lkstore.o \ + strcmpi.o LKSOURCES = $(patsubst %.o,%.c,$(LKOBJECTS)) ASLINK = $(top_builddir)bin/aslink$(EXEEXT) @@ -86,7 +88,7 @@ installdirs: # --------------------- dep: Makefile.dep -Makefile.dep: $(LKSOURCES) $(srcdir)/*.h $(top_builddir)*.h $(top_srcdir)/*.h +Makefile.dep: $(LKSOURCES) $(srcdir)/../*.h $(top_builddir)*.h $(top_srcdir)/*.h $(CPP) $(CPPFLAGS) $(M_OR_MM) $(filter %.c,$^) >Makefile.dep ifeq "$(findstring $(MAKECMDGOALS),uninstall check installcheck installdirs \ diff --git a/as/link/mcs51/alloc.h b/as/link/mcs51/alloc.h deleted file mode 100644 index dd404a86..00000000 --- a/as/link/mcs51/alloc.h +++ /dev/null @@ -1,4 +0,0 @@ -/* alloc.h */ -/* DECUS C */ - -#include diff --git a/as/link/mcs51/aslink.dsp b/as/link/mcs51/aslink.dsp index f19847e1..9d49a88d 100644 --- a/as/link/mcs51/aslink.dsp +++ b/as/link/mcs51/aslink.dsp @@ -7,19 +7,19 @@ CFG=aslink - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "aslink.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "aslink.mak" CFG="aslink - Win32 Release" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "aslink - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE "aslink - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FR /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FR /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FR /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FD /c -# ADD CPP /nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FD /c +# ADD CPP /nologo /ML /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -77,7 +77,7 @@ LINK32=link.exe # ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept # ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept -!ENDIF +!ENDIF # Begin Target @@ -144,7 +144,7 @@ SOURCE=.\lks19.c # End Source File # Begin Source File -SOURCE=.\lkstore.c +SOURCE=..\lkstore.c # End Source File # Begin Source File @@ -160,16 +160,12 @@ SOURCE=.\strcmpi.c # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=.\alloc.h +SOURCE=..\alloc.h # End Source File # Begin Source File SOURCE=.\aslink.h # End Source File -# Begin Source File - -SOURCE=.\strcmpi.h -# End Source File # End Group # End Target # End Project diff --git a/as/link/mcs51/lkarea.c b/as/link/mcs51/lkarea.c index 96a91307..a227b71f 100644 --- a/as/link/mcs51/lkarea.c +++ b/as/link/mcs51/lkarea.c @@ -315,6 +315,7 @@ lkparea(char *id) * structures. */ +VOID lnksect(register struct area *tap); /* * Resolve all area addresses. */ diff --git a/as/link/mcs51/lkdata.c b/as/link/mcs51/lkdata.c index 64af18b2..f49d03a4 100644 --- a/as/link/mcs51/lkdata.c +++ b/as/link/mcs51/lkdata.c @@ -122,7 +122,7 @@ long code_size=-1; /* code size struct lfile *filep; /* The pointers (lfile *) filep, * (lfile *) cfp, and (FILE *) sfp * are used in conjunction with - * the routine as_getline() to read + * the routine lk_getline() to read * asmlnk commands from * (1) the standard input or * (2) or a command file diff --git a/as/link/mcs51/lklex.c b/as/link/mcs51/lklex.c index 7c481300..73093ce9 100644 --- a/as/link/mcs51/lklex.c +++ b/as/link/mcs51/lklex.c @@ -24,7 +24,7 @@ * VOID getfid() * VOID getid() * VOID getSid() - * int as_getline() + * int lk_getline() * int getmap() * char getnb() * int more() @@ -103,7 +103,7 @@ char *id; * 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 @@ -135,13 +135,12 @@ char *id; */ VOID -getSid (id) -char *id; +getSid (char *id) { - register int c; + register int c; register char *p; - c = getnb(); + c = getnb(); p = id; do { if (p < &id[NCPS]) @@ -251,7 +250,7 @@ getnb() * global variables: * char ctype[] array of character types, one per * ASCII character - * + * * functions called: * char get() lklex.c * char getnb() lklex.c @@ -425,15 +424,15 @@ getmap(d) return (c); } -/*)Function int as_getline() +/*)Function int lk_getline() * - * The function as_getline() reads a line of input text from a + * 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 - * as_getline() returns a (1) after succesfully reading a line + * 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. @@ -479,7 +478,7 @@ getmap(d) */ int -as_getline() +lk_getline() { register int ftype; register char *fid; diff --git a/as/link/mcs51/lkmain.c b/as/link/mcs51/lkmain.c index 43392b83..8448a6d3 100644 --- a/as/link/mcs51/lkmain.c +++ b/as/link/mcs51/lkmain.c @@ -150,7 +150,7 @@ void Areas51 (void) * * The function main() evaluates the command line arguments to * determine if the linker parameters are to input through 'stdin' - * or read from a command file. The functions as_getline() and parse() + * or read from a command file. The functions lk_getline() and parse() * are to input and evaluate the linker parameters. The linking process * proceeds by making the first pass through each .rel file in the order * presented to the linker. At the end of the first pass the setbase(), @@ -204,7 +204,7 @@ void Areas51 (void) * FILE * afile() lkmain.c * int fclose() c_library * int fprintf() c_library - * int as_getline() lklex.c + * int lk_getline() lklex.c * VOID library() lklibr.c * VOID link_main() lkmain.c * VOID lkexit() lkmain.c @@ -285,7 +285,7 @@ main(int argc, char *argv[]) filep = startp; while (1) { ip = ib; - if (as_getline() == 0) + if (lk_getline() == 0) break; if (pflag && sfp != stdin) fprintf(stdout, "%s\n", ip); @@ -320,7 +320,7 @@ main(int argc, char *argv[]) Areas51(); /*JCF: Create the default 8051 areas in the right order*/ - while (as_getline()) { + while (lk_getline()) { ip = ib; /* pass any "magic comments" to NoICE output */ diff --git a/as/link/mcs51/lkmem.c b/as/link/mcs51/lkmem.c index 47fc14d4..b0132cf0 100644 --- a/as/link/mcs51/lkmem.c +++ b/as/link/mcs51/lkmem.c @@ -22,7 +22,6 @@ #include #include #include "aslink.h" -#include "strcmpi.h" int summary(struct area * areap) { diff --git a/as/link/mcs51/lknoice.c b/as/link/mcs51/lknoice.c index 2cd6a91c..d9209b6b 100644 --- a/as/link/mcs51/lknoice.c +++ b/as/link/mcs51/lknoice.c @@ -12,7 +12,6 @@ #include #include #include "aslink.h" -#include "strcmpi.h" static void DefineGlobal( char *name, Addr_T value, int page ); static void DefineScoped( char *name, Addr_T value, int page ); diff --git a/as/link/mcs51/lksym.c b/as/link/mcs51/lksym.c index 1ebc49cc..526e7189 100644 --- a/as/link/mcs51/lksym.c +++ b/as/link/mcs51/lksym.c @@ -16,11 +16,7 @@ #include #include -#if defined(_MSC_VER) -#include -#else -#include -#endif +#include #include "aslink.h" /*)Module lksym.c diff --git a/as/link/z80/Makefile.in b/as/link/z80/Makefile.in index 1f67a7f7..1c3367e7 100644 --- a/as/link/z80/Makefile.in +++ b/as/link/z80/Makefile.in @@ -11,13 +11,15 @@ 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 \ - lkgb.c lkgg.c + lkgb.c lkgg.c \ + ../lkstore.c OBJS = $(SRC:%.c=$(OBJDIR)/%.o) SLIBOBJS = $(SLIBSRC:%.c=$(OBJDIR)/%.o) BINS = $(BUILDDIR)link$(EXT)$(EXEEXT) +CPPFLAGS+= -I.. CFLAGS += $(CPPFLAGS) $(OPTS) -DINDEXLIB -DMLH_MAP -DUNIX -DSDK CFLAGS += -funsigned-char -DUNIX CFLAGS += -I$(top_builddir)as/$(PORT) -I$(SLIB) diff --git a/as/link/z80/aslink.h b/as/link/z80/aslink.h deleted file mode 100644 index e18cd023..00000000 --- a/as/link/z80/aslink.h +++ /dev/null @@ -1,737 +0,0 @@ -/* aslink.h */ - -/* - * (C) Copyright 1989-1996 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -/* - * Extensions: P. Felber - */ -#define VERSION "V01.75" - -/* - * Case Sensitivity Flag - */ -#define CASE_SENSITIVE 1 - -/*)Module asmlnk.h - * - * The module asmlnk.h contains the definitions for constants, - * structures, global variables, and LKxxxx functions - * contained in the LKxxxx.c files. - */ - -/*)BUILD - $(PROGRAM) = ASLINK - $(INCLUDE) = ASLINK.H - $(FILES) = { - LKMAIN.C - LKLEX.C - LKAREA.C - LKHEAD.C - LKSYM.C - LKEVAL.C - LKDATA.C - LKLIST.C - LKRLOC.C - LKLIBR.C - LKS19.C - LKIHX.C - } - $(STACK) = 2000 -*/ - -/* DECUS C void definition */ -/* File/extension seperator */ - -#ifdef decus -#define VOID char -#define FSEPX '.' -#endif - -/* PDOS C void definition */ -/* File/extension seperator */ - -#ifdef PDOS -#define VOID char -#define FSEPX ':' -#endif - -/* Default void definition */ -/* File/extension seperator */ - -#ifndef VOID -#define VOID void -#define FSEPX '.' -#define OTHERSYSTEM -#endif - -/* - * PATH_MAX - */ -#include -#ifndef PATH_MAX /* POSIX, but not required */ - #if defined(__BORLANDC__) || defined(_MSC_VER) - #include - #define PATH_MAX _MAX_PATH - #else - #define PATH_MAX 255 /* define a reasonable value */ - #endif -#endif - -/* - * This file defines the format of the - * relocatable binary file. - */ - -#ifdef SDK -#define NCPS 80 /* characters per symbol. Used to be 32... */ -#else /* SDK */ -#define NCPS 8 /* characters per symbol */ -#endif /* SDK */ -/* #define NCPS 32 */ /* characters per symbol */ -#define NDATA 16 /* actual data */ -#define NINPUT PATH_MAX /* Input buffer size */ -#define NHASH 64 /* Buckets in hash table */ -#define HMASK 077 /* Hash mask */ -#define NLPP 60 /* Lines per page */ -#define NTXT 16 /* T values */ -#define FILSPC PATH_MAX /* File spec length */ - -/* - * The "R_" relocation constants define values used in - * generating the assembler relocation output data for - * areas, symbols, and code. - * - * - * Relocation types. - * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - */ - -#define R_WORD 0x00 /* 16 bit */ -#define R_BYTE 0x01 /* 8 bit */ - -#define R_AREA 0x00 /* Base type */ -#define R_SYM 0x02 - -#define R_NORM 0x00 /* PC adjust */ -#define R_PCR 0x04 - -#define R_BYT1 0x00 /* Byte count for R_BYTE = 1 */ -#define R_BYT2 0x08 /* Byte count for R_BYTE = 2 */ - -#define R_SGND 0x00 /* Signed value */ -#define R_USGN 0x10 /* Unsigned value */ - -#define R_NOPAG 0x00 /* Page Mode */ -#define R_PAG0 0x20 /* Page '0' */ -#define R_PAG 0x40 /* Page 'nnn' */ - -/* - * Valid for R_BYT2: - */ -#define R_LSB 0x00 /* output low byte */ -#define R_MSB 0x80 /* output high byte */ - -/* - * Global symbol types. - */ -#define S_REF 1 /* referenced */ -#define S_DEF 2 /* defined */ - -/* - * Area types - */ -#define A_CON 0000 /* concatenate */ -#define A_OVR 0004 /* overlay */ -#define A_REL 0000 /* relocatable */ -#define A_ABS 0010 /* absolute */ -#define A_NOPAG 0000 /* non-paged */ -#define A_PAG 0020 /* paged */ - -/* - * File types - */ -#define F_INV 0 /* invalid */ -#define F_STD 1 /* stdin */ -#define F_LNK 2 /* File.lnk */ -#define F_REL 3 /* File.rel */ -#ifdef SDK -#define F_CMD 4 /* Command line */ -#endif /* SDK */ - -#ifdef GAMEBOY -/* - * Multiple banks support - */ -extern int nb_rom_banks; -extern int nb_ram_banks; -extern int current_rom_bank; -extern int mbc_type; -extern char cart_name[]; -/* - * ROM patching support - */ -typedef struct _patch { - unsigned int addr; - unsigned char value; - struct _patch *next; -} patch; -extern patch* patches; -#endif /* GAMEBOY */ -/* - * General assembler address type - */ -typedef unsigned int Addr_T; - -/* - * 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; /* Globle symbol list */ - char m_id[NCPS]; /* Module name */ -}; - -/* - * 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 */ -}; - -/* - * 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 */ -}; - -/* - * 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[NCPS]; /* Name */ -}; - -/* - * 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 */ -}; - -/* - * 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 */ -}; - -/* - * 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 */ -}; - -/* - * 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 */ -}; - -/* - * 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 */ -}; - -/* - * 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; -}; - -/* - * 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; -}; - -/* - * 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; - long offset; /*>=0 if rel file is embedded in a lib file at this offset*/ -}; - -/* - * External Definitions for all Global Variables - */ - -extern char *_abs_; /* = { ". .ABS." }; - */ -extern int lkerr; /* ASLink error flag - */ -extern char *ip; /* pointer into the REL file - * text line in ib[] - */ -extern char ib[NINPUT]; /* REL file text line - */ -extern char *rp; /* pointer into the LST file - * text line in rb[] - */ -extern char rb[NINPUT]; /* LST file text line being - * address relocated - */ -extern unsigned char ctype[]; /* array of character types, one per - * ASCII character - */ - -extern char sdccopt[NINPUT]; -extern char sdccopt_module[NINPUT]; -extern char curr_module[NINPUT]; - -/* - * Character Type Definitions - */ -#define SPACE 0000 -#define ETC 0000 -#define LETTER 0001 -#define DIGIT 0002 -#define BINOP 0004 -#define RAD2 0010 -#define RAD8 0020 -#define RAD10 0040 -#define RAD16 0100 -#define ILL 0200 - -#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 -#define DGT8 DIGIT|RAD16|RAD10|RAD8 -#define DGT10 DIGIT|RAD16|RAD10 -#define LTR16 LETTER|RAD16 - -#if CASE_SENSITIVE -#else -extern char ccase[]; /* an array of characters which - * perform the case translation function - */ -#endif - -extern 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. - */ -extern struct lfile *cfp; /* The pointer *cfp points to the - * current lfile structure - */ -extern struct lfile *startp;/* asmlnk startup file structure - */ -extern struct lfile *linkp; /* pointer to first lfile structure - * containing an input REL file - * specification - */ -extern struct lfile *lfp; /* pointer to current lfile structure - * being processed by parse() - */ -extern struct head *headp; /* The pointer to the first - * head structure of a linked list - */ -extern struct head *hp; /* Pointer to the current - * head structure - */ -extern struct area *areap; /* The pointer to the first - * area structure of a linked list - */ -extern struct area *ap; /* Pointer to the current - * area structure - */ -extern struct areax *axp; /* Pointer to the current - * areax structure - */ -extern struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -extern struct base *basep; /* The pointer to the first - * base structure - */ -extern struct base *bsp; /* Pointer to the current - * base structure - */ -extern struct globl *globlp;/* The pointer to the first - * globl structure - */ -extern struct globl *gsp; /* Pointer to the current - * globl structure - */ -extern struct sdp sdp; /* Base Paged structure - */ -extern struct rerr rerr; /* Structure containing the - * linker error information - */ -extern FILE *ofp; /* Linker Output file handle - */ -extern FILE *mfp; /* Map output file handle - */ -extern FILE *rfp; /* File handle for output - * address relocated ASxxxx - * listing file - */ -extern FILE *sfp; /* The file handle sfp points to the - * currently open file - */ -extern FILE *tfp; /* File handle for input - * ASxxxx listing file - */ -extern int oflag; /* Output file type flag - */ -extern int mflag; /* Map output flag - */ -#ifdef SDK -extern int symflag; /* no$gmb .sym output flag - */ -#endif -extern int xflag; /* Map file radix type flag - */ -extern int pflag; /* print linker command file flag - */ -extern int uflag; /* Listing relocation flag - */ -extern int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -extern int line; /* current line number - */ -extern int page; /* current page number - */ -extern int lop; /* current line number on page - */ -extern int pass; /* linker pass number - */ -extern int rtcnt; /* count of elements in the - * rtval[] and rtflg[] arrays - */ -extern Addr_T rtval[]; /* data associated with relocation - */ -extern int rtflg[]; /* indicates if rtval[] value is - * to be sent to the output file. - * (always set in this linker) - */ -extern int hilo; /* REL file byte ordering - */ -extern int gline; /* LST file relocation active - * for current line - */ -extern int gcntr; /* LST file relocation active - * counter - */ -extern struct lbpath *lbphead; /* pointer to the first - * library path structure - */ -extern struct lbname *lbnhead; /* pointer to the first - * library name structure - */ -extern struct lbfile *lbfhead; /* pointer to the first - * library file structure - */ - -/* C Library function definitions */ -/* for reference only -extern VOID exit(); -extern int fclose(); -extern char * fgets(); -extern FILE * fopen(); -extern int fprintf(); -extern VOID free(); -extern VOID * malloc(); -extern char putc(); -extern char * strcpy(); -extern int strlen(); -extern char * strncpy(); -*/ - -/* Program function definitions */ - -/* lkmain.c */ -extern FILE * afile(); -extern VOID bassav(); -extern VOID gblsav(); -extern VOID link(); -extern VOID lkexit(); -extern int main(); -extern VOID map(); -#ifdef SDK -extern VOID sym(); -#endif -extern int parse(); -extern VOID setbas(); -extern VOID setgbl(); -extern VOID usage(); - -/* lklex.c */ -extern char endline(); -extern char get(); -extern VOID getfid(); -extern VOID getid(); -extern int lk_getline(); -extern int getmap(); -extern char getnb(); -extern int more(); -extern VOID skip(); -extern VOID unget(); -extern VOID chop_crlf(); - -/* lkarea.c */ -extern VOID lkparea(); -extern VOID lnkarea(); -extern VOID lnksect(); -extern VOID newarea(); - -/* lkhead.c */ -extern VOID module(); -extern VOID newhead(); - -/* lksym.c */ -extern int hash(); -extern struct sym * lkpsym(); -extern VOID * new(); -extern struct sym * newsym(); -extern VOID symdef(); -extern int symeq(); -extern VOID syminit(); -extern VOID symmod(); -extern Addr_T symval(); - -/* lkeval.c */ -extern int digit(); -extern Addr_T eval(); -extern Addr_T expr(); -extern int oprio(); -extern Addr_T term(); - -/* lklist.c */ -extern int dgt(); -extern VOID lkulist(); -extern VOID lkalist(); -extern VOID lkglist(); -extern VOID lstarea(); -extern VOID newpag(); -extern VOID slew(); - -/* lkrloc.c */ -extern Addr_T adb_b(); -extern Addr_T adb_hi(); -extern Addr_T adb_lo(); -extern Addr_T adw_w(); -extern Addr_T adw_hi(); -extern Addr_T adw_lo(); -extern Addr_T evword(); -extern VOID rele(); -extern VOID reloc(); -extern VOID relt(); -extern VOID relr(); -extern VOID relp(); -extern VOID relerr(); -extern char * errmsg[]; -extern VOID errdmp(); -extern VOID relerp(); -extern VOID erpdmp(); -extern VOID prntval(); - -/* lklibr.c */ -extern int addfile(); -extern VOID addlib(); -extern VOID addpath(); -extern int fndsym(); -extern VOID library(); -extern VOID loadfile(); -extern VOID search(); - -/* lks19.c */ -extern VOID s19(); - -/* lkihx.c */ -extern VOID ihx(); - -/* lkgb.h */ -VOID gb(int in); -VOID gg(int in); - diff --git a/as/link/z80/linkgbz80.dsp b/as/link/z80/linkgbz80.dsp index db0fa18e..f806a65b 100644 --- a/as/link/z80/linkgbz80.dsp +++ b/as/link/z80/linkgbz80.dsp @@ -7,19 +7,19 @@ CFG=linkgbz80 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "linkgbz80.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "linkgbz80.mak" CFG="linkgbz80 - Win32 Debug" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "linkgbz80 - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "linkgbz80 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -78,7 +78,7 @@ LINK32=link.exe # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\link-gbz80.exe" /pdbtype:sept # SUBTRACT LINK32 /pdb:none -!ENDIF +!ENDIF # Begin Target @@ -154,6 +154,11 @@ SOURCE=.\lks19.c # End Source File # Begin Source File +SOURCE=..\lkstore.c +# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" +# End Source File +# Begin Source File + SOURCE=.\lksym.c # ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY" # End Source File @@ -163,7 +168,7 @@ SOURCE=.\lksym.c # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=.\aslink.h +SOURCE=..\aslink.h # End Source File # End Group # Begin Group "Resource Files" diff --git a/as/link/z80/linkz80.dsp b/as/link/z80/linkz80.dsp index cc287c78..1f8d8b96 100644 --- a/as/link/z80/linkz80.dsp +++ b/as/link/z80/linkz80.dsp @@ -7,19 +7,19 @@ CFG=linkz80 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "linkz80.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "linkz80.mak" CFG="linkz80 - Win32 Debug" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "linkz80 - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "linkz80 - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -78,7 +78,7 @@ LINK32=link.exe # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\link-z80.exe" /pdbtype:sept # SUBTRACT LINK32 /pdb:none -!ENDIF +!ENDIF # Begin Target @@ -154,6 +154,11 @@ SOURCE=.\lks19.c # End Source File # Begin Source File +SOURCE=..\lkstore.c +# ADD CPP /D "SDK" /D "INDEXLIB" +# End Source File +# Begin Source File + SOURCE=.\lksym.c # ADD CPP /D "SDK" /D "INDEXLIB" # End Source File @@ -163,7 +168,7 @@ SOURCE=.\lksym.c # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=.\aslink.h +SOURCE=..\aslink.h # End Source File # End Group # Begin Group "Resource Files" diff --git a/as/link/z80/lkarea.c b/as/link/z80/lkarea.c index deb61c99..75de7c65 100644 --- a/as/link/z80/lkarea.c +++ b/as/link/z80/lkarea.c @@ -33,7 +33,7 @@ * The function newarea() creates and/or modifies area * and areax structures for each A directive read from * the .rel file(s). The function lkparea() is called - * to find tha area structure associated with this name. + * to find the area structure associated with this name. * If the area does not yet exist then a new area * structure is created and linked to any existing * linked area structures. The area flags are copied @@ -187,8 +187,7 @@ newarea() */ VOID -lkparea(id) -char *id; +lkparea(char *id) { register struct area *tap; register struct areax *taxp; @@ -220,6 +219,7 @@ char *id; axp->a_bap = ap; axp->a_bhp = hp; strncpy(ap->a_id, id, NCPS); + ap->a_addr = 0; } /*)Function VOID lnkarea() @@ -262,7 +262,7 @@ char *id; * area address. The size of the area * is the sum of the section sizes. * - * NOTE: Relocatable (REL) areas ae always concatenated + * NOTE: Relocatable (REL) areas are always concatenated * with each other, thus relocatable area B * (defined after area A) will follow * relocatable area A independent of the @@ -295,9 +295,9 @@ char *id; * functions called: * int fprintf() c_library * VOID lnksect() lkarea.c - * symbol *lkpsym() lksysm.c + * symbol *lkpsym() lksym.c * char * strncpy() c_library - * int symeq() lksysm.c + * int symeq() lksym.c * * side effects: * All area and areax addresses and sizes are @@ -305,20 +305,73 @@ char *id; * structures. */ +unsigned long codemap[2048]; +Addr_T lnksect(register struct area *tap); /* * Resolve all area addresses. */ VOID lnkarea() { - register int rloc; + register Addr_T rloc = 0; + Addr_T gs_size = 0; char temp[NCPS]; struct sym *sp; + struct area *abs_ap = NULL; + struct area *gs0_ap = NULL; + + memset(codemap, 0, sizeof(codemap)); + + /* first sort all absolute areas to the front */ + ap = areap; + /* no need to check first area, it's in front anyway */ + while (ap && ap->a_ap) + { + if (ap->a_ap->a_flag & A_ABS) + {/* next area is absolute, move it to front, + reversed sequence is no problem for absolutes */ + abs_ap = ap->a_ap; + ap->a_ap = abs_ap->a_ap; + abs_ap->a_ap = areap; + areap = abs_ap; + } + else + { + ap = ap->a_ap; + } + } + + /* next accumulate all GSINITx/GSFINAL area sizes + into GSINIT so they stay together */ + ap = areap; + while (ap) + { + if (!strncmp(ap->a_id, "GS", 2)) + {/* GSxxxxx area */ + if (ap->a_size == 0) + { + axp = ap->a_axp; + while (axp) + { + ap->a_size += axp->a_size; + axp = axp->a_axp; + } + } + gs_size += ap->a_size; + if (!strcmp(ap->a_id, "GSINIT0")) + {/* GSINIT0 area */ + gs0_ap = ap; + } + } + ap = ap->a_ap; + } + if (gs0_ap) + gs0_ap->a_size = gs_size; - rloc = 0; ap = areap; - while (ap) { - if (ap->a_flag&A_ABS) { + while (ap) + { + if (ap->a_flag & A_ABS) { /* * Absolute sections */ @@ -329,8 +382,7 @@ lnkarea() */ if (ap->a_addr == 0) ap->a_addr = rloc; - lnksect(ap); - rloc = ap->a_addr + ap->a_size; + rloc = lnksect(ap); } /* @@ -339,7 +391,8 @@ lnkarea() * l_ the length of the area */ - if (! symeq(ap->a_id, _abs_)) { + if (! symeq(ap->a_id, _abs_)) + { strncpy(temp+2,ap->a_id,NCPS-2); *(temp+1) = '_'; @@ -359,6 +412,85 @@ lnkarea() } } +static +Addr_T find_empty_space(Addr_T start, Addr_T size, unsigned long *map) +{ + int i, j, k; + unsigned long mask, b; + + while (1) + { + Addr_T a = start; + i = start >> 5; + j = (start + size) >> 5; + mask = -(1 << (start & 0x1F)); + + while (i < j) + { + if (map[i] & mask) + { + k = 32; + for (b=0x80000000; b!=0; b>>=1, k--) + { + if (map[i] & b) + break; + } + start = a + k; + break; + } + i++; + mask = 0xFFFFFFFF; + a += 32; + } + if (start > a) + continue; + + mask &= (1 << ((start + size) & 0x1F)) - 1; + if (map[i] & mask) + { + k = 32; + for (b=0x80000000; b!=0; b>>=1, k--) + { + if (map[i] & b) + break; + } + start = (a & ~0x1F) + k; + } + if (start <= a) + break; + } + return start; +} + +static +Addr_T allocate_space(Addr_T start, Addr_T size, char* id, unsigned long *map) +{ + int i, j; + unsigned long mask; + Addr_T a = start; + i = start >> 5; + j = (start + size) >> 5; + mask = -(1 << (start & 0x1F)); + + while (i < j) + { + if (map[i] & mask) + { + fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id); + } + map[i++] |= mask; + mask = 0xFFFFFFFF; + a += 32; + } + mask &= (1 << ((start + size) & 0x1F)) - 1; + if (map[i] & mask) + { + fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id); + } + map[i] |= mask; + return start; +} + /*)Function VOID lnksect() * * area * tap pointer to an area structure @@ -385,9 +517,7 @@ lnkarea() * and linked into the structures. */ -VOID -lnksect(tap) -register struct area *tap; +Addr_T lnksect(register struct area *tap) { register Addr_T size, addr; register struct areax *taxp; @@ -399,8 +529,9 @@ register struct area *tap; "\n?ASlink-Warning-Paged Area %.8s Boundary Error\n", tap->a_id); lkerr++; } + taxp = tap->a_axp; - if (tap->a_flag&A_OVR) { + if (tap->a_flag & A_OVR) { /* * Overlayed sections */ @@ -410,11 +541,35 @@ register struct area *tap; size = taxp->a_size; taxp = taxp->a_axp; } - } else { + } + else if (tap->a_flag & A_ABS) + { + /* + * Absolute sections + */ + while (taxp) + { + allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap); + taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */ + size += taxp->a_size; + taxp = taxp->a_axp; + } + } + else + { /* * Concatenated sections */ + if (tap->a_size) { + addr = find_empty_space(addr, tap->a_size, codemap); + } while (taxp) { + //find next unused address now + if (taxp->a_size) + { + addr = find_empty_space(addr, taxp->a_size, codemap); + allocate_space(addr, taxp->a_size, tap->a_id, codemap); + } taxp->a_addr = addr; addr += taxp->a_size; size += taxp->a_size; @@ -422,9 +577,12 @@ register struct area *tap; } } tap->a_size = size; - if ((tap->a_flag&A_PAG) && (size > 256)) { + + if ((tap->a_flag & A_PAG) && (size > 256)) + { fprintf(stderr, "\n?ASlink-Warning-Paged Area %.8s Length Error\n", tap->a_id); lkerr++; } + return addr; } diff --git a/as/link/z80/lkdata.c b/as/link/z80/lkdata.c index 3d075b7d..bd1ed03e 100644 --- a/as/link/z80/lkdata.c +++ b/as/link/z80/lkdata.c @@ -11,7 +11,6 @@ #include #include -//#include #include "aslink.h" /*)Module lkdata.c @@ -254,7 +253,7 @@ struct areax *axp; /* Pointer to the current * char s_type; Symbol subtype * char s_flag; Flag byte * Addr_T s_addr; Address - * char s_id[NCPS]; Name + * char *s_id; Name (JLH) * }; */ struct sym *symhash[NHASH]; /* array of pointers to NHASH diff --git a/as/link/z80/lkeval.c b/as/link/z80/lkeval.c index e4bfe1d5..14e9cf67 100644 --- a/as/link/z80/lkeval.c +++ b/as/link/z80/lkeval.c @@ -11,7 +11,6 @@ #include #include -//#include #include "aslink.h" /*)Module lkeval.c @@ -304,7 +303,7 @@ term() } } /* Shouldn't get here. */ - return 0; + return(0); } /*)Function int digit(c, r) diff --git a/as/link/z80/lkhead.c b/as/link/z80/lkhead.c index 3eb127d9..41a5198c 100644 --- a/as/link/z80/lkhead.c +++ b/as/link/z80/lkhead.c @@ -11,7 +11,6 @@ #include #include -//#include #include "aslink.h" /*Module lkhead.c @@ -108,7 +107,7 @@ newhead() * Setup Absolute DEF linkage. */ lkparea(_abs_); - ap->a_flag = A_ABS|A_OVR; + ap->a_flag = A_ABS; } /*)Function VOID module() diff --git a/as/link/z80/lkihx.c b/as/link/z80/lkihx.c index 082a5fc5..a3d3b020 100644 --- a/as/link/z80/lkihx.c +++ b/as/link/z80/lkihx.c @@ -11,7 +11,6 @@ #include #include -//#include #include "aslink.h" /*)Module lkihx.c @@ -20,7 +19,7 @@ * output the relocated object code in the * Intel Hex format. * - * lkihx.c contains the following function: + * lkihx.c contains the following functions: * VOID ihx(i) * * lkihx.c contains no local variables. diff --git a/as/link/z80/lklex.c b/as/link/z80/lklex.c index 1ccdeea8..642062dc 100644 --- a/as/link/z80/lklex.c +++ b/as/link/z80/lklex.c @@ -15,7 +15,6 @@ #include #include -//#include #include "aslink.h" /*)Module lklex.c @@ -28,6 +27,7 @@ * char get() * VOID getfid() * VOID getid() + * VOID getSid() * int lk_getline() * int getmap() * char getnb() @@ -99,10 +99,67 @@ char *id; *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 FILSPC + * maximum length PATH_MAX * int c this is first character to * copy to the string buffer * @@ -111,7 +168,7 @@ char *id; * 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 - * FILSPC characters then the string is truncated, if the input string + * 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: @@ -140,8 +197,9 @@ char *str; register char *p; p = str; - do { - if (p < &str[FILSPC-1]) + do + { + if (p < &str[PATH_MAX-1]) *p++ = c; c = get(); if (c == ';') @@ -152,7 +210,7 @@ char *str; #else /* SDK */ } while (c && (ctype[c] != SPACE)); #endif /* SDK */ - while (p < &str[FILSPC]) + while (p < &str[PATH_MAX]) *p++ = 0; } @@ -426,7 +484,7 @@ getmap(d) int lk_getline() { - register int i, ftype; + register int ftype; register char *fid; loop: if (pflag && cfp && cfp->f_type == F_STD) @@ -501,9 +559,7 @@ loop: if (pflag && cfp && cfp->f_type == F_STD) return(0); } } - i = strlen(ib) - 1; - if (ib[i] == '\n') - ib[i] = 0; + chop_crlf(ib); return (1); } diff --git a/as/link/z80/lklibr.c b/as/link/z80/lklibr.c index c3761bbd..0fb575c9 100644 --- a/as/link/z80/lklibr.c +++ b/as/link/z80/lklibr.c @@ -23,23 +23,22 @@ #define MAXLINE 254 /*when using fgets*/ #include -#include #include -#include +#include #include "aslink.h" -#ifdef OTHERSYSTEM +#ifdef OTHERSYSTEM #ifdef SDK #ifdef UNIX #define LKDIRSEP '/' #define LKDIRSEPSTR "/" #else /* UNIX */ - #define LKDIRSEP '\\' - #define LKDIRSEPSTR "\\" + #define LKDIRSEP '\\' + #define LKDIRSEPSTR "\\" #endif /* UNIX */ #else /* SDK */ - #define LKDIRSEP '\\' - #define LKDIRSEPSTR "\\" + #define LKDIRSEP '\\' + #define LKDIRSEPSTR "\\" #endif /* SDK */ #endif @@ -49,22 +48,22 @@ #define LKOBJEXT "rel" #endif /* SDK */ -/*)Module lklibr.c +/*)Module lklibr.c * - * The module lklibr.c contains the functions which - * (1) specify the path(s) to library files [.LIB] - * (2) specify the library file(s) [.LIB] to search - * (3) search the library files for specific symbols - * and link the module containing this symbol + * The module lklibr.c contains the functions which + * (1) specify the path(s) to library files [.LIB] + * (2) specify the library file(s) [.LIB] to search + * (3) search the library files for specific symbols + * and link the module containing this symbol * - * lklibr.c contains the following functions: - * VOID addpath() - * VOID addlib() - * VOID addfile() - * VOID search() - * VOID fndsym() - * VOID library() - * VOID loadfile() + * lklibr.c contains the following functions: + * VOID addpath() + * VOID addlib() + * VOID addfile() + * VOID search() + * VOID fndsym() + * VOID library() + * VOID loadfile() * */ @@ -73,21 +72,21 @@ typedef struct slibrarysymbol mlibrarysymbol; typedef struct slibrarysymbol *pmlibrarysymbol; struct slibrarysymbol { - char * name; /*Warning: allocate memory before using*/ - pmlibrarysymbol next; + char * name; /*Warning: allocate memory before using*/ + pmlibrarysymbol next; }; typedef struct slibraryfile mlibraryfile; typedef struct slibraryfile *pmlibraryfile; struct slibraryfile { - int loaded; - char * libspc; - char * relfil; /*Warning: allocate memory before using*/ - char * filename; /*Warning: allocate memory before using*/ + int loaded; + char * libspc; + char * relfil; /*Warning: allocate memory before using*/ + char * filename; /*Warning: allocate memory before using*/ long offset; //if > 0, the embedded file offset in the library file libspc - pmlibrarysymbol symbols; - pmlibraryfile next; + pmlibrarysymbol symbols; + pmlibraryfile next; }; /* First entry in the library object symbol cache */ @@ -97,133 +96,133 @@ int buildlibraryindex(); void freelibraryindex (void); #endif /* INDEXLIB */ -/*)Function VOID addpath() +/*)Function VOID addpath() * - * The function addpath() creates a linked structure containing - * the paths to various object module library files. + * The function addpath() creates a linked structure containing + * the paths to various object module library files. * - * local variables: - * lbpath *lbph pointer to new path structure - * lbpath *lbp temporary pointer + * local variables: + * lbpath *lbph pointer to new path structure + * lbpath *lbp temporary pointer * - * global variables: - * lbpath *lbphead The pointer to the first - * path structure + * global variables: + * lbpath *lbphead The pointer to the first + * path structure * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * An lbpath structure may be created. + * side effects: + * An lbpath structure may be created. */ VOID addpath() { - struct lbpath *lbph, *lbp; - - lbph = (struct lbpath *) new (sizeof(struct lbpath)); - if (lbphead == NULL) { - lbphead = lbph; - } else { - lbp = lbphead; - while (lbp->next) - lbp = lbp->next; - lbp->next = lbph; - } - unget(getnb()); - lbph->path = (char *) new (strlen(ip)+1); - strcpy(lbph->path, ip); + struct lbpath *lbph, *lbp; + + lbph = (struct lbpath *) new (sizeof(struct lbpath)); + if (lbphead == NULL) { + lbphead = lbph; + } else { + lbp = lbphead; + while (lbp->next) + lbp = lbp->next; + lbp->next = lbph; + } + unget(getnb()); + lbph->path = (char *) new (strlen(ip)+1); + strcpy(lbph->path, ip); } -/*)Function VOID addlib() +/*)Function VOID addlib() * - * The function addlib() tests for the existance of a - * library path structure to determine the method of - * adding this library file to the library search structure. + * The function addlib() tests for the existance of a + * library path structure to determine the method of + * adding this library file to the library search structure. * - * This function calls the function addfile() to actually - * add the library file to the search list. + * This function calls the function addfile() to actually + * add the library file to the search list. * - * local variables: - * lbpath *lbph pointer to path structure + * local variables: + * lbpath *lbph pointer to path structure * - * global variables: - * lbpath *lbphead The pointer to the first - * path structure + * global variables: + * lbpath *lbphead The pointer to the first + * path structure * ip a pointer to the library name * - * functions called: - * VOID addfile() lklibr.c - * char getnb() lklex.c - * VOID unget() lklex.c + * functions called: + * VOID addfile() lklibr.c + * char getnb() lklex.c + * VOID unget() lklex.c * - * side effects: - * The function addfile() may add the file to - * the library search list. + * side effects: + * The function addfile() may add the file to + * the library search list. */ VOID addlib() { - struct lbpath *lbph; + struct lbpath *lbph; int foundcount=0; - unget(getnb()); + unget(getnb()); - if (lbphead == NULL) + if (lbphead == NULL) { - foundcount=addfile(NULL, ip); - } + foundcount=addfile(NULL, ip); + } else { - for (lbph=lbphead; lbph; lbph=lbph->next) + for (lbph=lbphead; lbph; lbph=lbph->next) { - foundcount+=addfile(lbph->path, ip); - } + foundcount+=addfile(lbph->path, ip); + } } if(foundcount == 0) { - fprintf(stderr, "\n?ASlink-Warning-Couldn't find library '%s'", ip); + fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip); } } -/*)Function int addfile(path,libfil) +/*)Function int addfile(path,libfil) * - * char *path library path specification - * char *libfil library file specification + * char *path library path specification + * char *libfil library file specification * - * The function addfile() searches for the library file - * by concatenating the path and libfil specifications. - * if the library is found, an lbname structure is created - * and linked to any previously defined structures. This - * linked list is used by the function fndsym() to attempt - * to find any undefined symbols. + * The function addfile() searches for the library file + * by concatenating the path and libfil specifications. + * if the library is found, an lbname structure is created + * and linked to any previously defined structures. This + * linked list is used by the function fndsym() to attempt + * to find any undefined symbols. * - * The function does not give report an error on invalid - * path / file specifications or if the file is not found. + * The function does not give report an error on invalid + * path / file specifications or if the file is not found. * - * local variables: - * lbname *lbnh pointer to new name structure - * lbname *lbn temporary pointer + * local variables: + * lbname *lbnh pointer to new name structure + * lbname *lbn temporary pointer * - * global variables: - * lbname *lbnhead The pointer to the first - * path structure + * global variables: + * lbname *lbnhead The pointer to the first + * path structure * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * An lbname structure may be created. + * side effects: + * An lbname structure may be created. * * return: * 1: the library was found @@ -232,38 +231,37 @@ addlib() int addfile(char * path, char * libfil) { - FILE *fp; - char *str; - struct lbname *lbnh, *lbn; + FILE *fp; + char *str; + struct lbname *lbnh, *lbn; int libfilinc=0; - if (path != NULL) + if (path != NULL) { - str = (char *) new (strlen(path) + strlen(libfil) + 6); - strcpy(str, path); - - if (str[strlen(str)-1] != LKDIRSEP) + str = (char *) new (strlen(path) + strlen(libfil) + 6); + strcpy(str, path); + if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\')) { - strcat(str, LKDIRSEPSTR); - } - } + strcat(str, LKDIRSEPSTR); + } + } else { - str = (char *) new (strlen(libfil) + 5); - } + str = (char *) new (strlen(libfil) + 5); + } - if (libfil[0] == LKDIRSEP) + if ((libfil[0] == '/') || (libfil[0] == '\\')) { libfil++; libfilinc=1; } - + strcat(str, libfil); - if(strchr(libfil, FSEPX) == NULL) + if(strchr(libfil, FSEPX) == NULL) { - sprintf(&str[strlen(str)], "%clib", FSEPX); - } + sprintf(&str[strlen(str)], "%clib", FSEPX); + } fp=fopen(str, "r"); if(fp == NULL) @@ -271,7 +269,7 @@ int addfile(char * path, char * libfil) /*Ok, that didn't work. Try with the 'libfil' name only*/ if(libfilinc) libfil--; fp=fopen(libfil, "r"); - if(fp != NULL) + if(fp != NULL) { /*Bingo! 'libfil' is the absolute path of the library*/ strcpy(str, libfil); @@ -281,16 +279,16 @@ int addfile(char * path, char * libfil) if(path==NULL) { - /*'path' can not be null since it is needed to find the '.o' files associated with + /*'path' can not be null since it is needed to find the .rel/.o files associated with the library. So, get 'path' from 'str' and then chop it off and recreate 'libfil'. That way putting 'path' and 'libfil' together will result into the original filepath as contained in 'str'.*/ int j; - path = (char *) new (strlen(str)); + path = (char *) new (strlen(str) + 1); strcpy(path, str); for(j=strlen(path)-1; j>=0; j--) { - if((path[j]=='\\')||(path[j]=='/')) + if((path[j] == '/') || (path[j] == '\\')) { strcpy(libfil, &path[j+1]); path[j+1]=0; @@ -300,260 +298,259 @@ int addfile(char * path, char * libfil) if(j<=0) path[0]=0; } - if (fp != NULL) + if (fp != NULL) { - fclose(fp); - lbnh = (struct lbname *) new (sizeof(struct lbname)); - if (lbnhead == NULL) + fclose(fp); + lbnh = (struct lbname *) new (sizeof(struct lbname)); + if (lbnhead == NULL) { - lbnhead = lbnh; - } + lbnhead = lbnh; + } else { - lbn = lbnhead; - while (lbn->next) - lbn = lbn->next; - lbn->next = lbnh; - } - - lbnh->path = path; - lbnh->libfil = (char *) new (strlen(libfil) + 1); - strcpy(lbnh->libfil, libfil); - lbnh->libspc = str; + lbn = lbnhead; + while (lbn->next) + lbn = lbn->next; + lbn->next = lbnh; + } + + lbnh->path = path; + lbnh->libfil = (char *) new (strlen(libfil) + 1); + strcpy(lbnh->libfil, libfil); + lbnh->libspc = str; return 1; - } + } else { - free(str); + free(str); return 0; - } + } } -/*)Function VOID search() +/*)Function VOID search() * - * The function search() looks through all the symbol tables - * at the end of pass 1. If any undefined symbols are found - * then the function fndsym() is called. Function fndsym() - * searches any specified library files to automagically - * import the object modules containing the needed symbol. + * The function search() looks through all the symbol tables + * at the end of pass 1. If any undefined symbols are found + * then the function fndsym() is called. Function fndsym() + * searches any specified library files to automagically + * import the object modules containing the needed symbol. * - * After a symbol is found and imported by the function - * fndsym() the symbol tables are again searched. The - * symbol tables are search until no more symbols can be - * resolved within the library files. This ensures that - * back references from one library module to another are - * also resolved. + * After a symbol is found and imported by the function + * fndsym() the symbol tables are again searched. The + * symbol tables are search until no more symbols can be + * resolved within the library files. This ensures that + * back references from one library module to another are + * also resolved. * - * local variables: - * int i temporary counter - * sym *sp pointer to a symbol structure - * int symfnd found a symbol flag + * local variables: + * int i temporary counter + * sym *sp pointer to a symbol structure + * int symfnd found a symbol flag * - * global variables: - * sym *symhash[] array of pointers to symbol tables + * global variables: + * sym *symhash[] array of pointers to symbol tables * - * functions called: - * int fndsym() lklibr.c + * functions called: + * int fndsym() lklibr.c * - * side effects: - * If a symbol is found then the library object module - * containing the symbol will be imported and linked. + * side effects: + * If a symbol is found then the library object module + * containing the symbol will be imported and linked. */ VOID search() { - register struct sym *sp; - register int i, symfnd; - - /* - * Look for undefined symbols. Keep - * searching until no more symbols are resolved. - */ - symfnd = 1; - while (symfnd) { - symfnd = 0; - /* - * Look through all the symbols - */ - for (i=0; is_type & S_DEF) == 0) { - if (fndsym(sp->s_id)) { - symfnd++; - } - } - sp = sp->s_sp; - } - } - } + register struct sym *sp; + register int i, symfnd; + + /* + * Look for undefined symbols. Keep + * searching until no more symbols are resolved. + */ + symfnd = 1; + while (symfnd) { + symfnd = 0; + /* + * Look through all the symbols + */ + for (i=0; is_type & S_DEF) == 0) { + if (fndsym(sp->s_id)) { + symfnd++; + } + } + sp = sp->s_sp; + } + } + } } /*Load a .rel file embedded in a sdcclib file*/ void LoadRel(char * libfname, FILE * libfp, char * ModName) { - char str[NINPUT+2]; - int state=0; - - while (fgets(str, NINPUT, libfp) != NULL) - { - str[NINPUT+1] = '\0'; - chop_crlf(str); - switch(state) - { - case 0: - if(EQ(str, "")) - { - fgets(str, NINPUT, libfp); - str[NINPUT+1] = '\0'; - chop_crlf(str); - if(EQ(str, ModName)) state=1; - else - { - fprintf(stderr, "?Aslink-Error-Bad offset in library file %s(%s)\n", + char str[NINPUT+2]; + int state=0; + + while (fgets(str, NINPUT, libfp) != NULL) + { + str[NINPUT+1] = '\0'; + chop_crlf(str); + switch(state) + { + case 0: + if(EQ(str, "")) + { + fgets(str, NINPUT, libfp); + str[NINPUT+1] = '\0'; + chop_crlf(str); + if(EQ(str, ModName)) state=1; + else + { + fprintf(stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", libfname, ModName); - lkexit(1); - } - } - break; - case 1: - if(EQ(str, "")) state=2; - break; - case 2: - if(EQ(str, "")) return; - ip = str; - link(); - break; - } - } + lkexit(1); + } + } + break; + case 1: + if(EQ(str, "")) state=2; + break; + case 2: + if(EQ(str, "")) return; + ip = str; + link_main(); + break; + } + } } -/*)Function VOID fndsym(name) - * - * char *name symbol name to find - * - * 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. - * - * 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 structure lbfile is created for the first library - * object file which contains the definition for the - * specified undefined symbol. - * - * If the library file [.LIB] contains file specifications for - * non existant files, no errors are returned. - * - * local variables: - * char buf[] [.REL] file input line - * char c [.REL] file input character - * FILE *fp file handle for object file - * lbfile *lbf temporary pointer - * lbfile *lbfh pointer to lbfile structure - * FILE *libfp file handle for library file - * lbname *lbnh pointer to lbname structure - * char *path file specification path - * char relfil[] [.REL] file specification - * char *str combined path and file specification - * char symname[] [.REL] file symbol string - * - * global variables: - * lbname *lbnhead The pointer to the first - * name structure - * lbfile *lbfhead The pointer to the first - * file structure - * - * functions called: - * int fclose() c_library - * int fgets() c_library - * FILE *fopen() c_library - * VOID free() c_library - * char getnb() lklex.c - * VOID lkexit() lkmain.c - * VOID loadfile() lklibr.c - * VOID * new() lksym.c - * char * sprintf() c_library - * int sscanf() c_library - * char * strcat() c_library - * char * strchr() c_library - * char * strcpy() c_library - * int strlen() c_library - * int strncmp() c_library - * VOID unget() lklex.c - * - * side effects: - * If the symbol is found then a new lbfile structure - * is created and added to the linked list of lbfile - * structures. The file containing the found symbol - * is linked. +/*)Function VOID fndsym(name) + * + * char *name symbol name to find + * + * 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. + * + * 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 structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. + * + * If the library file [.LIB] contains file specifications for + * non existant files, no errors are returned. + * + * local variables: + * char buf[] [.REL] file input line + * char c [.REL] file input character + * FILE *fp file handle for object file + * lbfile *lbf temporary pointer + * lbfile *lbfh pointer to lbfile structure + * FILE *libfp file handle for library file + * lbname *lbnh pointer to lbname structure + * char *path file specification path + * char relfil[] [.REL] file specification + * char *str combined path and file specification + * char symname[] [.REL] file symbol string + * + * global variables: + * lbname *lbnhead The pointer to the first + * name structure + * lbfile *lbfhead The pointer to the first + * file structure + * + * functions called: + * int fclose() c_library + * int fgets() c_library + * FILE *fopen() c_library + * VOID free() c_library + * char getnb() lklex.c + * VOID lkexit() lkmain.c + * VOID loadfile() lklibr.c + * VOID * new() lksym.c + * char * sprintf() c_library + * int sscanf() c_library + * char * strcat() c_library + * char * strchr() c_library + * char * strcpy() c_library + * int strlen() c_library + * int strncmp() c_library + * VOID unget() lklex.c + * + * side effects: + * If the symbol is found then a new lbfile structure + * is created and added to the linked list of lbfile + * structures. The file containing the found symbol + * is linked. */ #ifdef INDEXLIB int fndsym( char *name ) { - struct lbfile *lbfh, *lbf; - pmlibraryfile ThisLibr; - pmlibrarysymbol ThisSym = NULL; + struct lbfile *lbfh, *lbf; + pmlibraryfile ThisLibr; + pmlibrarysymbol ThisSym = NULL; pmlibraryfile FirstFound; int numfound=0; - /* Build the index if this is the first call to fndsym */ - if (libr==NULL) buildlibraryindex(); - - /* Iterate through all library object files */ - ThisLibr = libr; + /* Build the index if this is the first call to fndsym */ + if (libr==NULL) buildlibraryindex(); + + /* Iterate through all library object files */ + ThisLibr = libr; FirstFound = libr; /*So gcc stops whining*/ - while (ThisLibr) + while (ThisLibr) { - /* Iterate through all symbols in an object file */ - ThisSym = ThisLibr->symbols; + /* Iterate through all symbols in an object file */ + ThisSym = ThisLibr->symbols; - while (ThisSym) + while (ThisSym) { - //printf("ThisSym->name=%s\n", ThisSym->name); - if (!strcmp(ThisSym->name, name)) + if (!strcmp(ThisSym->name, name)) { - if ((!ThisLibr->loaded) && (numfound==0)) + if ((!ThisLibr->loaded) && (numfound==0)) { - /* Object file is not loaded - add it to the list */ - lbfh = (struct lbfile *) new (sizeof(struct lbfile)); - if (lbfhead == NULL) + /* Object file is not loaded - add it to the list */ + lbfh = (struct lbfile *) new (sizeof(struct lbfile)); + if (lbfhead == NULL) { - lbfhead = lbfh; - } + lbfhead = lbfh; + } else { - lbf = lbfhead; - while (lbf->next) - lbf = lbf->next; - lbf->next = lbfh; - } - lbfh->libspc = ThisLibr->libspc; - lbfh->filspc = ThisLibr->filename; - lbfh->relfil = (char *) new (strlen(ThisLibr->relfil) + 1); - strcpy(lbfh->relfil,ThisLibr->relfil); + lbf = lbfhead; + while (lbf->next) + lbf = lbf->next; + lbf->next = lbfh; + } + lbfh->libspc = ThisLibr->libspc; + lbfh->filspc = ThisLibr->filename; + lbfh->relfil = (char *) new (strlen(ThisLibr->relfil) + 1); + strcpy(lbfh->relfil, ThisLibr->relfil); lbfh->offset = ThisLibr->offset; if(lbfh->offset>0) { /*For an embedded object file in a library*/ @@ -562,10 +559,10 @@ int fndsym( char *name ) } else { /*For a stand alone object file*/ - loadfile(lbfh->filspc); + loadfile(lbfh->filspc); } - ThisLibr->loaded=1; - } + ThisLibr->loaded=1; + } if(numfound==0) { @@ -601,24 +598,24 @@ int fndsym( char *name ) numfound++; } } - } - ThisSym=ThisSym->next; /* Next sym in library */ - } - ThisLibr=ThisLibr->next; /* Next library in list */ - } - return numfound; + } + ThisSym=ThisSym->next; /* Next sym in library */ + } + ThisLibr=ThisLibr->next; /* Next library in list */ + } + return numfound; } pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * DirLib, pmlibraryfile This) { - char ModName[NCPS]=""; - char FLine[MAXLINE+1]; + char ModName[NCPS]=""; + char FLine[MAXLINE+1]; char buff[PATH_MAX]; - int state=0; - long IndexOffset=0, FileOffset; + int state=0; + long IndexOffset=0, FileOffset; pmlibrarysymbol ThisSym = NULL; - while(!feof(libfp)) + while(!feof(libfp)) { FLine[0]=0; fgets(FLine, MAXLINE, libfp); @@ -629,24 +626,24 @@ pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * Dir case 0: if(EQ(FLine, "")) { - /*The next line has the size of the index*/ + /*The next line has the size of the index*/ FLine[0]=0; fgets(FLine, MAXLINE, libfp); chop_crlf(FLine); - IndexOffset=atol(FLine); - state=1; + IndexOffset=atol(FLine); + state=1; } break; case 1: if(EQ(FLine, "")) - { - /*The next line has the name of the module and the offset - of the corresponding embedded file in the library*/ + { + /*The next line has the name of the module and the offset + of the corresponding embedded file in the library*/ FLine[0]=0; fgets(FLine, MAXLINE, libfp); chop_crlf(FLine); - sscanf(FLine, "%s %ld", ModName, &FileOffset); - state=2; + sscanf(FLine, "%s %ld", ModName, &FileOffset); + state=2; /*Create a new libraryfile object for this module*/ if(libr==NULL) @@ -655,93 +652,94 @@ pmlibraryfile buildlibraryindex_SdccLib(char * PathLib, FILE * libfp, char * Dir } else { - This->next=(pmlibraryfile)new( sizeof( mlibraryfile )); - This=This->next; + This->next=(pmlibraryfile)new( sizeof( mlibraryfile )); + This=This->next; } - This->next = NULL; - This->loaded=-1; + This->next = NULL; + This->loaded=-1; This->offset=FileOffset+IndexOffset; - This->libspc=PathLib; - + This->libspc=PathLib; + This->relfil=(char *)new(strlen(ModName)+1); - strcpy(This->relfil, ModName); + strcpy(This->relfil, ModName); sprintf(buff, "%s%s%c%s", DirLib, ModName, FSEPX, LKOBJEXT); This->filename=(char *)new(strlen(buff)+1); strcpy(This->filename, buff); This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/ - } + } else if(EQ(FLine, "")) - { - return This; /*Finish, get out of here*/ - } + { + return This; /*Finish, get out of here*/ + } break; case 2: if(EQ(FLine, "")) - { - This->loaded=0; - /*Create the index for the next module*/ + { + This->loaded=0; + /*Create the index for the next module*/ state=1; - } + } else - { - /*Add the symbols*/ + { + /*Add the symbols*/ if(ThisSym==NULL) /*First symbol of the current module*/ { - ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); } else { - ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol)); - ThisSym=ThisSym->next; + ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + ThisSym=ThisSym->next; } - ThisSym->next=NULL; + ThisSym->next=NULL; ThisSym->name=(char *)new(strlen(FLine)+1); - strcpy(ThisSym->name, FLine); + strcpy(ThisSym->name, FLine); } break; - - default: - return This; /*State machine should never reach this point, but just in case...*/ - break; + + default: + return This; /*State machine should never reach this point, but just in case...*/ + break; } } - return This; /*State machine should never reach this point, but just in case...*/ + return This; /*State machine should never reach this point, but just in case...*/ } /* buildlibraryindex - build an in-memory cache of the symbols contained in - * the libraries + * the libraries */ int buildlibraryindex(void) { - FILE *libfp, *fp; - struct lbname *lbnh; - char relfil[NINPUT+2], str[PATH_MAX], *path; - char buf[NINPUT+2], c; - char symname[NINPUT+2]; - pmlibraryfile This=NULL; - pmlibrarysymbol ThisSym; - - /* Iterate through all library files */ + FILE *libfp, *fp; + struct lbname *lbnh; + char relfil[NINPUT+2], str[PATH_MAX], *path; + char buf[NINPUT+2], c; + char symname[NINPUT+2]; + pmlibraryfile This=NULL; + pmlibrarysymbol ThisSym; + + /* + * Search through every library in the linked list "lbnhead". + */ for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) { - if ((libfp = fopen(lbnh->libspc, "r")) == NULL) - { - fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n", - lbnh->libspc); - lkexit(1); - } - - path=lbnh->path; + if ((libfp = fopen(lbnh->libspc, "r")) == NULL) + { + fprintf(stderr, "?Aslink-Error-Cannot open library file %s\n", + lbnh->libspc); + lkexit(1); + } + path = lbnh->path; - /* - * Read in a line from the library file. - * This is the relative file specification - * for a .REL file in this library. - */ + /* + * Read in a line from the library file. + * This is the relative file specification + * for a .REL file in this library. + */ while (fgets(relfil, NINPUT, libfp) != NULL) { @@ -750,40 +748,40 @@ int buildlibraryindex(void) if (path != NULL) { strcpy(str, path); -#ifdef OTHERSYSTEM - if (str[strlen(str)-1] != LKDIRSEP) +#ifdef OTHERSYSTEM + if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\')) { - strcat(str, LKDIRSEPSTR); + strcat(str, LKDIRSEPSTR); } #endif - } + } else { strcpy(str, ""); - } + } if(strcmp(relfil, "")==0) - { - /*Get the built in index of a library*/ - This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This); - break; /*get the index for next library*/ - } - + { + /*Get the built in index of this library*/ + This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This); + break; /*get the index for next library*/ + } + /*From here down, build the index for the original library format*/ - if (relfil[0] == LKDIRSEP) + if ((relfil[0] == '/') || (relfil[0] == '\\')) { - strcat(str, relfil+1); - } + strcat(str, relfil+1); + } else { - strcat(str, relfil); - } - + strcat(str, relfil); + } + if(strchr(relfil, FSEPX) == NULL) { - sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT); - } + sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT); + } if ((fp = fopen(str, "r")) != NULL) { @@ -794,86 +792,92 @@ int buildlibraryindex(void) } else { - This->next=(pmlibraryfile)new( sizeof( mlibraryfile )); - This=This->next; + This->next=(pmlibraryfile)new( sizeof( mlibraryfile )); + This=This->next; } - - This->next = NULL; - This->loaded=-1; + This->next = NULL; + This->loaded=-1; This->offset=-1; /*There should be a rel file*/ - This->libspc = lbnh->libspc; + This->libspc = lbnh->libspc; + This->relfil=(char *)new(strlen(relfil)+1); - strcpy(This->relfil, relfil); + strcpy(This->relfil, relfil); + This->filename=(char *)new(strlen(str)+1); - strcpy(This->filename, str); - - ThisSym = This->symbols = NULL; - - /* - * Read in the object file. Look for lines that - * begin with "S" and end with "D". These are - * symbol table definitions. If we find one, see - * if it is our symbol. Make sure we only read in - * our object file and don't go into the next one. - */ - - while (fgets(buf, NINPUT, fp) != NULL) + strcpy(This->filename, str); + + /*Start a new linked list of symbols for this module:*/ + This->symbols = ThisSym = NULL; + + /* + * Read in the object file. Look for lines that + * begin with "S" and end with "D". These are + * symbol table definitions. If we find one, see + * if it is our symbol. Make sure we only read in + * our object file and don't go into the next one. + */ + + while (fgets(buf, NINPUT, fp) != NULL) { - buf[NINPUT+1] = '\0'; - buf[strlen(buf) - 1] = '\0'; + buf[NINPUT+1] = '\0'; + buf[strlen(buf) - 1] = '\0'; - /* - * Skip everything that's not a symbol record. - */ - if (buf[0] != 'S') continue; + /* + * Skip everything that's not a symbol record. + */ + if (buf[0] != 'S') continue; - /* - * When a 'T line' is found terminate file scan. - * All 'S line's preceed 'T line's in .REL files. - */ - if (buf[0] == 'T') break; + /* + * When a 'T line' is found terminate file scan. + * All 'S line's preceed 'T line's in .REL files. + */ + if (buf[0] == 'T') break; - sscanf(buf, "S %s %c", symname, &c); + sscanf(buf, "S %s %c", symname, &c); /* If it's an actual symbol, record it */ - if (c == 'D') + if (c == 'D') { if(ThisSym==NULL) { - ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); } else { - ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); - ThisSym=ThisSym->next; + ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol)); + ThisSym=ThisSym->next; } - This->loaded=0; - ThisSym->next=NULL; + This->loaded=0; + ThisSym->next=NULL; ThisSym->name=(char *)new(strlen(symname)+1); - strcpy(ThisSym->name, symname); + strcpy(ThisSym->name, symname); } - } /* Closes while - read object file */ - fclose(fp); - } /* Closes if object file opened OK */ - } /* Ends while - processing all in libr */ - fclose(libfp); - } /* Ends good open of libr file */ - return 0; + } /* Closes while - read object file */ + fclose(fp); + } /* Closes if object file opened OK */ + else + { + fprintf(stderr, "?Aslink-Warning-Cannot open library module %s\n", str); + } + } /* Ends while - processing all in libr */ + fclose(libfp); + } /* Ends good open of libr file */ + return 0; } /*Release all memory allocated for the in-memory library index*/ void freelibraryindex (void) { - pmlibraryfile ThisLibr, ThisLibr2Free; - pmlibrarysymbol ThisSym, ThisSym2Free; + pmlibraryfile ThisLibr, ThisLibr2Free; + pmlibrarysymbol ThisSym, ThisSym2Free; - ThisLibr = libr; + ThisLibr = libr; while (ThisLibr) { - ThisSym = ThisLibr->symbols; + ThisSym = ThisLibr->symbols; - while (ThisSym) + while (ThisSym) { free(ThisSym->name); ThisSym2Free=ThisSym; @@ -886,7 +890,7 @@ void freelibraryindex (void) ThisLibr=ThisLibr->next; free(ThisLibr2Free); } - + libr=NULL; } @@ -900,13 +904,13 @@ file.*/ int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName) { - struct lbfile *lbfh, *lbf; - char ModName[NCPS]=""; - char FLine[MAXLINE+1]; - int state=0; - long IndexOffset=0, FileOffset; + struct lbfile *lbfh, *lbf; + char ModName[NCPS]=""; + char FLine[MAXLINE+1]; + int state=0; + long IndexOffset=0, FileOffset; - while(!feof(libfp)) + while(!feof(libfp)) { FLine[0]=0; fgets(FLine, MAXLINE, libfp); @@ -917,259 +921,332 @@ int SdccLib(char * PathLib, FILE * libfp, char * DirLib, char * SymName) case 0: if(EQ(FLine, "")) { - /*The next line has the size of the index*/ + /*The next line has the size of the index*/ FLine[0]=0; fgets(FLine, MAXLINE, libfp); chop_crlf(FLine); - IndexOffset=atol(FLine); - state=1; + IndexOffset=atol(FLine); + state=1; } break; case 1: if(EQ(FLine, "")) - { - /*The next line has the name of the module and the offset - of the corresponding embedded file in the library*/ + { + /*The next line has the name of the module and the offset + of the corresponding embedded file in the library*/ FLine[0]=0; fgets(FLine, MAXLINE, libfp); chop_crlf(FLine); - sscanf(FLine, "%s %ld", ModName, &FileOffset); - state=2; - } + sscanf(FLine, "%s %ld", ModName, &FileOffset); + state=2; + } else if(EQ(FLine, "")) - { - /*Reached the end of the index. The symbol is not in this library.*/ - return 0; - } + { + /*Reached the end of the index. The symbol is not in this library.*/ + return 0; + } break; case 2: if(EQ(FLine, "")) - { - /*The symbol is not in this module, try the next one*/ + { + /*The symbol is not in this module, try the next one*/ state=1; - } + } else - { - /*Check if this is the symbol we are looking for.*/ - if (strncmp(SymName, FLine, NCPS)==0) - { - /*The symbol is in this module.*/ - - /*As in the original library format, it is assumed that the .rel - files reside in the same directory as the lib files.*/ - strcat(DirLib, ModName); - sprintf(&DirLib[strlen(DirLib)], "%c%s", FSEPX, LKOBJEXT); - - /*If this module has been loaded already don't load it again.*/ - lbf = lbfhead; - while (lbf) - { - if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/ - lbf=lbf->next; - } - - /*Add the embedded file to the list of files to be loaded in - the second pass. That is performed latter by the function - library() below.*/ - lbfh = (struct lbfile *) new (sizeof(struct lbfile)); - if (lbfhead == NULL) - { - lbfhead = lbfh; - } - else - { - lbf = lbfhead; - while (lbf->next) - lbf = lbf->next; - lbf->next = lbfh; - } - - lbfh->libspc = PathLib; - lbfh->filspc = DirLib; - lbfh->relfil = (char *) new (strlen(ModName) + 1); - strcpy(lbfh->relfil, ModName); - /*Library embedded file, so lbfh->offset must be >=0*/ - lbfh->offset = IndexOffset+FileOffset; - - /*Jump to where the .rel begins and load it.*/ - fseek(libfp, lbfh->offset, SEEK_SET); - LoadRel(PathLib, libfp, ModName); - - return 1; /*Found the symbol, so success!*/ - } - } + { + /*Check if this is the symbol we are looking for.*/ + if (strncmp(SymName, FLine, NCPS)==0) + { + /*The symbol is in this module.*/ + + /*As in the original library format, it is assumed that the .rel + files reside in the same directory as the lib files.*/ + strcat(DirLib, ModName); + sprintf(&DirLib[strlen(DirLib)], "%c%s", FSEPX, LKOBJEXT); + + /*If this module has been loaded already don't load it again.*/ + lbf = lbfhead; + while (lbf) + { + if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/ + lbf=lbf->next; + } + + /*Add the embedded file to the list of files to be loaded in + the second pass. That is performed latter by the function + library() below.*/ + lbfh = (struct lbfile *) new (sizeof(struct lbfile)); + if (lbfhead == NULL) + { + lbfhead = lbfh; + } + else + { + lbf = lbfhead; + while (lbf->next) + lbf = lbf->next; + lbf->next = lbfh; + } + + lbfh->libspc = PathLib; + lbfh->filspc = DirLib; + lbfh->relfil = (char *) new (strlen(ModName) + 1); + strcpy(lbfh->relfil, ModName); + /*Library embedded file, so lbfh->offset must be >=0*/ + lbfh->offset = IndexOffset+FileOffset; + + /*Jump to where the .rel begins and load it.*/ + fseek(libfp, lbfh->offset, SEEK_SET); + LoadRel(PathLib, libfp, ModName); + + return 1; /*Found the symbol, so success!*/ + } + } + break; + + default: + return 0; /*It should never reach this point, but just in case...*/ break; - - default: - return 0; /*It should never reach this point, but just in case...*/ - break; } } - return 0; /*The symbol is not in this library*/ + return 0; /*The symbol is not in this library*/ } +/*)Function VOID fndsym(name) + * + * char *name symbol name to find + * + * 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. + * + * 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 structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. + * + * If the library file [.LIB] contains file specifications for + * non existant files, no errors are returned. + * + * local variables: + * char buf[] [.REL] file input line + * char c [.REL] file input character + * FILE *fp file handle for object file + * lbfile *lbf temporary pointer + * lbfile *lbfh pointer to lbfile structure + * FILE *libfp file handle for library file + * lbname *lbnh pointer to lbname structure + * char *path file specification path + * char relfil[] [.REL] file specification + * char *str combined path and file specification + * char symname[] [.REL] file symbol string + * + * global variables: + * lbname *lbnhead The pointer to the first + * name structure + * lbfile *lbfhead The pointer to the first + * file structure + * + * functions called: + * int fclose() c_library + * int fgets() c_library + * FILE *fopen() c_library + * VOID free() c_library + * char getnb() lklex.c + * VOID lkexit() lkmain.c + * VOID loadfile() lklibr.c + * VOID * new() lksym.c + * char * sprintf() c_library + * int sscanf() c_library + * char * strcat() c_library + * char * strchr() c_library + * char * strcpy() c_library + * int strlen() c_library + * int strncmp() c_library + * VOID unget() lklex.c + * + * side effects: + * If the symbol is found then a new lbfile structure + * is created and added to the linked list of lbfile + * structures. The file containing the found symbol + * is linked. + */ + int fndsym(name) char *name; { - FILE *libfp, *fp; - struct lbname *lbnh; - struct lbfile *lbfh, *lbf; - char relfil[NINPUT+2]; - char buf[NINPUT+2]; - char symname[NINPUT]; - char *path,*str; - char c; - int result; - - /* - * Search through every library in the linked list "lbnhead". - */ - -/*1*/ for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) { - if ((libfp = fopen(lbnh->libspc, "r")) == NULL) { - fprintf(stderr, "Cannot open library file %s\n", - lbnh->libspc); - lkexit(1); - } - path = lbnh->path; - - /* - * Read in a line from the library file. - * This is the relative file specification - * for a .REL file in this library. - */ - -/*2*/ while (fgets(relfil, NINPUT, libfp) != NULL) { - relfil[NINPUT+1] = '\0'; - chop_crlf(relfil); - if (path != NULL) { - str = (char *) new (strlen(path)+strlen(relfil)+6); - strcpy(str,path); -#ifdef OTHERSYSTEM + FILE *libfp, *fp; + struct lbname *lbnh; + struct lbfile *lbfh, *lbf; + char relfil[NINPUT+2]; + char buf[NINPUT+2]; + char symname[NINPUT]; + char *path,*str; + char c; + int result; + + /* + * Search through every library in the linked list "lbnhead". + */ + + for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) + { + if ((libfp = fopen(lbnh->libspc, "r")) == NULL) + { + fprintf(stderr, "?ASlink-Error-Cannot open library file %s\n", + lbnh->libspc); + lkexit(1); + } + path = lbnh->path; + + /* + * Read in a line from the library file. + * This is the relative file specification + * for a .REL file in this library. + */ + + while (fgets(relfil, NINPUT, libfp) != NULL) + { + relfil[NINPUT+1] = '\0'; + chop_crlf(relfil); + if (path != NULL) + { + str = (char *) new (strlen(path)+strlen(relfil)+6); + strcpy(str,path); +#ifdef OTHERSYSTEM + if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\')) + { #ifdef SDK #ifdef UNIX - if (str[strlen(str)-1] != '/') { - strcat(str,"/"); + strcat(str,"/"); #else /* UNIX */ - if (str[strlen(str)-1] != '\\') { - strcat(str,"\\"); + strcat(str,"\\"); #endif /* UNIX */ #else /* SDK */ - if (str[strlen(str)-1] != '\\') { - strcat(str,"\\"); + strcat(str,"\\"); #endif /* SDK */ - } + } #endif - } else { - str = (char *) new (strlen(relfil) + 5); - } + } + else + { + str = (char *) new (strlen(relfil) + 5); + } /*See if this is a library with embedded files*/ - if(strcmp(relfil, "")==0) - { - result=SdccLib(lbnh->libspc, libfp, str, name); - if(result) return(1); /*Found the symbol*/ - free(str); - /*The symbol is not in the current library, - check the next library in the list*/ - break; - } - - /*From here down is the support for libraries in the original format*/ -#ifdef SDK -#ifdef UNIX - if (relfil[0] == '/') { -#else /* UNIX */ - if (relfil[0] == '\\') { -#endif /* UNIX */ -#else /* SDK */ - if (relfil[0] == '\\') { -#endif /* SDK */ - strcat(str,relfil+1); - } else { - strcat(str,relfil); - } - if(strchr(relfil, FSEPX) == NULL) + if(strcmp(relfil, "")==0) + { + result=SdccLib(lbnh->libspc, libfp, str, name); + if(result) return(1); /*Found the symbol*/ + free(str); + /*The symbol is not in the current library, + check the next library in the list*/ + break; + } + + /*From here down is the support for libraries in the original format*/ + if ((relfil[0] == '/') || (relfil[0] == '\\')) + { + strcat(str, relfil+1); + } + else + { + strcat(str, relfil); + } + + if(strchr(relfil, FSEPX) == NULL) { sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT); - } - -/*3*/ if ((fp = fopen(str, "r")) != NULL) { - - /* - * Read in the object file. Look for lines that - * begin with "S" and end with "D". These are - * symbol table definitions. If we find one, see - * if it is our symbol. Make sure we only read in - * our object file and don't go into the next one. - */ - -/*4*/ while (fgets(buf, NINPUT, fp) != NULL) { - - buf[NINPUT+1] = '\0'; - buf[strlen(buf) - 1] = '\0'; - - /* - * Skip everything that's not a symbol record. - */ - if (buf[0] != 'S') - continue; - - /* - * When a 'T line' is found terminate file scan. - * All 'S line's preceed 'T line's in .REL files. - */ - if (buf[0] == 'T') - break; - - sscanf(buf, "S %s %c", symname, &c); - - /* - * If we find a symbol definition for the - * symbol we're looking for, load in the - * file and add it to lbfhead so it gets - * loaded on pass number 2. - */ -/*5*/ if (strncmp(symname, name, NCPS) == 0 && c == 'D') { - - lbfh = (struct lbfile *) new (sizeof(struct lbfile)); - if (lbfhead == NULL) { - lbfhead = lbfh; - } else { - lbf = lbfhead; - while (lbf->next) - lbf = lbf->next; - lbf->next = lbfh; - } - lbfh->libspc = lbnh->libspc; - lbfh->filspc = str; - lbfh->relfil = (char *) new (strlen(relfil) + 1); - lbfh->offset = -1; /*Stand alone rel file*/ - strcpy(lbfh->relfil,relfil); - fclose(fp); - fclose(libfp); - loadfile(str); - return (1); - -/*5*/ } - -/*4*/ } - fclose(fp); -/*3*/ } - - free(str); -/*2*/ } - fclose(libfp); -/*1*/ } - return(0); + } + + if ((fp = fopen(str, "r")) != NULL) + { + /* + * Read in the object file. Look for lines that + * begin with "S" and end with "D". These are + * symbol table definitions. If we find one, see + * if it is our symbol. Make sure we only read in + * our object file and don't go into the next one. + */ + + while (fgets(buf, NINPUT, fp) != NULL) + { + buf[NINPUT+1] = '\0'; + chop_crlf(buf); + /* + * Skip everything that's not a symbol record. + */ + if (buf[0] != 'S') + continue; + + /* + * When a 'T line' is found terminate file scan. + * All 'S line's preceed 'T line's in .REL files. + */ + if (buf[0] == 'T') + break; + + sscanf(buf, "S %s %c", symname, &c); + + /* + * If we find a symbol definition for the + * symbol we're looking for, load in the + * file and add it to lbfhead so it gets + * loaded on pass number 2. + */ + if (strncmp(symname, name, NCPS) == 0 && c == 'D') + { + lbfh = (struct lbfile *) new (sizeof(struct lbfile)); + if (lbfhead == NULL) + { + lbfhead = lbfh; + } + else + { + lbf = lbfhead; + while (lbf->next) + lbf = lbf->next; + lbf->next = lbfh; + } + + lbfh->libspc = lbnh->libspc; + lbfh->filspc = str; + lbfh->relfil = (char *) new (strlen(relfil) + 1); + lbfh->offset = -1; /*Stand alone rel file*/ + strcpy(lbfh->relfil,relfil); + fclose(fp); + fclose(libfp); + loadfile(str); + return (1); + } + } + fclose(fp); + } + free(str); + } + fclose(libfp); + } + return(0); } + #endif /* INDEXLIB */ void loadfile_SdccLib(char * libspc, char * module, long offset) { - FILE *fp; + FILE *fp; #ifdef __CYGWIN__ char posix_path[PATH_MAX]; @@ -1180,92 +1257,91 @@ void loadfile_SdccLib(char * libspc, char * module, long offset) fp = fopen(libspc,"r"); #endif - if (fp != NULL) - { - fseek(fp, offset, SEEK_SET); - LoadRel(libspc, fp, module); - fclose(fp); - } + if (fp != NULL) + { + fseek(fp, offset, SEEK_SET); + LoadRel(libspc, fp, module); + fclose(fp); + } else { - fprintf(stderr, "?Aslink-Error-Opening library '%s'\n", libspc); - lkexit(1); + fprintf(stderr, "?ASlink-Error-Opening library '%s'\n", libspc); + lkexit(1); } } -/*)Function VOID library() +/*)Function VOID library() * - * The function library() links all the library object files - * contained in the lbfile structures. + * The function library() links all the library object files + * contained in the lbfile structures. * - * local variables: - * lbfile *lbfh pointer to lbfile structure + * local variables: + * lbfile *lbfh pointer to lbfile structure * - * global variables: - * lbfile *lbfhead pointer to first lbfile structure + * global variables: + * lbfile *lbfhead pointer to first lbfile structure * - * functions called: - * VOID loadfile lklibr.c + * functions called: + * VOID loadfile lklibr.c * - * side effects: - * Links all files contained in the lbfile structures. + * side effects: + * Links all files contained in the lbfile structures. */ VOID library() { - struct lbfile *lbfh; - - for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) - { - if(lbfh->offset<0) - { - /*Stand alone rel file (original lib format)*/ - loadfile(lbfh->filspc); - } - else - { - /*rel file embedded in lib (new lib format)*/ - loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset); - } - } + struct lbfile *lbfh; + + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) + { + if(lbfh->offset<0) + { + /*Stand alone rel file (original lib format)*/ + loadfile(lbfh->filspc); + } + else + { + /*rel file embedded in lib (new lib format)*/ + loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset); + } + } #ifdef INDEXLIB freelibraryindex(); #endif } -/*)Function VOID loadfile(filspc) +/*)Function VOID loadfile(filspc) * - * char *filspc library object file specification + * char *filspc library object file specification * - * The function loadfile() links the library object module. + * The function loadfile() links the library object module. * - * local variables: - * FILE *fp file handle - * int i input line length - * char str[] file input line + * local variables: + * FILE *fp file handle + * int i input line length + * char str[] file input line * - * global variables: - * char *ip pointer to linker input string + * global variables: + * char *ip pointer to linker input string * - * functions called: - * int fclose() c_library - * int fgets() c_library - * FILE * fopen() c_library - * VOID link() lkmain.c - * int strlen() c_library + * functions called: + * int fclose() c_library + * int fgets() c_library + * FILE * fopen() c_library + * VOID link_main() lkmain.c + * int strlen() c_library * - * side effects: - * If file exists it is linked. + * side effects: + * If file exists it is linked. */ VOID loadfile(filspc) char *filspc; { - FILE *fp; - char str[NINPUT+2]; - int i; + FILE *fp; + char str[NINPUT+2]; #ifdef __CYGWIN__ char posix_path[PATH_MAX]; @@ -1276,22 +1352,20 @@ char *filspc; fp = fopen(filspc,"r"); #endif - if (fp != NULL) + if (fp != NULL) { - while (fgets(str, NINPUT, fp) != NULL) + while (fgets(str, NINPUT, fp) != NULL) { - str[NINPUT+1] = '\0'; - i = strlen(str) - 1; - if (str[i] == '\n') - str[i] = '\0'; - ip = str; - link(); - } - fclose(fp); - } + str[NINPUT+1] = '\0'; + chop_crlf(str); + ip = str; + link_main(); + } + fclose(fp); + } else { - fprintf(stderr, "?Aslink-Error-Opening library '%s'\n", filspc); - lkexit(1); + fprintf(stderr, "?ASlink-Error-Opening library '%s'\n", filspc); + lkexit(1); } } diff --git a/as/link/z80/lklist.c b/as/link/z80/lklist.c index 827b44c2..30d21091 100644 --- a/as/link/z80/lklist.c +++ b/as/link/z80/lklist.c @@ -14,146 +14,164 @@ #include #include "aslink.h" -/*)Module lklist.c +/*)Module lklist.c * - * The module lklist.c contains the functions which - * output the linker .map file and produce a relocated - * listing .rst file. + * 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 the following functions: + * int dgt() + * VOID lstarea() + * VOID lkulist() + * VOID lkalist() + * VOID lkglist() + * VOID newpag() + * VOID slew() * - * lklist.c contains no local variables. + * lklist.c contains no local variables. */ -/*)Function VOID slew(fp) +/*)Function VOID slew(fp) * - * FILE * fp output file handle + * 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. + * 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 + * local variables: + * int i loop counter * - * global variables: - * int lop current line number on page - * int xflag Map file radix type flag + * 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 + * functions called: + * int fprintf() c_library + * VOID newpag() lklist.c * - * side effects: - * The page line and the page count may be updated. + * side effects: + * The page line and the page count may be updated. */ VOID slew(fp) FILE *fp; { - register int i; + register int i; - if (lop++ >= NLPP) { - newpag(fp); - if (xflag == 0) { - fprintf(fp, "Hexidecimal\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; - } + 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() +/*)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. + * 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 + * local variables: + * none * - * global variables: - * int lop current line number on page - * int page current page number + * global variables: + * int lop current line number on page + * int page current page number * - * functions called: - * int fprintf() c_library + * functions called: + * int fprintf() c_library * - * side effects: - * The page and line counters are updated. + * 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; + fprintf(fp, "\fASxxxx Linker %s, page %u.\n", VERSION, ++page); + lop = 1; } -#if NCPS-8 +#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) +/*)Function VOID lstarea(xp) * - * area * xp pointer to an area structure + * 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. + * 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 + * 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 + * 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 + * 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. + * side effects: + * Map output generated. */ #ifndef MLH_MAP @@ -161,887 +179,832 @@ VOID lstarea(xp) struct area *xp; { -// register struct area *op; - register struct areax *oxp; - register c, i, j; - register char *ptr; - int nmsym; - Addr_T a0, ai, aj; - struct sym *sp; - struct sym **p; + 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, "Hexidecimal\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]; - 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"); } - } + putc('\n', mfp); + if (xflag == 0) { + fprintf(mfp, "Hexadecimal\n\n"); + } else + if (xflag == 1) { + fprintf(mfp, "Octal\n\n"); + } else + if (xflag == 2) { + fprintf(mfp, "Decimal\n\n"); + } + fprintf(mfp, "Area "); + fprintf(mfp, "Addr Size Decimal Bytes (Attributes)\n"); + fprintf(mfp, "-------------------------------- "); + fprintf(mfp, "---- ---- ------- ----- ------------\n"); + /* + * Output Area Header + */ + ptr = &xp->a_id[0]; + fprintf(mfp, "%-32s", ptr ); /* JLH: width matches --- above */ + ai = xp->a_addr; + aj = xp->a_size; + if (xflag == 0) { + fprintf(mfp, " %04X %04X", ai, aj); + } else + if (xflag == 1) { + fprintf(mfp, " %06o %06o", ai, aj); + } else + if (xflag == 2) { + fprintf(mfp, " %05u %05u", ai, aj); + } + fprintf(mfp, " = %6u. bytes ", aj); + if (xp->a_flag & A_ABS) { + fprintf(mfp, "(ABS"); + } else { + fprintf(mfp, "(REL"); + } + if (xp->a_flag & A_OVR) { + fprintf(mfp, ",OVR"); + } else { + fprintf(mfp, ",CON"); + } + if (xp->a_flag & A_PAG) { + fprintf(mfp, ",PAG"); + } + fprintf(mfp, ")"); + if (xp->a_flag & A_PAG) { + ai = (ai & 0xFF); + aj = (aj > 256); + if (ai || aj) { fprintf(mfp, " "); } + if (ai) { fprintf(mfp, " Boundary"); } + if (ai & aj) { fprintf(mfp, " /"); } + if (aj) { fprintf(mfp, " Length"); } + if (ai || aj) { fprintf(mfp, " Error"); } + } - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - if (nmsym == 0) { - putc('\n', mfp); - return; - } + /* + * Find number of symbols in area + */ + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + if (nmsym == 0) { + putc('\n', mfp); + return; + } - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) + == NULL) { + fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); + return; + } + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) { + p[nmsym++] = sp; + } + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } + 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, " "); + /* + * 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]; - while (ptr < &sp->s_id[NCPS]) { - if ((c = *ptr++) != 0) { - putc(c, mfp); - } else { - putc(' ', mfp); - } - } - i++; - } - putc('\n', mfp); - free(p); + 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; + register struct areax *oxp; + register int i, j; + int nmsym; + Addr_T a0, ai = 0, aj = 0; + struct sym *sp; + struct sym **p; - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } + /* + * Find number of symbols in area + */ + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } - /* - * Symbol Table Output - */ - if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { - fprintf(mfp, "AREA %s\n", xp->a_id ); - switch (xflag) { - case 1: - fprintf(mfp, "\tRADIX OCTAL\n" ); - break; - case 2: - fprintf(mfp, "\tRADIX DEC\n" ); - break; - default: - fprintf(mfp, "\tRADIX HEX\n" ); - break; - } - fprintf( mfp, "\tBASE %04X\n" - "\tSIZE %04X\n" - "\tATTRIB " - , xp->a_addr, xp->a_size ); - if (xp->a_flag & A_ABS) { - fprintf(mfp, "ABS"); - } else { - fprintf(mfp, "REL"); - } - if (xp->a_flag & A_OVR) { - fprintf(mfp, " OVR"); - } else { - fprintf(mfp, " CON"); - } - if (xp->a_flag & A_PAG) { - fprintf(mfp, " PAG"); - } - if (xp->a_flag & A_PAG) { - ai = (ai & 0xFF); - aj = (aj > 256); - if (ai || aj) { fprintf(mfp, " "); } - if (ai) { fprintf(mfp, " Boundary"); } - if (ai & aj) { fprintf(mfp, " /"); } - if (aj) { fprintf(mfp, " Length"); } - if (ai || aj) { fprintf(mfp, " Error"); } - } + /* + * Symbol Table Output + */ + if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { + fprintf(mfp, "AREA %s\n", xp->a_id ); + switch (xflag) { + case 1: + fprintf(mfp, "\tRADIX OCTAL\n" ); + break; + case 2: + fprintf(mfp, "\tRADIX DEC\n" ); + break; + default: + fprintf(mfp, "\tRADIX HEX\n" ); + break; + } + fprintf( mfp, "\tBASE %04X\n" + "\tSIZE %04X\n" + "\tATTRIB " + , xp->a_addr, xp->a_size ); + if (xp->a_flag & A_ABS) { + fprintf(mfp, "ABS"); + } else { + fprintf(mfp, "REL"); + } + if (xp->a_flag & A_OVR) { + fprintf(mfp, " OVR"); + } else { + fprintf(mfp, " CON"); + } + if (xp->a_flag & A_PAG) { + fprintf(mfp, " PAG"); + } + if (xp->a_flag & A_PAG) { + ai = (ai & 0xFF); + aj = (aj > 256); + if (ai || aj) { fprintf(mfp, " "); } + if (ai) { fprintf(mfp, " Boundary"); } + if (ai & aj) { fprintf(mfp, " /"); } + if (aj) { fprintf(mfp, " Length"); } + if (ai || aj) { fprintf(mfp, " Error"); } + } - fprintf( mfp,"\n"); - if (nmsym>0) { - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } + fprintf( mfp,"\n"); + if (nmsym>0) { + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) + == NULL) { + fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); + return; + } + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) { + p[nmsym++] = sp; + } + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } + /* + * Bubble Sort of Addresses in Symbol Table Array + */ + j = 1; + while (j) { + j = 0; + sp = p[0]; + a0 = sp->s_addr + sp->s_axp->a_addr; + for (i=1; is_addr + sp->s_axp->a_addr; + if (a0 > ai) { + j = 1; + p[i] = p[i-1]; + p[i-1] = sp; + } + a0 = ai; + } + } - fprintf( mfp, "\tGLOBALS\n"); - i = 0; - while (i < nmsym) { - fprintf(mfp, "\t\t%s\t%04X\n", p[i]->s_id, p[i]->s_addr + p[i]->s_axp->a_addr ); - i++; - } - free(p); - } - } + 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) +/*)Function VOID lstarea(xp) * - * area * xp pointer to an area structure + * 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. + * 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 + * 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 + * 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 + * 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. + * 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; + 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"); } - } + putc('\n', mfp); + slew(mfp); + /* + * Output Area Header + */ + ptr = &xp->a_id[0]; + while (ptr < &xp->a_id[NCPS]) { + if ((c = *ptr++) != 0) { + putc(c, mfp); + } else { + putc(' ', mfp); + } + } + ai = xp->a_addr; + aj = xp->a_size; + if (xflag == 0) { + fprintf(mfp, " %04X %04X", ai, aj); + } else + if (xflag == 1) { + fprintf(mfp, " %06o %06o", ai, aj); + } else + if (xflag == 2) { + fprintf(mfp, " %05u %05u", ai, aj); + } + fprintf(mfp, " = %6u. bytes ", aj); + if (xp->a_flag & A_ABS) { + fprintf(mfp, "(ABS"); + } else { + fprintf(mfp, "(REL"); + } + if (xp->a_flag & A_OVR) { + fprintf(mfp, ",OVR"); + } else { + fprintf(mfp, ",CON"); + } + if (xp->a_flag & A_PAG) { + fprintf(mfp, ",PAG"); + } + fprintf(mfp, ")"); + if (xp->a_flag & A_PAG) { + ai = (ai & 0xFF); + aj = (aj > 256); + if (ai || aj) { fprintf(mfp, " "); } + if (ai) { fprintf(mfp, " Boundary"); } + if (ai & aj) { fprintf(mfp, " /"); } + if (aj) { fprintf(mfp, " Length"); } + if (ai || aj) { fprintf(mfp, " Error"); } + } - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } - if (nmsym == 0) { - putc('\n', mfp); - slew(mfp); - return; - } + /* + * Find number of symbols in area + */ + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + if (nmsym == 0) { + putc('\n', mfp); + slew(mfp); + return; + } - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - slew(mfp); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) + == NULL) { + fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); + slew(mfp); + return; + } + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) { + p[nmsym++] = sp; + } + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } + 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]; - while (ptr < &sp->s_id[NCPS]) { - if ((c = *ptr++) != 0) { - putc(c, mfp); - } else { - putc(' ', mfp); - } - } - if (++i < nmsym) - if (i % 4 != 0) - fprintf(mfp, " | "); - } - putc('\n', mfp); - free(p); - slew(mfp); + /* + * 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; + /* Output the current area symbols to a NO$GMB .sym file */ + register struct areax *oxp; + register int i, j; + int nmsym; + Addr_T a0, ai; + struct sym *sp; + struct sym **p; - /* - * Find number of symbols in area - */ - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) - ++nmsym; - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } + /* + * Find number of symbols in area + */ + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } - /* - * Symbol Table Output - */ - if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { - /* Dont worry about any area information */ - fprintf(mfp, "; Area: %s\n", xp->a_id ); - if (nmsym>0) { - /* - * Allocate space for an array of pointers to symbols - * and load array. - */ - if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) - == NULL) { - fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); - return; - } - nmsym = 0; - oxp = xp->a_axp; - while (oxp) { - for (i=0; is_axp) { - p[nmsym++] = sp; - } - sp = sp->s_sp; - } - } - oxp = oxp->a_axp; - } + /* + * Symbol Table Output + */ + if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) { + /* Dont worry about any area information */ + fprintf(mfp, "; Area: %s\n", xp->a_id ); + if (nmsym>0) { + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) + == NULL) { + fprintf(mfp, "\nInsufficient space to build Map Segment.\n"); + return; + } + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) { + p[nmsym++] = sp; + } + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } - /* - * Bubble Sort of Addresses in Symbol Table Array - */ - j = 1; - while (j) { - j = 0; - sp = p[0]; - a0 = sp->s_addr + sp->s_axp->a_addr; - for (i=1; is_addr + sp->s_axp->a_addr; - if (a0 > ai) { - j = 1; - p[i] = p[i-1]; - p[i-1] = sp; - } - a0 = ai; - } - } - i = 0; - while (i < nmsym) { - /* no$gmb requires the symbol names to be less than 32 chars long. Truncate. */ - char name[32]; - strncpy(name, p[i]->s_id, 31); - name[31] = '\0'; - if ((strncmp("l__", name, 3)!=0)&&(strchr(name,' ')==NULL)) { - a0=p[i]->s_addr + p[i]->s_axp->a_addr; - if (a0>0x7FFFU) { - /* Not inside the ROM, so treat as being in bank zero */ - fprintf(mfp, "00:%04X %s\n", a0, name); - } - else { - fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, name); - } - } - i++; - } - free(p); - } - } + /* + * Bubble Sort of Addresses in Symbol Table Array + */ + j = 1; + while (j) { + j = 0; + sp = p[0]; + a0 = sp->s_addr + sp->s_axp->a_addr; + for (i=1; is_addr + sp->s_axp->a_addr; + if (a0 > ai) { + j = 1; + p[i] = p[i-1]; + p[i-1] = sp; + } + a0 = ai; + } + } + i = 0; + while (i < nmsym) { + /* no$gmb requires the symbol names to be less than 32 chars long. Truncate. */ + char name[32]; + strncpy(name, p[i]->s_id, 31); + name[31] = '\0'; + if ((strncmp("l__", name, 3)!=0)&&(strchr(name,' ')==NULL)) { + a0=p[i]->s_addr + p[i]->s_axp->a_addr; + if (a0>0x7FFFU) { + /* Not inside the ROM, so treat as being in bank zero */ + fprintf(mfp, "00:%04X %s\n", a0, name); + } + else { + fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, name); + } + } + i++; + } + free(p); + } + } } #endif -/*)Function VOID lkulist(i) +/*)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 + * 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. + * 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 + * 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 + * 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 + * 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. + * 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; + Addr_T pc; - /* - * Exit if listing file is not open - */ - if (tfp == NULL) - return; + /* + * 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); - } + /* + * 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 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); - } - } - } + /* + * 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, rb); + /* + * Copy remainder of LST to RST + */ + } else { + if (gline == 0) + fprintf(rfp, "%s", rb); - while (fgets(rb, sizeof(rb), tfp) != 0) { - fprintf(rfp, rb); - } - fclose(tfp); - tfp = NULL; - fclose(rfp); - rfp = NULL; - } + while (fgets(rb, sizeof(rb), tfp) != 0) { + fprintf(rfp, "%s", rb); + } + fclose(tfp); + tfp = NULL; + fclose(rfp); + rfp = NULL; + } } -/*)Function VOID lkalist(pc) +/*)Function VOID lkalist(pc) * - * int pc current program counter value + * int pc current program counter value * - * The function lkalist() performs the following functions: + * 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. + * (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. + * (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 + * 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 + * 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 + * 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. + * 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; + char str[8]; + int i; - /* - * Exit if listing file is not open - */ -loop: if (tfp == NULL) - return; + /* + * Exit if listing file is not open + */ +loop: if (tfp == NULL) + return; - /* - * Copy current LST to RST - */ - if (gline == 0) { - fprintf(rfp, rb); - gline = 1; - } + /* + * Copy current LST to RST + */ + if (gline == 0) { + fprintf(rfp, "%s", rb); + gline = 1; + } - /* - * Clear text line buffer - */ - for (i=0,rp=rb; i #include #include -//#include #include "aslink.h" -#include #ifndef SDK_VERSION_STRING -#define SDK_VERSION_STRING "3.0.0" +#define SDK_VERSION_STRING "3.0.0" #endif #ifndef TARGET_STRING -#define TARGET_STRING "gbz80" +#define TARGET_STRING "gbz80" #endif #ifdef WIN32T @@ -30,133 +30,133 @@ void Timer(int action, char * message) { - static double start, end, total=0.0; + static double start, end, total=0.0; static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; if(action==0) start=clock()*secs_per_tick; else if(action==1) { - end=clock() * secs_per_tick; - printf("%s \t%f seconds.\n", message, (end-start)); - total+=end-start; + end=clock() * secs_per_tick; + printf("%s \t%f seconds.\n", message, (end-start)); + total+=end-start; } else { - printf("Total time: \t%f seconds.\n", total); - total=0.0; + printf("Total time: \t%f seconds.\n", total); + total=0.0; } } #endif -/*)Module lkmain.c - * - * The module lkmain.c contains the functions which - * (1) input the linker options, parameters, and specifications - * (2) perform a two pass link - * (3) produce the appropriate linked data output and/or - * link map file and/or relocated listing files. - * - * lkmain.c contains the following functions: - * FILE * afile(fn,ft,wf) - * VOID bassav() - * VOID gblsav() - * VOID link() - * VOID lkexit() - * VOID main(argc,argv) - * VOID map() - * int parse() - * VOID setbas() - * VOID setgbl() - * VOID usage() - * - * lkmain.c contains the following local variables: - * char * usetext[] array of pointers to the - * command option tect lines +/*)Module lkmain.c + * + * The module lkmain.c contains the functions which + * (1) input the linker options, parameters, and specifications + * (2) perform a two pass link + * (3) produce the appropriate linked data output and/or + * link map file and/or relocated listing files. + * + * lkmain.c contains the following functions: + * FILE * afile(fn,ft,wf) + * VOID bassav() + * VOID gblsav() + * VOID link_main() + * VOID lkexit() + * VOID main(argc,argv) + * VOID map() + * int parse() + * VOID setbas() + * VOID setgbl() + * VOID usage() + * + * lkmain.c contains the following local variables: + * char * usetext[] array of pointers to the + * command option tect lines * */ -/*)Function VOID main(argc,argv) - * - * int argc number of command line arguments + 1 - * char * argv[] array of pointers to the command line - * arguments - * - * The function main() evaluates the command line arguments to - * determine if the linker parameters are to input through 'stdin' - * or read from a command file. The functiond lk_getline() and parse() - * are to input and evaluate the linker parameters. The linking process - * proceeds by making the first pass through each .rel file in the order - * presented to the linker. At the end of the first pass the setbase(), - * lnkarea(), setgbl(), and symdef() functions are called to evaluate - * the base address terms, link all areas, define global variables, - * and look for undefined symbols. Following these routines a linker - * map file may be produced and the linker output files may be opened. - * The second pass through the .rel files will output the linked data - * in one of the four supported formats. - * - * local variables: - * char * p pointer to an argument string - * int c character from argument string - * int i loop counter - * - * global variables: - * text line in ib[] - * lfile *cfp The pointer *cfp points to the - * current lfile structure - * char ctype[] array of character types, one per - * ASCII character - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * head *hp Pointer to the current - * head structure - * char ib[NINPUT] .rel file text line - * char *ip pointer into the .rel file - * lfile *linkp pointer to first lfile structure - * containing an input .rel file - * specification - * int lkerr error flag - * int mflag Map output flag - * int oflag Output file type flag - * FILE *ofp Output file handle - * for word formats - * FILE *ofph Output file handle - * for high byte format - * FILE *ofpl Output file handle - * for low byte format - * int pass linker pass number - * int pflag print linker command file flag - * int radix current number conversion radix - * FILE *sfp The file handle sfp points to the - * currently open file - * lfile *startp asmlnk startup file structure - * FILE * stdin c_library - * FILE * stdout c_library - * - * functions called: - * FILE * afile() lkmain.c - * int fclose() c_library - * int fprintf() c_library - * int lk_getline() lklex.c - * VOID library() lklibr.c - * VOID link() lkmain.c - * VOID lkexit() lkmain.c - * VOID lnkarea() lkarea.c - * VOID map() lkmain.c - * VOID new() lksym.c - * int parse() lkmain.c - * VOID reloc() lkreloc.c - * VOID search() lklibr.c - * VOID setbas() lkmain.c - * VOID setgbl() lkmain.c - * VOID symdef() lksym.c - * VOID usage() lkmain.c - * - * side effects: - * Completion of main() completes the linking process - * and may produce a map file (.map) and/or a linked - * data files (.ihx or .s19) and/or one or more - * relocated listing files (.rst). +/*)Function VOID main(argc,argv) + * + * int argc number of command line arguments + 1 + * char * argv[] array of pointers to the command line + * arguments + * + * The function main() evaluates the command line arguments to + * determine if the linker parameters are to input through 'stdin' + * or read from a command file. The functions lk_getline() and parse() + * are to input and evaluate the linker parameters. The linking process + * proceeds by making the first pass through each .rel file in the order + * presented to the linker. At the end of the first pass the setbase(), + * lnkarea(), setgbl(), and symdef() functions are called to evaluate + * the base address terms, link all areas, define global variables, + * and look for undefined symbols. Following these routines a linker + * map file may be produced and the linker output files may be opened. + * The second pass through the .rel files will output the linked data + * in one of the four supported formats. + * + * local variables: + * char * p pointer to an argument string + * int c character from argument string + * int i loop counter + * + * global variables: + * text line in ib[] + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * char ctype[] array of character types, one per + * ASCII character + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * head *hp Pointer to the current + * head structure + * char ib[NINPUT] .rel file text line + * char *ip pointer into the .rel file + * lfile *linkp pointer to first lfile structure + * containing an input .rel file + * specification + * int lkerr error flag + * int mflag Map output flag + * int oflag Output file type flag + * FILE *ofp Output file handle + * for word formats + * FILE *ofph Output file handle + * for high byte format + * FILE *ofpl Output file handle + * for low byte format + * int pass linker pass number + * int pflag print linker command file flag + * int radix current number conversion radix + * FILE *sfp The file handle sfp points to the + * currently open file + * lfile *startp asmlnk startup file structure + * FILE * stdin c_library + * FILE * stdout c_library + * + * functions called: + * FILE * afile() lkmain.c + * int fclose() c_library + * int fprintf() c_library + * int lk_getline() lklex.c + * VOID library() lklibr.c + * VOID link_main() lkmain.c + * VOID lkexit() lkmain.c + * VOID lnkarea() lkarea.c + * VOID map() lkmain.c + * VOID new() lksym.c + * int parse() lkmain.c + * VOID reloc() lkreloc.c + * VOID search() lklibr.c + * VOID setbas() lkmain.c + * VOID setgbl() lkmain.c + * VOID symdef() lksym.c + * VOID usage() lkmain.c + * + * side effects: + * Completion of main() completes the linking process + * and may produce a map file (.map) and/or a linked + * data files (.ihx or .s19) and/or one or more + * relocated listing files (.rst). */ #ifdef SDK @@ -182,650 +182,653 @@ char *default_globlp[] = { #endif /* GAMEBOY */ int -main(argc, argv) -char *argv[]; +main(int argc, char *argv[]) { - register char *p; - register int c, i; + register char *p; + register int c, i; #ifdef WIN32T Timer(0, ""); #endif #ifdef GAMEBOY - nb_rom_banks = 2; - nb_ram_banks = 0; - mbc_type = 0; - symflag=0; - - for(i = 0; default_basep[i] != NULL; i++) { - if(basep == NULL) { - basep = (struct base *)new(sizeof(struct base)); - bsp = basep; - } else { - bsp->b_base = (struct base *)new(sizeof(struct base)); - bsp = bsp->b_base; - } - bsp->b_strp = default_basep[i]; - } - for(i = 0; default_globlp[i] != NULL; i++) { - if(globlp == NULL) { - globlp = (struct globl *)new(sizeof(struct globl)); - gsp = globlp; - } else { - gsp->g_globl = (struct globl *)new(sizeof(struct globl)); - gsp = gsp->g_globl; - } - gsp->g_strp = default_globlp[i]; - } + nb_rom_banks = 2; + nb_ram_banks = 0; + mbc_type = 0; + symflag=0; + + for(i = 0; default_basep[i] != NULL; i++) { + if(basep == NULL) { + basep = (struct base *)new(sizeof(struct base)); + bsp = basep; + } else { + bsp->b_base = (struct base *)new(sizeof(struct base)); + bsp = bsp->b_base; + } + bsp->b_strp = default_basep[i]; + } + for(i = 0; default_globlp[i] != NULL; i++) { + if(globlp == NULL) { + globlp = (struct globl *)new(sizeof(struct globl)); + gsp = globlp; + } else { + gsp->g_globl = (struct globl *)new(sizeof(struct globl)); + gsp = gsp->g_globl; + } + gsp->g_strp = default_globlp[i]; + } #endif /* GAMEBOY */ #ifndef SDK - fprintf(stdout, "\n"); + fprintf(stdout, "\n"); #endif /* SDK */ - startp = (struct lfile *) new (sizeof (struct lfile)); - - pflag = 1; - for (i=1; if_type = F_STD; - break; - - case 'f': - case 'F': - startp->f_type = F_LNK; - break; - - case 'n': - case 'N': - pflag = 0; - break; - - case 'p': - case 'P': - pflag = 1; - break; - - default: - usage(); - } - } - -#ifdef SDK - if(c == '-') { - startp->f_type = F_CMD; - startp->f_idp = (char *)&argv[i+1]; - break; - } + startp = (struct lfile *) new (sizeof (struct lfile)); + + pflag = 1; + for (i=1; if_type = F_STD; + break; + + case 'f': + case 'F': + startp->f_type = F_LNK; + break; + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + default: + usage(); + } + } + +#ifdef SDK + if(c == '-') { + startp->f_type = F_CMD; + startp->f_idp = (char *)&argv[i+1]; + break; + } #endif /* SDK */ - } else { - if (startp->f_type == F_LNK) { - startp->f_idp = p; - } - } - } - if (startp->f_type == F_INV) - usage(); - if (startp->f_type == F_LNK && startp->f_idp == NULL) - usage(); + } else { + if (startp->f_type == F_LNK) { + startp->f_idp = p; + } + } + } + if (startp->f_type == F_INV) + usage(); + if (startp->f_type == F_LNK && startp->f_idp == NULL) + usage(); #ifdef SDK - if (startp->f_type == F_CMD && startp->f_idp == NULL) - usage(); + if (startp->f_type == F_CMD && startp->f_idp == NULL) + usage(); #endif /* SDK */ - cfp = NULL; - sfp = NULL; - filep = startp; - while (1) { - ip = ib; - if (lk_getline() == 0) - break; - if (pflag && sfp != stdin) - fprintf(stdout, "%s\n", ip); - if (*ip == '\0' || parse()) - break; - } - if (sfp) - fclose(sfp); - if (linkp == NULL) - usage(); + cfp = NULL; + sfp = NULL; + filep = startp; + while (1) { + ip = ib; + if (lk_getline() == 0) + break; + if (pflag && sfp != stdin) + fprintf(stdout, "%s\n", ip); + if (*ip == '\0' || parse()) + break; + } + + if (sfp) { + fclose(sfp); + sfp = NULL; + } + + if (linkp == NULL) + usage(); #ifdef SDK - if (linkp->f_flp == NULL) - usage(); + if (linkp->f_flp == NULL) + usage(); #endif /* SDK */ #ifdef GAMEBOY - for(i = 1; i < nb_rom_banks; i++) { - bsp->b_base = (struct base *)new(sizeof(struct base)); - bsp = bsp->b_base; - bsp->b_strp = (char *)malloc(18); - sprintf(bsp->b_strp, "_CODE_%d=0x4000", i); - } - for(i = 0; i < nb_ram_banks; i++) { - bsp->b_base = (struct base *)new(sizeof(struct base)); - bsp = bsp->b_base; - bsp->b_strp = (char *)malloc(18); - sprintf(bsp->b_strp, "_DATA_%d=0xA000", i); - } + for(i = 1; i < nb_rom_banks; i++) { + bsp->b_base = (struct base *)new(sizeof(struct base)); + bsp = bsp->b_base; + bsp->b_strp = (char *)malloc(18); + sprintf(bsp->b_strp, "_CODE_%d=0x4000", i); + } + for(i = 0; i < nb_ram_banks; i++) { + bsp->b_base = (struct base *)new(sizeof(struct base)); + bsp = bsp->b_base; + bsp->b_strp = (char *)malloc(18); + sprintf(bsp->b_strp, "_DATA_%d=0xA000", i); + } #endif /* GAMEBOY */ - syminit(); - for (pass=0; pass<2; ++pass) { - cfp = NULL; - sfp = NULL; + syminit(); + for (pass=0; pass<2; ++pass) { + cfp = NULL; + sfp = NULL; #ifdef SDK - filep = linkp->f_flp; + filep = linkp->f_flp; #else /* SDK */ - filep = linkp; + filep = linkp; #endif /* SDK */ - hp = NULL; - radix = 10; - - while (lk_getline()) { - ip = ib; - link(); - } - if (pass == 0) { - /* - * Search libraries for global symbols - */ - search(); - /* - * Set area base addresses. - */ - setbas(); - /* - * Link all area addresses. - */ - lnkarea(); - /* - * Process global definitions. - */ - setgbl(); - /* - * Check for undefined globals. - */ - symdef(stderr); + hp = NULL; + radix = 10; + + while (lk_getline()) { + ip = ib; + link_main(); + } + if (pass == 0) { + /* + * Search libraries for global symbols + */ + search(); + /* + * Set area base addresses. + */ + setbas(); + /* + * Link all area addresses. + */ + lnkarea(); + /* + * Process global definitions. + */ + setgbl(); + /* + * Check for undefined globals. + */ + symdef(stderr); #ifdef SDK - if (symflag) - sym(); + if (symflag) + sym(); #endif - /* - * Output Link Map. - */ - if (mflag) - map(); - /* - * Open output file - */ - if (oflag == 1) { + /* + * Output Link Map if requested. + */ + if (mflag) + map(); + /* + * Open output file + */ + if (oflag == 1) { #ifdef SDK - ofp = afile(linkp->f_idp, "ihx", 1); + ofp = afile(linkp->f_idp, "ihx", 1); #else /* SDK */ - ofp = afile(linkp->f_idp, "IHX", 1); + ofp = afile(linkp->f_idp, "IHX", 1); #endif /* SDK */ - if (ofp == NULL) { - lkexit(1); - } - } else - if (oflag == 2) { + if (ofp == NULL) { + lkexit(1); + } + } else + if (oflag == 2) { #ifdef SDK - ofp = afile(linkp->f_idp, "s19", 1); + ofp = afile(linkp->f_idp, "s19", 1); #else /* SDK */ - ofp = afile(linkp->f_idp, "S19", 1); + ofp = afile(linkp->f_idp, "S19", 1); #endif /* SDK */ - if (ofp == NULL) { - lkexit(1); - } + if (ofp == NULL) { + lkexit(1); + } #ifdef SDK - } else - if (oflag == 3) { - binary = 1; - ofp = afile(linkp->f_idp, "", 1); - binary = 0; - if (ofp == NULL) { - lkexit(1); - } + } else + if (oflag == 3) { + binary = 1; + ofp = afile(linkp->f_idp, "", 1); + binary = 0; + if (ofp == NULL) { + lkexit(1); + } #endif /* SDK */ - } - } else { - /* - * Link in library files - */ - library(); - reloc('E'); - } - } + } + } else { + /* + * Link in library files + */ + library(); + reloc('E'); + } + } #ifdef WIN32T - Timer(1, "Linker time"); + Timer(1, "Linker execution time"); #endif - lkexit(lkerr); + + lkexit(lkerr); /* Never get here. */ return 0; } -/*)Function VOID lkexit(i) +/*)Function VOID lkexit(i) * - * int i exit code + * int i exit code * - * The function lkexit() explicitly closes all open - * files and then terminates the program. + * The function lkexit() explicitly closes all open + * files and then terminates the program. * - * local variables: - * none + * local variables: + * none * - * global variables: - * FILE * mfp file handle for .map - * FILE * ofp file handle for .ihx/.s19 - * FILE * rfp file hanlde for .rst - * FILE * sfp file handle for .rel - * FILE * tfp file handle for .lst + * global variables: + * FILE * mfp file handle for .map + * FILE * ofp file handle for .ihx/.s19 + * FILE * rfp file hanlde for .rst + * FILE * sfp file handle for .rel + * FILE * tfp file handle for .lst * - * functions called: - * int fclose() c_library - * VOID exit() c_library + * functions called: + * int fclose() c_library + * VOID exit() c_library * - * side effects: - * All files closed. Program terminates. + * side effects: + * All files closed. Program terminates. */ -VOID -lkexit(i) -int i; +VOID +lkexit(int i) { - if (mfp != NULL) fclose(mfp); - if (ofp != NULL) fclose(ofp); - if (rfp != NULL) fclose(rfp); - if (sfp != NULL) fclose(sfp); - if (tfp != NULL) fclose(tfp); - exit(i); + if (mfp != NULL) fclose(mfp); + if (ofp != NULL) fclose(ofp); + if (rfp != NULL) fclose(rfp); + if (sfp != NULL) fclose(sfp); + if (tfp != NULL) fclose(tfp); + exit(i); } -/*)Function link() - * - * The function link() evaluates the directives for each line of - * text read from the .rel file(s). The valid directives processed - * are: - * X, D, Q, H, M, A, S, T, R, and P. - * - * local variables: - * int c first non blank character of a line - * - * global variables: - * head *headp The pointer to the first - * head structure of a linked list - * head *hp Pointer to the current - * head structure - * int pass linker pass number - * int radix current number conversion radix - * - * functions called: - * char endline() lklex.c - * VOID module() lkhead.c - * VOID newarea() lkarea.c - * VOID newhead() lkhead.c - * sym * newsym() lksym.c - * VOID reloc() lkreloc.c - * - * side effects: - * Head, area, and symbol structures are created and - * the radix is set as the .rel file(s) are read. +/*)Function link_main() + * + * The function link_main() evaluates the directives for each line of + * text read from the .rel file(s). The valid directives processed + * are: + * X, D, Q, H, M, A, S, T, R, and P. + * + * local variables: + * int c first non blank character of a line + * + * global variables: + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * int pass linker pass number + * int radix current number conversion radix + * + * functions called: + * char endline() lklex.c + * VOID module() lkhead.c + * VOID newarea() lkarea.c + * VOID newhead() lkhead.c + * sym * newsym() lksym.c + * VOID reloc() lkreloc.c + * + * side effects: + * Head, area, and symbol structures are created and + * the radix is set as the .rel file(s) are read. */ VOID -link() +link_main() { - register int c; + register char c; - if ((c=endline()) == 0) { return; } - switch (c) { + if ((c=endline()) == 0) { return; } + switch (c) { - case 'O': /*For some important sdcc options*/ - if (pass == 0) - { - if(strlen(sdccopt)==0) - { - strcpy(sdccopt, &ip[1]); - strcpy(sdccopt_module, curr_module); - } - else - { - if(strcmp(sdccopt, &ip[1])!=0) + case 'O': /*For some important sdcc options*/ + if (pass == 0) { - fprintf(stderr, - "?ASlink-Warning-Conflicting sdcc options:\n" - " \"%s\" in module \"%s\" and\n" - " \"%s\" in module \"%s\".\n", - sdccopt, sdccopt_module, &ip[1], curr_module); - lkerr++; + if(strlen(sdccopt)==0) + { + strcpy(sdccopt, &ip[1]); + strcpy(sdccopt_module, curr_module); + } + else + { + if(strcmp(sdccopt, &ip[1])!=0) + { + fprintf(stderr, + "?ASlink-Warning-Conflicting sdcc options:\n" + " \"%s\" in module \"%s\" and\n" + " \"%s\" in module \"%s\".\n", + sdccopt, sdccopt_module, &ip[1], curr_module); + lkerr++; + } + } } - } - } - break; - - case 'X': - radix = 16; - break; - - case 'D': - radix = 10; - break; - - case 'Q': - radix = 8; - break; - - case 'H': - if (pass == 0) { - newhead(); - } else { - if (hp == 0) { - hp = headp; - } else { - hp = hp->h_hp; - } - } - sdp.s_area = NULL; - sdp.s_areax = NULL; - sdp.s_addr = 0; - break; - - case 'M': - if (pass == 0) + break; + + case 'X': + radix = 16; + break; + + case 'D': + radix = 10; + break; + + case 'Q': + radix = 8; + break; + + case 'H': + if (pass == 0) { + newhead(); + } else { + if (hp == 0) { + hp = headp; + } else { + hp = hp->h_hp; + } + } + sdp.s_area = NULL; + sdp.s_areax = NULL; + sdp.s_addr = 0; + break; + + case 'M': + if (pass == 0) { strcpy(curr_module, &ip[1]); - module(); + module(); + } + break; + + case 'A': + if (pass == 0) + newarea(); + if (sdp.s_area == NULL) { + sdp.s_area = areap; + sdp.s_areax = areap->a_axp; + sdp.s_addr = 0; + } + break; + + case 'S': + if (pass == 0) + newsym(); + break; + + case 'T': + case 'R': + case 'P': + if (pass == 0) + break; + reloc(c); + break; + + default: + break; + } + if (c == 'X' || c == 'D' || c == 'Q') { + if ((c = get()) == 'H') { + hilo = 1; + } else + if (c == 'L') { + hilo = 0; + } } - break; - - case 'A': - if (pass == 0) - newarea(); - if (sdp.s_area == NULL) { - sdp.s_area = areap; - sdp.s_areax = areap->a_axp; - sdp.s_addr = 0; - } - break; - - case 'S': - if (pass == 0) - newsym(); - break; - - case 'T': - case 'R': - case 'P': - if (pass == 0) - break; - reloc(c); - break; - - default: - break; - } - if (c == 'X' || c == 'D' || c == 'Q') { - if ((c = get()) == 'H') { - hilo = 1; - } else - if (c == 'L') { - hilo = 0; - } - } } -/*)Function VOID map() - * - * The function map() opens the output map file and calls the various - * routines to - * (1) output the variables in each area, - * (2) list the files processed with module names, - * (3) list the libraries file processed, - * (4) list base address definitions, - * (5) list global variable definitions, and - * (6) list any undefined variables. - * - * local variables: - * int i counter - * head * hdp pointer to head structure - * lbfile *lbfh pointer to library file structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * head *headp The pointer to the first - * head structure of a linked list - * lbfile *lbfhead The pointer to the first - * lbfile structure of a linked list - * lfile *linkp pointer to first lfile structure - * containing an input REL file - * specification - * int lop current line number on page - * FILE *mfp Map output file handle - * int page current page number - * - * functions called: - * FILE * afile() lkmain.c - * int fprintf() c_library - * VOID lkexit() lkmain.c - * VOID lstarea() lklist.c - * VOID newpag() lklist.c - * VOID symdef() lksym.c - * - * side effects: - * The map file is created. +/*)Function VOID map() + * + * The function map() opens the output map file and calls the various + * routines to + * (1) output the variables in each area, + * (2) list the files processed with module names, + * (3) list the libraries file processed, + * (4) list base address definitions, + * (5) list global variable definitions, and + * (6) list any undefined variables. + * + * local variables: + * int i counter + * head * hdp pointer to head structure + * lbfile *lbfh pointer to library file structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * head *headp The pointer to the first + * head structure of a linked list + * lbfile *lbfhead The pointer to the first + * lbfile structure of a linked list + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int lop current line number on page + * FILE *mfp Map output file handle + * int page current page number + * + * functions called: + * FILE * afile() lkmain.c + * int fprintf() c_library + * VOID lkexit() lkmain.c + * VOID lstarea() lklist.c + * VOID newpag() lklist.c + * VOID symdef() lksym.c + * + * side effects: + * The map file is created. */ #ifndef MLH_MAP VOID map() { - register i; - register struct head *hdp; - register struct lbfile *lbfh; + register int i; + register struct head *hdp; + register struct lbfile *lbfh; - /* - * Open Map File - */ + /* + * Open Map File + */ #ifdef SDK - mfp = afile(linkp->f_idp, "map", 1); + mfp = afile(linkp->f_idp, "map", 1); #else /* SDK */ - mfp = afile(linkp->f_idp, "MAP", 1); + mfp = afile(linkp->f_idp, "MAP", 1); #endif /* SDK */ - if (mfp == NULL) { - lkexit(1); - } - - /* - * Output Map Area Lists - */ - page = 0; - lop = NLPP; - ap = areap; - while (ap) { - lstarea(ap); - ap = ap->a_ap; - } - /* - * List Linked Files - */ - newpag(mfp); - fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n"); - hdp = headp; + if (mfp == NULL) { + lkexit(1); + } + + /* + * Output Map Area Lists + */ + page = 0; + lop = NLPP; + ap = areap; + while (ap) { + lstarea(ap); + ap = ap->a_ap; + } + /* + * List Linked Files + */ + newpag(mfp); + fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n"); + hdp = headp; #ifdef SDK - filep = linkp->f_flp; + filep = linkp->f_flp; #else /* SDK */ - filep = linkp; + filep = linkp; #endif /* SDK */ - while (filep) { - fprintf(mfp, "%-16s", filep->f_idp); - i = 0; - while ((hdp != NULL) && (hdp->h_lfile == filep)) { - if (i % 5) { - fprintf(mfp, ", %8.8s", hdp->m_id); - } else { - if (i) { - fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id); - } else { - fprintf(mfp, " [ %8.8s", hdp->m_id); - } - } - hdp = hdp->h_hp; - i++; - } - if (i) - fprintf(mfp, " ]"); - fprintf(mfp, "\n"); - filep = filep->f_flp; - } - /* - * List Linked Libraries - */ - if (lbfhead != NULL) { - fprintf(mfp, - "\nLibraries Linked [ object file ]\n\n"); - for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { - fprintf(mfp, "%-32s [ %16.16s ]\n", - lbfh->libspc, lbfh->relfil); - } - fprintf(mfp, "\n"); - } - /* - * List Base Address Definitions - */ - if (basep) { - newpag(mfp); - fprintf(mfp, "\nUser Base Address Definitions\n\n"); - bsp = basep; - while (bsp) { - fprintf(mfp, "%s\n", bsp->b_strp); - bsp = bsp->b_base; - } - } - /* - * List Global Definitions - */ - if (globlp) { - newpag(mfp); - fprintf(mfp, "\nUser Global Definitions\n\n"); - gsp = globlp; - while (gsp) { - fprintf(mfp, "%s\n", gsp->g_strp); - gsp = gsp->g_globl; - } - } - fprintf(mfp, "\n\f"); - symdef(mfp); + while (filep) { + fprintf(mfp, "%-16s", filep->f_idp); + i = 0; + while ((hdp != NULL) && (hdp->h_lfile == filep)) { + if (i % 5) { + fprintf(mfp, ", %8.8s", hdp->m_id); + } else { + if (i) { + fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id); + } else { + fprintf(mfp, " [ %8.8s", hdp->m_id); + } + } + hdp = hdp->h_hp; + i++; + } + if (i) + fprintf(mfp, " ]"); + fprintf(mfp, "\n"); + filep = filep->f_flp; + } + /* + * List Linked Libraries + */ + if (lbfhead != NULL) { + fprintf(mfp, + "\nLibraries Linked [ object file ]\n\n"); + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { + fprintf(mfp, "%-32s [ %16.16s ]\n", + lbfh->libspc, lbfh->relfil); + } + fprintf(mfp, "\n"); + } + /* + * List Base Address Definitions + */ + if (basep) { + newpag(mfp); + fprintf(mfp, "\nUser Base Address Definitions\n\n"); + bsp = basep; + while (bsp) { + fprintf(mfp, "%s\n", bsp->b_strp); + bsp = bsp->b_base; + } + } + /* + * List Global Definitions + */ + if (globlp) { + newpag(mfp); + fprintf(mfp, "\nUser Global Definitions\n\n"); + gsp = globlp; + while (gsp) { + fprintf(mfp, "%s\n", gsp->g_strp); + gsp = gsp->g_globl; + } + } + fprintf(mfp, "\n\f"); + symdef(mfp); } #else VOID map() { - register struct head *hdp; - register struct lbfile *lbfh; + register struct head *hdp; + register struct lbfile *lbfh; - /* - * Open Map File - */ + /* + * Open Map File + */ #ifdef SDK - mfp = afile(linkp->f_idp, "map", 1); + mfp = afile(linkp->f_idp, "map", 1); #else /* SDK */ - mfp = afile(linkp->f_idp, "MAP", 1); + mfp = afile(linkp->f_idp, "MAP", 1); #endif /* SDK */ - if (mfp == NULL) { - lkexit(1); - } - - /* - *Output Map Area Lists - */ - page = 0; - lop = NLPP; - ap = areap; - while (ap) { - lstarea(ap); - ap = ap->a_ap; - } - /* - * List Linked Files - */ - hdp = headp; + if (mfp == NULL) { + lkexit(1); + } + + /* + *Output Map Area Lists + */ + page = 0; + lop = NLPP; + ap = areap; + while (ap) { + lstarea(ap); + ap = ap->a_ap; + } + /* + * List Linked Files + */ + hdp = headp; #ifdef SDK - filep = linkp->f_flp; + filep = linkp->f_flp; #else /* SDK */ - filep = linkp; + filep = linkp; #endif /* SDK */ - if (filep) { - fprintf( mfp, "MODULES\n"); - } - while (filep) { - fprintf(mfp, "\tFILE %s\n", filep->f_idp); - while ((hdp != NULL) && (hdp->h_lfile == filep)) { - if (strlen(hdp->m_id)>0) - fprintf(mfp, "\t\tNAME %s\n", hdp->m_id); - hdp = hdp->h_hp; - } - filep = filep->f_flp; - } - /* - * List Linked Libraries - */ - if (lbfhead != NULL) { - fprintf(mfp, "LIBRARIES\n"); - for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { - fprintf(mfp, "\tLIBRARY %s\n" - "\t\tMODULE %s\n", - lbfh->libspc, lbfh->relfil); - } - } - /* - * List Base Address Definitions - */ - if (basep) { - fprintf(mfp, "USERBASEDEF\n"); - bsp = basep; - while (bsp) { - fprintf(mfp, "\t%s\n", bsp->b_strp); - bsp = bsp->b_base; - } - } - /* - * List Global Definitions - */ - if (globlp) { - fprintf(mfp, "USERGLOBALDEF\n"); - gsp = globlp; - while (gsp) { - fprintf(mfp, "\t%s\n", gsp->g_strp); - gsp = gsp->g_globl; - } - } - symdef(mfp); + if (filep) { + fprintf( mfp, "MODULES\n"); + } + while (filep) { + fprintf(mfp, "\tFILE %s\n", filep->f_idp); + while ((hdp != NULL) && (hdp->h_lfile == filep)) { + if (strlen(hdp->m_id)>0) + fprintf(mfp, "\t\tNAME %s\n", hdp->m_id); + hdp = hdp->h_hp; + } + filep = filep->f_flp; + } + /* + * List Linked Libraries + */ + if (lbfhead != NULL) { + fprintf(mfp, "LIBRARIES\n"); + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { + fprintf(mfp, "\tLIBRARY %s\n" + "\t\tMODULE %s\n", + lbfh->libspc, lbfh->relfil); + } + } + /* + * List Base Address Definitions + */ + if (basep) { + fprintf(mfp, "USERBASEDEF\n"); + bsp = basep; + while (bsp) { + fprintf(mfp, "\t%s\n", bsp->b_strp); + bsp = bsp->b_base; + } + } + /* + * List Global Definitions + */ + if (globlp) { + fprintf(mfp, "USERGLOBALDEF\n"); + gsp = globlp; + while (gsp) { + fprintf(mfp, "\t%s\n", gsp->g_strp); + gsp = gsp->g_globl; + } + } + symdef(mfp); #ifdef SDK - if (mfp!=NULL) { - fclose(mfp); - mfp = NULL; - } + if (mfp!=NULL) { + fclose(mfp); + mfp = NULL; + } #endif } #endif /* MLH_MAP */ @@ -836,667 +839,662 @@ VOID lstareatosym(struct area *xp); VOID sym() { - /* - * Open sym File - */ - mfp = afile(linkp->f_idp, "sym", 1); - if (mfp == NULL) { - lkexit(1); - } - fprintf( mfp, "; no$gmb format .sym file\n" - "; Generated automagically by ASxxxx linker %s (SDK " SDK_VERSION_STRING ")\n" - , VERSION ); - /* - * Output sym Area Lists - */ - page = 0; - lop = NLPP; - ap = areap; - while (ap) { - lstareatosym(ap); - ap = ap->a_ap; - } - if (mfp!=NULL) { - fclose(mfp); - mfp = NULL; - } + /* + * Open sym File + */ + mfp = afile(linkp->f_idp, "sym", 1); + if (mfp == NULL) { + lkexit(1); + } + fprintf( mfp, "; no$gmb format .sym file\n" + "; Generated automagically by ASxxxx linker %s (SDK " SDK_VERSION_STRING ")\n" + , VERSION ); + /* + * Output sym Area Lists + */ + page = 0; + lop = NLPP; + ap = areap; + while (ap) { + lstareatosym(ap); + ap = ap->a_ap; + } + if (mfp!=NULL) { + fclose(mfp); + mfp = NULL; + } } #endif /* SDK */ -/*)Function int parse() - * - * The function parse() evaluates all command line or file input - * linker directives and updates the appropriate variables. - * - * local variables: - * int c character value - * char fid[] file id string - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * lfile *lfp pointer to current lfile structure - * being processed by parse() - * lfile *linkp pointer to first lfile structure - * containing an input REL file - * specification - * int mflag Map output flag - * int oflag Output file type flag - * int pflag print linker command file flag - * FILE * stderr c_library - * int uflag Relocated listing flag - * int xflag Map file radix type flag - * - * Functions called: - * VOID addlib() lklibr.c - * VOID addpath() lklibr.c - * VOID bassav() lkmain.c - * int fprintf() c_library - * VOID gblsav() lkmain.c - * VOID getfid() lklex.c - * char getnb() lklex.c - * VOID lkexit() lkmain.c - * char * strcpy() c_library - * int strlen() c_library - * - * side effects: - * Various linker flags are updated and the linked - * structure lfile is created. +/*)Function int parse() + * + * The function parse() evaluates all command line or file input + * linker directives and updates the appropriate variables. + * + * local variables: + * int c character value + * char fid[] file id string + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * lfile *lfp pointer to current lfile structure + * being processed by parse() + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int mflag Map output flag + * int oflag Output file type flag + * int pflag print linker command file flag + * FILE * stderr c_library + * int uflag Relocated listing flag + * int xflag Map file radix type flag + * + * Functions called: + * VOID addlib() lklibr.c + * VOID addpath() lklibr.c + * VOID bassav() lkmain.c + * int fprintf() c_library + * VOID gblsav() lkmain.c + * VOID getfid() lklex.c + * char getnb() lklex.c + * VOID lkexit() lkmain.c + * char * strcpy() c_library + * int strlen() c_library + * + * side effects: + * Various linker flags are updated and the linked + * structure lfile is created. */ int parse() { - register int c; - char fid[NINPUT]; - - while ((c = getnb()) != 0) { - if (c == ';') - return(0); - if ( c == '-') { - while (ctype[c=get()] & LETTER) { - switch(c) { - - case 'i': - case 'I': - oflag = 1; - break; - - case 's': - case 'S': - oflag = 2; - break; + register int c; + char fid[NINPUT]; + + while ((c = getnb()) != 0) { + if (c == ';') + return(0); + if ( c == '-') { + while (ctype[c=get()] & LETTER) { + switch(c) { + + case 'i': + case 'I': + oflag = 1; + break; + + case 's': + case 'S': + oflag = 2; + break; #ifdef GAMEBOY - case 'y': - case 'Y': - c = get(); - if(c == 'O' || c == 'o') - nb_rom_banks = expr(0); - else if(c == 'A' || c == 'a') - nb_ram_banks = expr(0); - else if(c == 'T' || c == 't') - mbc_type = expr(0); - else if(c == 'N' || c == 'n') { - int i = 0; - if(getnb() != '=' || getnb() != '"') { - fprintf(stderr, "Syntax error in -YN=\"name\" flag\n"); - lkexit(1); - } - while((c = get()) != '"' && i < 16) { - cart_name[i++] = c; - } - if(i < 16) - cart_name[i] = 0; - else - while(get() != '"') - ; - } else if(c == 'P' || c == 'p') { - patch *p = patches; - - patches = (patch *)malloc(sizeof(patch)); - patches->next = p; - patches->addr = expr(0); - if(getnb() != '=') { - fprintf(stderr, "Syntax error in -YHaddr=val flag\n"); - lkexit(1); - } - patches->value = expr(0); - } else { - fprintf(stderr, "Invalid option\n"); - lkexit(1); - } - break; + case 'y': + case 'Y': + c = get(); + if(c == 'O' || c == 'o') + nb_rom_banks = expr(0); + else if(c == 'A' || c == 'a') + nb_ram_banks = expr(0); + else if(c == 'T' || c == 't') + mbc_type = expr(0); + else if(c == 'N' || c == 'n') { + int i = 0; + if(getnb() != '=' || getnb() != '"') { + fprintf(stderr, "Syntax error in -YN=\"name\" flag\n"); + lkexit(1); + } + while((c = get()) != '"' && i < 16) { + cart_name[i++] = c; + } + if(i < 16) + cart_name[i] = 0; + else + while(get() != '"') + ; + } else if(c == 'P' || c == 'p') { + patch *p = patches; + + patches = (patch *)malloc(sizeof(patch)); + patches->next = p; + patches->addr = expr(0); + if(getnb() != '=') { + fprintf(stderr, "Syntax error in -YHaddr=val flag\n"); + lkexit(1); + } + patches->value = expr(0); + } else { + fprintf(stderr, "Invalid option\n"); + lkexit(1); + } + break; #endif /* GAMEBOY */ #ifdef SDK - case 'j': - case 'J': - ++symflag; - break; - case 'z': - case 'Z': - oflag = 3; - break; + case 'j': + case 'J': + ++symflag; + break; + case 'z': + case 'Z': + oflag = 3; + break; #endif /* SDK */ - case 'm': - case 'M': - ++mflag; - break; - - case 'u': - case 'U': - uflag = 1; - break; - - case 'x': - case 'X': - xflag = 0; - break; - - case 'q': - case 'Q': - xflag = 1; - break; - - case 'd': - case 'D': - xflag = 2; - break; - - case 'e': - case 'E': - return(1); - - case 'n': - case 'N': - pflag = 0; - break; - - case 'p': - case 'P': - pflag = 1; - break; - - case 'b': - case 'B': - bassav(); - return(0); - - case 'g': - case 'G': - gblsav(); - return(0); - - case 'k': - case 'K': - addpath(); - return(0); - - case 'l': - case 'L': - addlib(); - return(0); - - default: - fprintf(stderr, "Invalid option\n"); - lkexit(1); - } - } - if (c == ';') - return(0); - } else - if (ctype[c] != ILL) { - if (linkp == NULL) { - linkp = (struct lfile *) - new (sizeof (struct lfile)); - lfp = linkp; - } else { - lfp->f_flp = (struct lfile *) - new (sizeof (struct lfile)); - lfp = lfp->f_flp; - } - getfid(fid, c); - lfp->f_idp = (char *) new (strlen(fid)+1); - strcpy(lfp->f_idp, fid); - lfp->f_type = F_REL; - } else { - fprintf(stderr, "Invalid input"); - lkexit(1); - } - } - return(0); + case 'm': + case 'M': + ++mflag; + break; + + case 'u': + case 'U': + uflag = 1; + break; + + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'e': + case 'E': + return(1); + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + case 'b': + case 'B': + bassav(); + return(0); + + case 'g': + case 'G': + gblsav(); + return(0); + + case 'k': + case 'K': + addpath(); + return(0); + + case 'l': + case 'L': + addlib(); + return(0); + + default: + fprintf(stderr, "Invalid option\n"); + lkexit(1); + } + } + if (c == ';') + return(0); + } else if (ctype[c] & ILL) { + fprintf(stderr, "Invalid input"); + lkexit(1); + } else { + if (linkp == NULL) { + linkp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = linkp; + } else { + lfp->f_flp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = lfp->f_flp; + } + getfid(fid, c); + lfp->f_idp = (char *) new (strlen(fid)+1); + strcpy(lfp->f_idp, fid); + lfp->f_type = F_REL; + } + } + return(0); } -/*)Function VOID bassav() +/*)Function VOID bassav() * - * The function bassav() creates a linked structure containing - * the base address strings input to the linker. + * The function bassav() creates a linked structure containing + * the base address strings input to the linker. * - * local variables: - * none + * local variables: + * none * - * global variables: - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * char *ip pointer into the REL file - * text line in ib[] + * global variables: + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * The basep structure is created. + * side effects: + * The basep structure is created. */ VOID bassav() { - if (basep == NULL) { - basep = (struct base *) - new (sizeof (struct base)); - bsp = basep; - } else { - bsp->b_base = (struct base *) - new (sizeof (struct base)); - bsp = bsp->b_base; - } - unget(getnb()); - bsp->b_strp = (char *) new (strlen(ip)+1); - strcpy(bsp->b_strp, ip); + if (basep == NULL) { + basep = (struct base *) + new (sizeof (struct base)); + bsp = basep; + } else { + bsp->b_base = (struct base *) + new (sizeof (struct base)); + bsp = bsp->b_base; + } + unget(getnb()); + bsp->b_strp = (char *) new (strlen(ip)+1); + strcpy(bsp->b_strp, ip); } - -/*)Function VOID setbas() - * - * The function setbas() scans the base address lines in hte - * basep structure, evaluates the arguments, and sets beginning - * address of the specified areas. - * - * local variables: - * int v expression value - * char id[] base id string - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * char *ip pointer into the REL file - * text line in ib[] - * int lkerr error flag - * - * functions called: - * Addr_T expr() lkeval.c - * int fprintf() c_library - * VOID getid() lklex.c - * char getnb() lklex.c - * int symeq() lksym.c - * - * side effects: - * The base address of an area is set. + +/*)Function VOID setbas() + * + * The function setbas() scans the base address lines in the + * basep structure, evaluates the arguments, and sets beginning + * address of the specified areas. + * + * local variables: + * int v expression value + * char id[] base id string + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag + * + * functions called: + * Addr_T expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * char getnb() lklex.c + * int symeq() lksym.c + * + * side effects: + * The base address of an area is set. */ VOID setbas() { - register int v; - char id[NCPS]; - - bsp = basep; - while (bsp) { - ip = bsp->b_strp; - getid(id, -1); - if (getnb() == '=') { - v = expr(0); - for (ap = areap; ap != NULL; ap = ap->a_ap) { - if (symeq(id, ap->a_id)) - break; - } - if (ap == NULL) { + register int v; + char id[NCPS]; + + bsp = basep; + while (bsp) { + ip = bsp->b_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + for (ap = areap; ap != NULL; ap = ap->a_ap) { + if (symeq(id, ap->a_id)) + break; + } + if (ap == NULL) { #ifndef SDK - fprintf(stderr, - "No definition of area %s\n", id); - lkerr++; + fprintf(stderr, + "ASlink-Warning-No definition of area %s\n", id); + lkerr++; #endif /* SDK */ - } else { - ap->a_addr = v; - } - } else { - fprintf(stderr, "No '=' in base expression"); - lkerr++; - } - bsp = bsp->b_base; - } + } else { + ap->a_addr = v; + } + } else { + fprintf(stderr, "ASlink-Warning-No '=' in base expression"); + lkerr++; + } + bsp = bsp->b_base; + } } -/*)Function VOID gblsav() +/*)Function VOID gblsav() * - * The function gblsav() creates a linked structure containing - * the global variable strings input to the linker. + * The function gblsav() creates a linked structure containing + * the global variable strings input to the linker. * - * local variable: - * none + * local variable: + * none * - * global variables: - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * char *ip pointer into the REL file - * text line in ib[] - * int lkerr error flag + * global variables: + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * The globlp structure is created. + * side effects: + * The globlp structure is created. */ VOID gblsav() { - if (globlp == NULL) { - globlp = (struct globl *) - new (sizeof (struct globl)); - gsp = globlp; - } else { - gsp->g_globl = (struct globl *) - new (sizeof (struct globl)); - gsp = gsp->g_globl; - } - unget(getnb()); - gsp->g_strp = (char *) new (strlen(ip)+1); - strcpy(gsp->g_strp, ip); + if (globlp == NULL) { + globlp = (struct globl *) + new (sizeof (struct globl)); + gsp = globlp; + } else { + gsp->g_globl = (struct globl *) + new (sizeof (struct globl)); + gsp = gsp->g_globl; + } + unget(getnb()); + 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 hte - * globlp structure, evaluates the arguments, and sets a variable - * to this value. - * - * local variables: - * int v expression value - * char id[] base id string - * sym * sp pointer to a symbol structure - * - * global variables: - * char *ip pointer into the REL file - * text line in ib[] - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * FILE * stderr c_library - * int lkerr error flag - * - * functions called: - * Addr_T expr() lkeval.c - * int fprintf() c_library - * VOID getid() lklex.c - * char getnb() lklex.c - * sym * lkpsym() lksym.c - * - * side effects: - * The value of a variable is set. + +/*)Function VOID setgbl() + * + * The function setgbl() scans the global variable lines in the + * globlp structure, evaluates the arguments, and sets a variable + * to this value. + * + * local variables: + * int v expression value + * char id[] base id string + * sym * sp pointer to a symbol structure + * + * global variables: + * char *ip pointer into the REL file + * text line in ib[] + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * FILE * stderr c_library + * int lkerr error flag + * + * functions called: + * Addr_T expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * char getnb() lklex.c + * sym * lkpsym() lksym.c + * + * side effects: + * The value of a variable is set. */ VOID setgbl() { - register int v; - register struct sym *sp; - char id[NCPS]; - - gsp = globlp; - while (gsp) { - ip = gsp->g_strp; - getid(id, -1); - if (getnb() == '=') { - v = expr(0); - sp = lkpsym(id, 0); - if (sp == NULL) { + register int v; + register struct sym *sp; + char id[NCPS]; + + gsp = globlp; + while (gsp) { + ip = gsp->g_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + sp = lkpsym(id, 0); + if (sp == NULL) { #ifndef SDK - fprintf(stderr, - "No definition of symbol %s\n", id); - lkerr++; + fprintf(stderr, + "No definition of symbol %s\n", id); + lkerr++; #endif /* SDK */ - } else { + } else { #ifndef SDK - if (sp->s_flag & S_DEF) { - fprintf(stderr, - "Redefinition of symbol %s\n", id); - lkerr++; - sp->s_axp = NULL; - } + if (sp->s_flag & S_DEF) { + fprintf(stderr, + "Redefinition of symbol %s\n", id); + lkerr++; + sp->s_axp = NULL; + } #endif /* SDK */ - sp->s_addr = v; - sp->s_type |= S_DEF; - } - } else { - fprintf(stderr, "No '=' in global expression"); - lkerr++; - } - gsp = gsp->g_globl; - } + sp->s_addr = v; + sp->s_type |= S_DEF; + } + } else { + fprintf(stderr, "No '=' in global expression"); + lkerr++; + } + gsp = gsp->g_globl; + } } -/*)Function FILE * afile(fn,, ft, wf) - * - * char * fn file specification string - * char * ft file type string - * int wf read(0)/write(1) flag - * - * The function afile() opens a file for reading or writing. - * (1) If the file type specification string ft - * is not NULL then a file specification is - * constructed with the file path\name in fn - * and the extension in ft. - * (2) If the file type specification string ft - * is NULL then the file specification is - * constructed from fn. If fn does not have - * a file type then the default .rel file - * type is appended to the file specification. - * - * afile() returns a file handle for the opened file or aborts - * the assembler on an open error. - * - * local variables: - * int c character value - * char fb[] constructed file specification string - * FILE * fp filehandle for opened file - * char * p1 pointer to filespec string fn - * char * p2 pointer to filespec string fb - * char * p3 pointer to filetype string ft - * - * global variables: - * int lkerr error flag - * - * functions called: - * FILE * fopen() c_library - * int fprintf() c_library - * - * side effects: - * File is opened for read or write. +/*)Function FILE * afile(fn,, ft, wf) + * + * char * fn file specification string + * char * ft file type string + * int wf read(0)/write(1) flag + * + * The function afile() opens a file for reading or writing. + * (1) If the file type specification string ft + * is not NULL then a file specification is + * constructed with the file path\name in fn + * and the extension in ft. + * (2) If the file type specification string ft + * is NULL then the file specification is + * constructed from fn. If fn does not have + * a file type then the default .rel file + * type is appended to the file specification. + * + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. + * + * local variables: + * int c character value + * char fb[] constructed file specification string + * FILE * fp filehandle for opened file + * char * p1 pointer to filespec string fn + * char * p2 pointer to filespec string fb + * char * p3 pointer to filetype string ft + * + * global variables: + * int lkerr error flag + * + * functions called: + * FILE * fopen() c_library + * int fprintf() c_library + * + * side effects: + * File is opened for read or write. */ FILE * -afile(fn, ft, wf) -char *fn; -char *ft; +afile(char *fn, char *ft, int wf) { #if 0 - register char *p1, *p2, *p3; - register int c; + register char *p1, *p2, *p3; + register int c; #else - int i; -#endif - FILE *fp; - char fb[FILSPC]; - -#if 0 - p1 = fn; - p2 = fb; - p3 = ft; - while ((c = *p1++) != 0 && c != FSEPX) { - if (p2 < &fb[FILSPC-4]) - *p2++ = c; - } - *p2++ = FSEPX; - if (*p3 == 0) { - if (c == FSEPX) { - p3 = p1; - } else { + int i; +#endif + FILE *fp; + char fb[PATH_MAX]; + +#if 0 + p1 = fn; + p2 = fb; + p3 = ft; + while ((c = *p1++) != 0 && c != FSEPX) { + if (p2 < &fb[PATH_MAX-4]) + *p2++ = c; + } + *p2++ = FSEPX; + if (*p3 == 0) { + if (c == FSEPX) { + p3 = p1; + } else { #ifdef SDK - p3 = "rel"; + p3 = "rel"; #else /* SDK */ - p3 = "REL"; + p3 = "REL"; #endif /* SDK */ - } - } - while ((c = *p3++) != 0) { - if (p2 < &fb[FILSPC-1]) - *p2++ = c; - } - *p2++ = 0; + } + } + while ((c = *p3++) != 0) { + if (p2 < &fb[FILSPC-1]) + *p2++ = c; + } + *p2++ = 0; #else - /*Look backward the name path and get rid of the extension, if any*/ - i=strlen(fn); - for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--); - if( (fn[i]=='.') && *ft && strcmp(ft, "lnk") ) - { - strncpy(fb, fn, i); - fb[i]=0; - } - else - { - strcpy(fb, fn); - } - - /*Add the extension*/ - if (fb[i] != '.') - { - strcat(fb, "."); + /*Look backward the name path and get rid of the extension, if any*/ + i=strlen(fn); + for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--); + if( (fn[i]=='.') && *ft && strcmp(ft, "lnk") ) + { + strncpy(fb, fn, i); + fb[i]=0; + } + else + { + strcpy(fb, fn); + } + + /*Add the extension*/ + if (fb[i] != '.') + { + strcat(fb, "."); #ifdef SDK - strcat(fb, strlen(ft)?ft:"rel"); + strcat(fb, strlen(ft)?ft:"rel"); #else - strcat(fb, strlen(ft)?ft:"REL"); + strcat(fb, strlen(ft)?ft:"REL"); #endif - } + } #endif #ifdef SDK - if ((fp = fopen(fb, wf?(binary?"wb":"w"):(binary?"rb":"r"))) == NULL) { + if ((fp = fopen(fb, wf?(binary?"wb":"w"):(binary?"rb":"r"))) == NULL) { #else /* SDK */ - if ((fp = fopen(fb, wf?"w":"r")) == NULL) { + if ((fp = fopen(fb, wf?"w":"r")) == NULL) { #endif /* SDK */ - fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); - lkerr++; - } - return (fp); + fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); + lkerr++; + } + return (fp); } char *usetxt[] = { #ifdef SDK - "Distributed with SDK " SDK_VERSION_STRING ", built on " __DATE__ " " __TIME__, - "Compile options: SDK Target " TARGET_STRING + "Distributed with SDK " SDK_VERSION_STRING ", built on " __DATE__ " " __TIME__, + "Compile options: SDK Target " TARGET_STRING #ifdef INDEXLIB - " INDEXLIB" + " INDEXLIB" #endif - "\n", + "\n", #endif - "Startup:", + "Startup:", #ifdef SDK - " -- [Commands] Non-interactive command line input", + " -- [Commands] Non-interactive command line input", #endif /* SDK */ - " -c Command line input", - " -f file[LNK] File input", - " -p Prompt and echo of file[LNK] to stdout (default)", - " -n No echo of file[LNK] to stdout", + " -c Command line input", + " -f file[LNK] File input", + " -p Prompt and echo of file[LNK] to stdout (default)", + " -n No echo of file[LNK] to stdout", #ifdef SDK - "Usage: [-Options] outfile file [file ...]", + "Usage: [-Options] outfile file [file ...]", #else /* SDK */ - "Usage: [-Options] file [file ...]", + "Usage: [-Options] file [file ...]", #endif /* SDK */ - "Librarys:", - " -k Library path specification, one per -k", - " -l Library file specification, one per -l", - "Relocation:", - " -b area base address = expression", - " -g global symbol = expression", + "Libraries:", + " -k Library path specification, one per -k", + " -l Library file specification, one per -l", + "Relocation:", + " -b area base address = expression", + " -g global symbol = expression", #ifdef GAMEBOY - " -yo Number of rom banks (default: 2)", - " -ya Number of ram banks (default: 0)", - " -yt MBC type (default: no MBC)", - " -yn Name of program (default: name of output file)", - " -yp# Patch one byte in the output GB file (# is: addr=byte)", + " -yo Number of rom banks (default: 2)", + " -ya Number of ram banks (default: 0)", + " -yt MBC type (default: no MBC)", + " -yn Name of program (default: name of output file)", + " -yp# Patch one byte in the output GB file (# is: addr=byte)", #endif /* GAMEBOY */ - "Map format:", - " -m Map output generated as file[MAP]", + "Map format:", + " -m Map output generated as file[MAP]", #ifdef SDK - " -j no$gmb symbol file generated as file[SYM]", + " -j no$gmb symbol file generated as file[SYM]", #endif /* SDK */ - " -x Hexidecimal (default)", - " -d Decimal", - " -q Octal", - "Output:", - " -i Intel Hex as file[IHX]", - " -s Motorola S19 as file[S19]", + " -x Hexadecimal (default), -d Decimal, -q Octal", + "Output:", + " -i Intel Hex as file[IHX]", + " -s Motorola S19 as file[S19]", #ifdef SDK #ifdef GAMEGEAR - " -z Gamegear image as file[GG]", + " -z Gamegear image as file[GG]", #else - " -z Gameboy image as file[GB]", + " -z Gameboy image as file[GB]", #endif /* GAMEGEAR */ #endif /* SDK */ - "List:", - " -u Update listing file(s) with link data as file(s)[.RST]", - "End:", - " -e or null line terminates input", - "", - 0 + "List:", + " -u Update listing file(s) with link data as file(s)[.RST]", + "End:", + " -e or null line terminates input", + "", + 0 }; -/*)Function VOID usage() +/*)Function VOID usage() * - * The function usage() outputs to the stderr device the - * assembler name and version and a list of valid assembler options. + * The function usage() outputs to the stderr device the + * assembler name and version and a list of valid assembler options. * - * local variables: - * char ** dp pointer to an array of - * text string pointers. + * local variables: + * char ** dp pointer to an array of + * text string pointers. * - * global variables: - * FILE * stderr c_library + * global variables: + * FILE * stderr c_library * - * functions called: - * int fprintf() c_library + * functions called: + * int fprintf() c_library * - * side effects: - * none + * side effects: + * none */ VOID usage() { - register char **dp; + register char **dp; - fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); - for (dp = usetxt; *dp; dp++) - fprintf(stderr, "%s\n", *dp); - lkexit(1); + fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + lkexit(1); } diff --git a/as/link/z80/lkrloc.c b/as/link/z80/lkrloc.c index e5bdd05a..5e97dae3 100644 --- a/as/link/z80/lkrloc.c +++ b/as/link/z80/lkrloc.c @@ -16,1156 +16,1120 @@ #include #include #include -//#include #include #include "aslink.h" -/*)Module lkrloc.c - * - * The module lkrloc.c contains the functions which - * perform the relocation calculations. - * - * lkrloc.c contains the following functions: - * Addr_T adb_b() - * Addr_T adb_lo() - * Addr_T adb_hi() - * Addr_T adw_w() - * Addr_T adw_lo() - * Addr_T adw_hi() - * VOID erpdmp() - * VOID errdmp() - * Addr_T evword() - * VOID prntval() - * VOID rele() - * VOID relerr() - * VOID relerp() - * VOID reloc() - * VOID relp() - * VOID relr() - * VOID relt() - * - * lkrloc.c the local variable errmsg[]. +/*)Module lkrloc.c + * + * The module lkrloc.c contains the functions which + * perform the relocation calculations. + * + * lkrloc.c contains the following functions: + * Addr_T adb_b() + * Addr_T adb_lo() + * Addr_T adb_hi() + * Addr_T adw_w() + * Addr_T adw_lo() + * Addr_T adw_hi() + * VOID erpdmp() + * VOID errdmp() + * Addr_T evword() + * VOID prntval() + * VOID rele() + * VOID relerr() + * VOID relerp() + * VOID reloc() + * VOID relp() + * VOID relr() + * VOID relt() + * + * lkrloc.c the local variable errmsg[]. * */ -/*)Function VOID reloc(c) +/*)Function VOID reloc(c) * - * char c process code + * char c process code * - * The function reloc() calls a particular relocation - * function determined by the process code. + * The function reloc() calls a particular relocation + * function determined by the process code. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int lkerr error flag + * global variables: + * int lkerr error flag * - * called functions: - * int fprintf() c_library - * VOID rele() lkrloc.c - * VOID relp() lkrloc.c - * VOID relr() lkrloc.c - * VOId relt() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID rele() lkrloc.c + * VOID relp() lkrloc.c + * VOID relr() lkrloc.c + * VOId relt() lkrloc.c * - * side effects: - * Refer to the called relocation functions. + * side effects: + * Refer to the called relocation functions. * */ -VOID -reloc(c) -char c; +VOID reloc(char c) { - switch(c) { + switch(c) { - case 'T': - relt(); - break; + case 'T': + relt(); + break; - case 'R': - relr(); - break; + case 'R': + relr(); + break; - case 'P': - relp(); - break; + case 'P': + relp(); + break; - case 'E': - rele(); - break; + case 'E': + rele(); + break; - default: - fprintf(stderr, "Undefined Relocation Operation\n"); - lkerr++; - break; + default: + fprintf(stderr, "Undefined Relocation Operation\n"); + lkerr++; + break; - } + } } -/*)Function VOID relt() +/*)Function VOID relt() * - * The function relt() evaluates a T line read by - * the linker. Each byte value read is saved in the - * rtval[] array, rtflg[] is set, and the number of - * evaluations is maintained in rtcnt. + * The function relt() evaluates a T line read by + * the linker. Each byte value read is saved in the + * rtval[] array, rtflg[] is set, and the number of + * evaluations is maintained in rtcnt. * - * T Line + * T Line * - * T xx xx nn nn nn nn nn ... + * T xx xx nn nn nn nn nn ... * * - * In: "T n0 n1 n2 n3 ... nn" + * In: "T n0 n1 n2 n3 ... nn" * - * Out: 0 1 2 .. rtcnt - * +----+----+----+----+----+ - * rtval | n0 | n1 | n2 | .. | nn | - * +----+----+----+----+----+ - * rtflag| 1 | 1 | 1 | 1 | 1 | - * +----+----+----+----+----+ + * Out: 0 1 2 .. rtcnt + * +----+----+----+----+----+ + * rtval | n0 | n1 | n2 | .. | nn | + * +----+----+----+----+----+ + * rtflag| 1 | 1 | 1 | 1 | 1 | + * +----+----+----+----+----+ * - * The T line contains the assembled code output by the assem- - * bler with xx xx being the offset address from the current area - * base address and nn being the assembled instructions and data in - * byte format. + * The T line contains the assembled code output by the assem- + * bler with xx xx being the offset address from the current area + * base address and nn being the assembled instructions and data in + * byte format. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int rtcnt number of values evaluated - * int rtflg[] array of evaluation flags - * int rtval[] array of evaluation values + * global variables: + * int rtcnt number of values evaluated + * int rtflg[] array of evaluation flags + * int rtval[] array of evaluation values * - * called functions: - * int eval() lkeval.c - * int more() lklex.c + * called functions: + * int eval() lkeval.c + * int more() lklex.c * - * side effects: - * Linker input T line evaluated. + * side effects: + * Linker input T line evaluated. * */ -VOID -relt() +VOID relt(VOID) { - rtcnt = 0; - while (more()) { - if (rtcnt < NTXT) { - rtval[rtcnt] = eval(); - rtflg[rtcnt] = 1; - rtcnt++; - } - } + rtcnt = 0; + while (more()) { + if (rtcnt < NTXT) { + rtval[rtcnt] = eval(); + rtflg[rtcnt] = 1; + rtcnt++; + } + } } -/*)Function VOID relr() - * - * The function relr() evaluates a R line read by - * the linker. The R line data is combined with the - * previous T line data to perform the relocation of - * code and data bytes. The S19 / IHX output and - * translation of the LST files to RST files may be - * performed. - * - * R Line - * - * R 0 0 nn nn n1 n2 xx xx ... - * - * The R line provides the relocation information to the linker. - * The nn nn value is the current area index, i.e. which area the - * current values were assembled. Relocation information is en- - * coded in groups of 4 bytes: - * - * 1. n1 is the relocation mode and object format - * 1. bit 0 word(0x00)/byte(0x01) - * 2. bit 1 relocatable area(0x00)/symbol(0x02) - * 3. bit 2 normal(0x00)/PC relative(0x04) relocation - * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for - * byte data - * 5. bit 4 signed(0x00)/unsigned(0x10) byte data - * 6. bit 5 normal(0x00)/page '0'(0x20) reference - * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference - * - * 2. n2 is a byte index into the corresponding (i.e. pre- - * ceeding) T line data (i.e. a pointer to the data to be - * updated by the relocation). The T line data may be - * 1-byte or 2-byte byte data format or 2-byte word - * format. - * - * 3. xx xx is the area/symbol index for the area/symbol be- - * ing referenced. the corresponding area/symbol is found - * in the header area/symbol lists. - * - * The groups of 4 bytes are repeated for each item requiring relo- - * cation in the preceeding T line. - * - * local variable: - * areax **a pointer to array of area pointers - * int aindex area index - * char *errmsg[] array of pointers to error strings - * int error error code - * int lkerr error flag - * int mode relocation mode - * adrr_t paga paging base area address - * Addr_T pags paging symbol address - * Addr_T pc relocated base address - * Addr_T r PCR relocation value - * Addr_T reli relocation initial value - * Addr_T relv relocation final value - * int rindex symbol / area index - * Addr_T rtbase base code address - * Addr_T rtofst rtval[] index offset - * int rtp index into T data - * sym **s pointer to array of symbol pointers - * - * global variables: - * head *hp pointer to the head structure - * rerr rerr linker error structure - * FILE *stderr standard error device - * - * called functions: - * Addr_T adb_b() lkrloc.c - * Addr_T adb_lo() lkrloc.c - * Addr_T adb_hi() lkrloc.c - * Addr_T adw_w() lkrloc.c - * Addr_T evword() lkrloc.c - * int eval() lkeval.c - * int fprintf() c_library - * VOID ihx() lkihx.c - * int lkulist lklist.c - * int more() lklex.c - * VOID relerr() lkrloc.c - * VOID s19() lks19.c - * int symval() lksym.c - * - * side effects: - * The R and T lines are combined to produce - * relocated code and data. Output S19 / IHX - * and relocated listing files may be produced. +/*)Function VOID relr() + * + * The function relr() evaluates a R line read by + * the linker. The R line data is combined with the + * previous T line data to perform the relocation of + * code and data bytes. The S19 / IHX output and + * translation of the LST files to RST files may be + * performed. + * + * R Line + * + * R 0 0 nn nn n1 n2 xx xx ... + * + * The R line provides the relocation information to the linker. + * The nn nn value is the current area index, i.e. which area the + * current values were assembled. Relocation information is en- + * coded in groups of 4 bytes: + * + * 1. n1 is the relocation mode and object format + * 1. bit 0 word(0x00)/byte(0x01) + * 2. bit 1 relocatable area(0x00)/symbol(0x02) + * 3. bit 2 normal(0x00)/PC relative(0x04) relocation + * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for + * byte data + * 5. bit 4 signed(0x00)/unsigned(0x10) byte data + * 6. bit 5 normal(0x00)/page '0'(0x20) reference + * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference + * + * 2. n2 is a byte index into the corresponding (i.e. pre- + * ceeding) T line data (i.e. a pointer to the data to be + * updated by the relocation). The T line data may be + * 1-byte or 2-byte byte data format or 2-byte word + * format. + * + * 3. xx xx is the area/symbol index for the area/symbol be- + * ing referenced. the corresponding area/symbol is found + * in the header area/symbol lists. + * + * The groups of 4 bytes are repeated for each item requiring relo- + * cation in the preceeding T line. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * char *errmsg[] array of pointers to error strings + * int error error code + * int lkerr error flag + * int mode relocation mode + * adrr_t paga paging base area address + * Addr_T pags paging symbol address + * Addr_T pc relocated base address + * Addr_T r PCR relocation value + * Addr_T reli relocation initial value + * Addr_T relv relocation final value + * int rindex symbol / area index + * Addr_T rtbase base code address + * Addr_T rtofst rtval[] index offset + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * rerr rerr linker error structure + * FILE *stderr standard error device + * + * called functions: + * Addr_T adb_b() lkrloc.c + * Addr_T adb_lo() lkrloc.c + * Addr_T adb_hi() lkrloc.c + * Addr_T adw_w() lkrloc.c + * Addr_T evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * VOID ihx() lkihx.c + * int lkulist lklist.c + * int more() lklex.c + * VOID relerr() lkrloc.c + * VOID s19() lks19.c + * int symval() lksym.c + * + * side effects: + * The R and T lines are combined to produce + * relocated code and data. Output S19 / IHX + * and relocated listing files may be produced. * */ -VOID -relr() +VOID relr(VOID) { - register int mode; - register Addr_T reli, relv; - int aindex, rindex, rtp, error; - Addr_T r, rtbase, rtofst, paga = 0, pags = 0, pc; - struct areax **a; - struct sym **s; - - /* - * Get area and symbol lists - */ - a = hp->a_list; - s = hp->s_list; - - /* - * Verify Area Mode - */ - if (eval() != (R_WORD | R_AREA) || eval()) { - fprintf(stderr, "R input error\n"); - lkerr++; - } - - /* - * Get area pointer - */ - aindex = evword(); - if (aindex >= hp->h_narea) { - fprintf(stderr, "R area error\n"); - lkerr++; - return; - } - - /* - * Base values - */ - rtbase = adw_w(0, 0); - rtofst = 2; - - /* - * Relocate address - */ - pc = adw_w(a[aindex]->a_addr, 0); + register int mode; + register Addr_T reli, relv; + int aindex, rindex, rtp, error; + Addr_T r, rtbase, rtofst, paga = 0, pags = 0, pc; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "R input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + + /* + * Base values + */ + rtbase = adw_w(0, 0); + rtofst = 2; + + /* + * Relocate address + */ + pc = adw_w(a[aindex]->a_addr, 0); #ifdef GAMEBOY - { - char *s = strrchr(a[aindex]->a_bap->a_id, '_'); - if(s != NULL && isdigit((unsigned char)s[1])) - current_rom_bank = atoi(s+1); - else - current_rom_bank = 0; - } + { + char *s = strrchr(a[aindex]->a_bap->a_id, '_'); + if(s != NULL && isdigit((unsigned char)s[1])) + current_rom_bank = atoi(s+1); + else + current_rom_bank = 0; + } #endif /* GAMEBOY */ - /* - * Do remaining relocations - */ - while (more()) { - error = 0; - mode = eval(); - rtp = eval(); - rindex = evword(); - - /* - * R_SYM or R_AREA references - */ - if (mode & R_SYM) { - if (rindex >= hp->h_nglob) { - fprintf(stderr, "R symbol error\n"); - lkerr++; - return; - } - reli = symval(s[rindex]); - } else { - if (rindex >= hp->h_narea) { - fprintf(stderr, "R area error\n"); - lkerr++; - return; - } - reli = a[rindex]->a_addr; - } - - /* - * R_PCR addressing - */ - if (mode & R_PCR) { - if (mode & R_BYTE) { - reli -= (pc + (rtp-rtofst) + 1); - } else { - reli -= (pc + (rtp-rtofst) + 2); - } - } - - /* - * R_PAG0 or R_PAG addressing - */ - if (mode & (R_PAG0|R_PAG)) { - paga = sdp.s_area->a_addr; - pags = sdp.s_addr; - reli -= paga + pags; - } - - /* - * R_BYTE or R_WORD operation - */ - if (mode & R_BYTE) { - if (mode & R_BYT2) { - if (mode & R_MSB) { - relv = adb_hi(reli, rtp); - } else { - relv = adb_lo(reli, rtp); - } - } else { - relv = adb_b(reli, rtp); - } - } else { - /* - * R_WORD with the R_BYT2 mode is flagged - * as an 'r' error by the assembler, - * but it is processed here anyway. - */ - if (mode & R_BYT2) { - if (mode & R_MSB) { - relv = adw_hi(reli, rtp); - } else { - relv = adw_lo(reli, rtp); - } - } else { - relv = adw_w(reli, rtp); - } - } - - /* - * R_BYTE with R_BYT2 offset adjust - */ - if (mode & R_BYTE) { - if (mode & R_BYT2) { - rtofst += 1; - } - } - - /* - * Unsigned Byte Checking - */ - if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) - error = 1; - - /* - * PCR Relocation Error Checking - */ - if (mode & R_PCR && mode & R_BYTE) { - r = relv & ~0x7F; - if (r != (Addr_T) ~0x7F && r != 0) - error = 2; - } - - /* - * Page Relocation Error Checking - */ - if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) - error = 3; - if (mode & R_PAG && (relv & ~0xFF)) - error = 4; - - /* - * Error Processing - */ - if (error) { - rerr.aindex = aindex; - rerr.mode = mode; - rerr.rtbase = rtbase + rtp - rtofst - 1; - rerr.rindex = rindex; - rerr.rval = relv - reli; - relerr(errmsg[error-1]); - } - } - if (uflag != 0) { - lkulist(1); - } - if (oflag == 1) { - ihx(1); - } else - if (oflag == 2) { - s19(1); + /* + * Do remaining relocations + */ + while (more()) { + error = 0; + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "R symbol error\n"); + lkerr++; + return; + } + reli = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + reli = a[rindex]->a_addr; + } + + /* + * R_PCR addressing + */ + if (mode & R_PCR) { + if (mode & R_BYTE) { + reli -= (pc + (rtp-rtofst) + 1); + } else { + reli -= (pc + (rtp-rtofst) + 2); + } + } + + /* + * R_PAG0 or R_PAG addressing + */ + if (mode & (R_PAG0 | R_PAG)) { + paga = sdp.s_area->a_addr; + pags = sdp.s_addr; + reli -= paga + pags; + } + + /* + * R_BYTE or R_WORD operation + */ + if (mode & R_BYTE) { + if (mode & R_BYT2) { + /* This is a two byte address, of + * which we will select one byte. + */ + if (mode & R_MSB) { + relv = adb_hi(reli, rtp); + } else { + relv = adb_lo(reli, rtp); + } + } else { + relv = adb_b(reli, rtp); + } + } else { + /* + * R_WORD with the R_BYT2 mode is flagged + * as an 'r' error by the assembler, + * but it is processed here anyway. + */ + if (mode & R_BYT2) { + if (mode & R_MSB) { + relv = adw_hi(reli, rtp); + } else { + relv = adw_lo(reli, rtp); + } + } else { + relv = adw_w(reli, rtp); + } + } + + /* + * R_BYTE with R_BYT2 offset adjust + */ + if (mode & R_BYTE) { + if (mode & R_BYT2) { + rtofst += 1; + } + } + + /* + * Unsigned Byte Checking + */ + if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) + error = 1; + + /* + * PCR Relocation Error Checking + */ + if (mode & R_PCR && mode & R_BYTE) { + r = relv & ~0x7F; + if (r != (Addr_T) ~0x7F && r != 0) + error = 2; + } + + /* + * Page Relocation Error Checking + */ + if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) + error = 3; + if (mode & R_PAG && (relv & ~0xFF)) + error = 4; + + /* + * Error Processing + */ + if (error) { + rerr.aindex = aindex; + rerr.mode = mode; + rerr.rtbase = rtbase + rtp - rtofst - 1; + rerr.rindex = rindex; + rerr.rval = relv - reli; + relerr(errmsg[error-1]); + } + } + if (uflag != 0) { + lkulist(1); + } + if (oflag == 1) { + ihx(1); + } else + if (oflag == 2) { + s19(1); #ifdef SDK - } else - if (oflag == 3) { + } else + if (oflag == 3) { #ifdef GAMEGEAR - gg(1); + gg(1); #endif /* GAMEGEAR */ #ifdef GAMEBOY - gb(1); + gb(1); #endif /* GAMEBOY */ #endif /* SDK */ - } + } } char *errmsg[] = { - "Unsigned Byte error", - "Byte PCR relocation error", - "Page0 relocation error", - "Page Mode relocation error" + "Unsigned Byte error", + "Byte PCR relocation error", + "Page0 relocation error", + "Page Mode relocation error" }; -/*)Function VOID relp() - * - * The function relp() evaluates a P line read by - * the linker. The P line data is combined with the - * previous T line data to set the base page address - * and test the paging boundary and length. - * - * P Line - * - * P 0 0 nn nn n1 n2 xx xx - * - * The P line provides the paging information to the linker as - * specified by a .setdp directive. The format of the relocation - * information is identical to that of the R line. The correspond- - * ing T line has the following information: - * T xx xx aa aa bb bb - * - * Where aa aa is the area reference number which specifies the - * selected page area and bb bb is the base address of the page. - * bb bb will require relocation processing if the 'n1 n2 xx xx' is - * specified in the P line. The linker will verify that the base - * address is on a 256 byte boundary and that the page length of an - * area defined with the PAG type is not larger than 256 bytes. - * - * local variable: - * areax **a pointer to array of area pointers - * int aindex area index - * int mode relocation mode - * Addr_T relv relocation value - * int rindex symbol / area index - * int rtp index into T data - * sym **s pointer to array of symbol pointers - * - * global variables: - * head *hp pointer to the head structure - * int lkerr error flag - * sdp sdp base page structure - * FILE *stderr standard error device - * - * called functions: - * Addr_T adw_w() lkrloc.c - * Addr_T evword() lkrloc.c - * int eval() lkeval.c - * int fprintf() c_library - * int more() lklex.c - * int symval() lksym.c - * - * side effects: - * The P and T lines are combined to set - * the base page address and report any - * paging errors. +/*)Function VOID relp() + * + * The function relp() evaluates a P line read by + * the linker. The P line data is combined with the + * previous T line data to set the base page address + * and test the paging boundary and length. + * + * P Line + * + * P 0 0 nn nn n1 n2 xx xx + * + * The P line provides the paging information to the linker as + * specified by a .setdp directive. The format of the relocation + * information is identical to that of the R line. The correspond- + * ing T line has the following information: + * T xx xx aa aa bb bb + * + * Where aa aa is the area reference number which specifies the + * selected page area and bb bb is the base address of the page. + * bb bb will require relocation processing if the 'n1 n2 xx xx' is + * specified in the P line. The linker will verify that the base + * address is on a 256 byte boundary and that the page length of an + * area defined with the PAG type is not larger than 256 bytes. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * int mode relocation mode + * Addr_T relv relocation value + * int rindex symbol / area index + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * int lkerr error flag + * sdp sdp base page structure + * FILE *stderr standard error device + * + * called functions: + * Addr_T adw_w() lkrloc.c + * Addr_T evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * int more() lklex.c + * int symval() lksym.c + * + * side effects: + * The P and T lines are combined to set + * the base page address and report any + * paging errors. * */ -VOID -relp() +VOID relp(VOID) { - register int aindex, rindex; - int mode, rtp; - Addr_T relv; - struct areax **a; - struct sym **s; - - /* - * Get area and symbol lists - */ - a = hp->a_list; - s = hp->s_list; - - /* - * Verify Area Mode - */ - if (eval() != (R_WORD | R_AREA) || eval()) { - fprintf(stderr, "P input error\n"); - lkerr++; - } - - /* - * Get area pointer - */ - aindex = evword(); - if (aindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - - /* - * Do remaining relocations - */ - while (more()) { - mode = eval(); - rtp = eval(); - rindex = evword(); - - /* - * R_SYM or R_AREA references - */ - if (mode & R_SYM) { - if (rindex >= hp->h_nglob) { - fprintf(stderr, "P symbol error\n"); - lkerr++; - return; - } - relv = symval(s[rindex]); - } else { - if (rindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - relv = a[rindex]->a_addr; - } - adw_w(relv, rtp); - } - - /* - * Paged values - */ - aindex = adw_w(0,2); - if (aindex >= hp->h_narea) { - fprintf(stderr, "P area error\n"); - lkerr++; - return; - } - sdp.s_areax = a[aindex]; - sdp.s_area = sdp.s_areax->a_bap; - sdp.s_addr = adw_w(0,4); - if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) - relerp("Page Definition Boundary Error"); + register int aindex, rindex; + int mode, rtp; + Addr_T relv; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "P input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + + /* + * Do remaining relocations + */ + while (more()) { + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "P symbol error\n"); + lkerr++; + return; + } + relv = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + relv = a[rindex]->a_addr; + } + adw_w(relv, rtp); + } + + /* + * Paged values + */ + aindex = adw_w(0,2); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + sdp.s_areax = a[aindex]; + sdp.s_area = sdp.s_areax->a_bap; + sdp.s_addr = adw_w(0,4); + if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) + relerp("Page Definition Boundary Error"); } -/*)Function VOID rele() +/*)Function VOID rele() * - * The function rele() closes all open output files - * at the end of the linking process. + * The function rele() closes all open output files + * at the end of the linking process. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int oflag output type flag - * int uflag relocation listing flag + * global variables: + * int oflag output type flag + * int uflag relocation listing flag * - * called functions: - * VOID ihx() lkihx.c - * VOID lkulist() lklist.c - * VOID s19() lks19.c + * called functions: + * VOID ihx() lkihx.c + * VOID lkulist() lklist.c + * VOID s19() lks19.c * - * side effects: - * All open output files are closed. + * side effects: + * All open output files are closed. * */ -VOID -rele() +VOID rele(VOID) { - if (uflag != 0) { - lkulist(0); - } - if (oflag == 1) { - ihx(0); - } else - if (oflag == 2) { - s19(0); + if (uflag != 0) { + lkulist(0); + } + if (oflag == 1) { + ihx(0); + } else + if (oflag == 2) { + s19(0); #ifdef SDK - } else - if (oflag == 3) { + } else + if (oflag == 3) { #ifdef GAMEGEAR - gg(0); + gg(0); #endif /* GAMEGEAR */ #ifdef GAMEBOY - gb(0); + gb(0); #endif /* GAMEBOY */ #endif /* SDK */ - } + } } -/*)Function Addr_T evword() +/*)Function Addr_T evword() * - * The function evword() combines two byte values - * into a single word value. + * The function evword() combines two byte values + * into a single word value. * - * local variable: - * Addr_T v temporary evaluation variable + * local variable: + * Addr_T v temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * int eval() lkeval.c + * called functions: + * int eval() lkeval.c * - * side effects: - * Relocation text line is scanned to combine - * two byte values into a single word value. + * side effects: + * Relocation text line is scanned to combine + * two byte values into a single word value. * */ -Addr_T -evword() +Addr_T evword(VOID) { - register Addr_T v; - - if (hilo) { - v = (eval() << 8); - v += eval(); - } else { - v = eval(); - v += (eval() << 8); - } - return(v); + register Addr_T v; + + if (hilo) { + v = (eval() << 8); + v += eval(); + } else { + v = eval(); + v += (eval() << 8); + } + return(v); } -/*)Function Addr_T adb_b(v, i) +/*)Function Addr_T adb_b(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_b() adds the value of v to - * the single byte value contained in rtval[i]. - * The new value of rtval[i] is returned. + * The function adb_b() adds the value of v to + * the single byte value contained in rtval[i]. + * The new value of rtval[i] is returned. * - * local variable: - * none + * local variable: + * none * - * global variables: - * none + * global variables: + * none * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. + * side effects: + * The value of rtval[] is changed. * */ -Addr_T -adb_b(v, i) -register Addr_T v; -register int i; +Addr_T adb_b(register Addr_T v, register int i) { - return(rtval[i] += v); + return(rtval[i] += v); } -/*)Function Addr_T adb_lo(v, i) +/*)Function Addr_T adb_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_lo() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB rtflg[] is cleared. + * The function adb_lo() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * MSB of the word value is cleared to reflect - * the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * MSB of the word value is cleared to reflect + * the fact that the LSB is the selected byte. * */ -Addr_T -adb_lo(v, i) -Addr_T v; -int i; +Addr_T adb_lo(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Remove Hi byte - */ - if (hilo) { - rtflg[i] = 0; - } else { - rtflg[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Remove Hi byte + */ + if (hilo) { + rtflg[i] = 0; + } else { + rtflg[i+1] = 0; + } + return (j); } -/*)Function Addr_T adb_hi(v, i) +/*)Function Addr_T adb_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adb_hi() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The LSB rtflg[] is cleared. + * The function adb_hi() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The LSB rtflg[] is cleared. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The rtflg[] value corresponding to the - * LSB of the word value is cleared to reflect - * the fact that the MSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The rtflg[] value corresponding to the + * LSB of the word value is cleared to reflect + * the fact that the MSB is the selected byte. * */ -Addr_T -adb_hi(v, i) -Addr_T v; -int i; +Addr_T adb_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Remove Lo byte - */ - if (hilo) { - rtflg[i+1] = 0; - } else { - rtflg[i] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Remove Lo byte + */ + if (hilo) { + rtflg[i+1] = 0; + } else { + rtflg[i] = 0; + } + return (j); } -/*)Function Addr_T adw_w(v, i) +/*)Function Addr_T adw_w(v, i) * - * int v value to add to word - * int i rtval[] index + * int v value to add to word + * int i rtval[] index * - * The function adw_w() adds the value of v to the - * word value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. + * The function adw_w() adds the value of v to the + * word value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The word value of rtval[] is changed. + * side effects: + * The word value of rtval[] is changed. * */ -Addr_T -adw_w(v, i) -register Addr_T v; -register int i; +Addr_T adw_w(register Addr_T v, register int i) { - register Addr_T j; - - if (hilo) { - j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff); - rtval[i] = (j >> 8) & 0xff; - rtval[i+1] = j & 0xff; - } else { - j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8); - rtval[i] = j & 0xff; - rtval[i+1] = (j >> 8) & 0xff; - } - return(j); + register Addr_T j; + + if (hilo) { + j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff); + rtval[i] = (j >> 8) & 0xff; + rtval[i+1] = j & 0xff; + } else { + j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + } + return(j); } -/*)Function Addr_T adw_lo(v, i) +/*)Function Addr_T adw_lo(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adw_lo() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB rtval[] is zeroed. + * The function adw_lo() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB rtval[] is zeroed. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The MSB of the word value is cleared to reflect - * the fact that the LSB is the selected byte. + * side effects: + * The value of rtval[] is changed. + * The MSB of the word value is cleared to reflect + * the fact that the LSB is the selected byte. * */ -Addr_T -adw_lo(v, i) -Addr_T v; -int i; +Addr_T adw_lo(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * Clear Hi byte - */ - if (hilo) { - rtval[i] = 0; - } else { - rtval[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * Clear Hi byte + */ + if (hilo) { + rtval[i] = 0; + } else { + rtval[i+1] = 0; + } + return (j); } -/*)Function Addr_T adw_hi(v, i) +/*)Function Addr_T adw_hi(v, i) * - * int v value to add to byte - * int i rtval[] index + * int v value to add to byte + * int i rtval[] index * - * The function adw_hi() adds the value of v to the - * double byte value contained in rtval[i] and rtval[i+1]. - * The new value of rtval[i] / rtval[i+1] is returned. - * The MSB and LSB values are interchanged. - * The MSB rtval[] is zeroed. + * The function adw_hi() adds the value of v to the + * double byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * The MSB and LSB values are interchanged. + * The MSB rtval[] is zeroed. * - * local variable: - * Addr_T j temporary evaluation variable + * local variable: + * Addr_T j temporary evaluation variable * - * global variables: - * hilo byte ordering parameter + * global variables: + * hilo byte ordering parameter * - * called functions: - * none + * called functions: + * none * - * side effects: - * The value of rtval[] is changed. - * The MSB and LSB values are interchanged and - * then the MSB cleared. + * side effects: + * The value of rtval[] is changed. + * The MSB and LSB values are interchanged and + * then the MSB cleared. * */ -Addr_T -adw_hi(v, i) -Addr_T v; -int i; +Addr_T adw_hi(Addr_T v, int i) { - register Addr_T j; - - j = adw_w(v, i); - /* - * LSB = MSB, Clear MSB - */ - if (hilo) { - rtval[i+1] = rtval[i]; - rtval[i] = 0; - } else { - rtval[i] = rtval[i+1]; - rtval[i+1] = 0; - } - return (j); + register Addr_T j; + + j = adw_w(v, i); + /* + * LSB = MSB, Clear MSB + */ + if (hilo) { + rtval[i+1] = rtval[i]; + rtval[i] = 0; + } else { + rtval[i] = rtval[i+1]; + rtval[i+1] = 0; + } + return (j); } -/*)Function VOID relerr(str) +/*)Function VOID relerr(str) * - * char *str error string + * char *str error string * - * The function relerr() outputs the error string to - * stderr and to the map file (if it is open). + * The function relerr() outputs the error string to + * stderr and to the map file (if it is open). * - * local variable: - * none + * local variable: + * none * - * global variables: - * FILE *mfp handle for the map file + * global variables: + * FILE *mfp handle for the map file * - * called functions: - * VOID errdmp() lkrloc.c + * called functions: + * VOID errdmp() lkrloc.c * - * side effects: - * Error message inserted into map file. + * side effects: + * Error message inserted into map file. * */ -VOID -relerr(str) -char *str; +VOID relerr(char *str) { - errdmp(stderr, str); - if (mfp) - errdmp(mfp, str); + errdmp(stderr, str); + if (mfp) + errdmp(mfp, str); } -/*)Function VOID errdmp(fptr, str) +/*)Function VOID errdmp(fptr, str) * - * FILE *fptr output file handle - * char *str error string + * FILE *fptr output file handle + * char *str error string * - * The function errdmp() outputs the error string str - * to the device specified by fptr. Additional information - * is output about the definition and referencing of - * the symbol / area error. + * The function errdmp() outputs the error string str + * to the device specified by fptr. Additional information + * is output about the definition and referencing of + * the symbol / area error. * - * local variable: - * int mode error mode - * int aindex area index - * int lkerr error flag - * int rindex error index - * sym **s pointer to array of symbol pointers - * areax **a pointer to array of area pointers - * areax *raxp error area extension pointer + * local variable: + * int mode error mode + * int aindex area index + * int lkerr error flag + * int rindex error index + * sym **s pointer to array of symbol pointers + * areax **a pointer to array of area pointers + * areax *raxp error area extension pointer * - * global variables: - * sdp sdp base page structure + * global variables: + * sdp sdp base page structure * - * called functions: - * int fprintf() c_library - * VOID prntval() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c * - * side effects: - * Error reported. + * side effects: + * Error reported. * */ -VOID -errdmp(fptr, str) -FILE *fptr; -char *str; +VOID errdmp(FILE *fptr, char *str) { - int mode, aindex, rindex; - struct sym **s; - struct areax **a; - struct areax *raxp; - - a = hp->a_list; - s = hp->s_list; - - mode = rerr.mode; - aindex = rerr.aindex; - rindex = rerr.rindex; - - /* - * Print Error - */ - fprintf(fptr, "\n?ASlink-Warning-%s", str); - lkerr++; - - /* - * Print symbol if symbol based - */ - if (mode & R_SYM) { - fprintf(fptr, " for symbol %.*s\n", - NCPS, &s[rindex]->s_id[0]); - } else { - fprintf(fptr, "\n"); - } - - /* - * Print Ref Info - */ - fprintf(fptr, - " file module area offset\n"); - fprintf(fptr, - " Refby %-8.8s %-8.8s %-8.8s ", - hp->h_lfile->f_idp, - &hp->m_id[0], - &a[aindex]->a_bap->a_id[0]); - prntval(fptr, rerr.rtbase); - - /* - * Print Def Info - */ - if (mode & R_SYM) { - raxp = s[rindex]->s_axp; - } else { - raxp = a[rindex]; - } - fprintf(fptr, - " Defin %-8.8s %-8.8s %-8.8s ", - raxp->a_bhp->h_lfile->f_idp, - &raxp->a_bhp->m_id[0], - &raxp->a_bap->a_id[0]); - if (mode & R_SYM) { - prntval(fptr, s[rindex]->s_addr); - } else { - prntval(fptr, rerr.rval); - } + int mode, aindex, rindex; + struct sym **s; + struct areax **a; + struct areax *raxp; + + a = hp->a_list; + s = hp->s_list; + + mode = rerr.mode; + aindex = rerr.aindex; + rindex = rerr.rindex; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s", str); + lkerr++; + + /* + * Print symbol if symbol based + */ + if (mode & R_SYM) { + fprintf(fptr, " for symbol %.*s\n", + NCPS, &s[rindex]->s_id[0]); + } else { + fprintf(fptr, "\n"); + } + + /* + * Print Ref Info + */ + fprintf(fptr, + " file module area offset\n"); + fprintf(fptr, + " Refby %-8.8s %-8.8s %-8.8s ", + hp->h_lfile->f_idp, + &hp->m_id[0], + &a[aindex]->a_bap->a_id[0]); + prntval(fptr, rerr.rtbase); + + /* + * Print Def Info + */ + if (mode & R_SYM) { + raxp = s[rindex]->s_axp; + } else { + raxp = a[rindex]; + } + fprintf(fptr, + " Defin %-8.8s %-8.8s %-8.8s ", + raxp->a_bhp->h_lfile->f_idp, + &raxp->a_bhp->m_id[0], + &raxp->a_bap->a_id[0]); + if (mode & R_SYM) { + prntval(fptr, s[rindex]->s_addr); + } else { + prntval(fptr, rerr.rval); + } } -/*)Function VOID prntval(fptr, v) +/*)Function VOID prntval(fptr, v) * - * FILE *fptr output file handle - * Addr_T v value to output + * FILE *fptr output file handle + * Addr_T v value to output * - * The function prntval() outputs the value v, in the - * currently selected radix, to the device specified - * by fptr. + * The function prntval() outputs the value v, in the + * currently selected radix, to the device specified + * by fptr. * - * local variable: - * none + * local variable: + * none * - * global variables: - * int xflag current radix + * global variables: + * int xflag current radix * - * called functions: - * int fprintf() c_library + * called functions: + * int fprintf() c_library * - * side effects: - * none + * side effects: + * none * */ -VOID -prntval(fptr, v) -FILE *fptr; -Addr_T v; +VOID prntval(FILE *fptr, Addr_T v) { - if (xflag == 0) { - fprintf(fptr, "%04X\n", v); - } else - if (xflag == 1) { - fprintf(fptr, "%06o\n", v); - } else - if (xflag == 2) { - fprintf(fptr, "%05u\n", v); - } + if (xflag == 0) { + fprintf(fptr, "%04X\n", v); + } else + if (xflag == 1) { + fprintf(fptr, "%06o\n", v); + } else + if (xflag == 2) { + fprintf(fptr, "%05u\n", v); + } } -/*)Function VOID relerp(str) +/*)Function VOID relerp(str) * - * char *str error string + * char *str error string * - * The function relerp() outputs the paging error string to - * stderr and to the map file (if it is open). + * The function relerp() outputs the paging error string to + * stderr and to the map file (if it is open). * - * local variable: - * none + * local variable: + * none * - * global variables: - * FILE *mfp handle for the map file + * global variables: + * FILE *mfp handle for the map file * - * called functions: - * VOID erpdmp() lkrloc.c + * called functions: + * VOID erpdmp() lkrloc.c * - * side effects: - * Error message inserted into map file. + * side effects: + * Error message inserted into map file. * */ -VOID -relerp(str) -char *str; +VOID relerp(char *str) { - erpdmp(stderr, str); - if (mfp) - erpdmp(mfp, str); + erpdmp(stderr, str); + if (mfp) + erpdmp(mfp, str); } -/*)Function VOID erpdmp(fptr, str) +/*)Function VOID erpdmp(fptr, str) * - * FILE *fptr output file handle - * char *str error string + * FILE *fptr output file handle + * char *str error string * - * The function erpdmp() outputs the error string str - * to the device specified by fptr. + * The function erpdmp() outputs the error string str + * to the device specified by fptr. * - * local variable: - * head *thp pointer to head structure + * local variable: + * head *thp pointer to head structure * - * global variables: - * int lkerr error flag - * sdp sdp base page structure + * global variables: + * int lkerr error flag + * sdp sdp base page structure * - * called functions: - * int fprintf() c_library - * VOID prntval() lkrloc.c + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c * - * side effects: - * Error reported. + * side effects: + * Error reported. * */ -VOID -erpdmp(fptr, str) -FILE *fptr; -char *str; +VOID erpdmp(FILE *fptr, char *str) { - register struct head *thp; - - thp = sdp.s_areax->a_bhp; - - /* - * Print Error - */ - fprintf(fptr, "\n?ASlink-Warning-%s\n", str); - lkerr++; - - /* - * Print PgDef Info - */ - fprintf(fptr, - " file module pgarea pgoffset\n"); - fprintf(fptr, - " PgDef %-8.8s %-8.8s %-8.8s ", - thp->h_lfile->f_idp, - &thp->m_id[0], - &sdp.s_area->a_id[0]); - prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); + register struct head *thp; + + thp = sdp.s_areax->a_bhp; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s\n", str); + lkerr++; + + /* + * Print PgDef Info + */ + fprintf(fptr, + " file module pgarea pgoffset\n"); + fprintf(fptr, + " PgDef %-8.8s %-8.8s %-8.8s ", + thp->h_lfile->f_idp, + &thp->m_id[0], + &sdp.s_area->a_id[0]); + prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); } diff --git a/as/link/z80/lks19.c b/as/link/z80/lks19.c index bbca7530..26d8892e 100644 --- a/as/link/z80/lks19.c +++ b/as/link/z80/lks19.c @@ -11,7 +11,6 @@ #include #include -//#include #include "aslink.h" /*)Module lks19.c diff --git a/as/link/z80/lksym.c b/as/link/z80/lksym.c index 33cc6ffb..50c21f87 100644 --- a/as/link/z80/lksym.c +++ b/as/link/z80/lksym.c @@ -98,6 +98,7 @@ syminit() * 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 @@ -130,7 +131,7 @@ newsym() struct sym **s; char id[NCPS]; - getid(id, -1); + getSid(id); // old: getid(id, -1); tsp = lkpsym(id, 1); c = getnb();get();get(); if (c == 'R') { @@ -179,7 +180,7 @@ newsym() lkexit(1); /* Never reached */ - return 0; + return(0); } /*)Function sym * lkpsym(id,f) @@ -232,7 +233,7 @@ char *id; sp = (struct sym *) new (sizeof(struct sym)); sp->s_sp = symhash[h]; symhash[h] = sp; - strncpy(sp->s_id, id, NCPS); + sp->s_id = StoreString( id ); /* JLH */ return (sp); } @@ -359,8 +360,8 @@ struct sym *tsp; p = hp->s_list; for (i=0; ih_nglob; ++i) { if (p[i] == tsp) { - fprintf(fp, "\n?ASlink-Warning-Undefined Global %s ", tsp->s_id); - fprintf(fp, "referenced by module %s\n", hp->m_id); + fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id); + fprintf(fp, "referenced by module '%s'\n", hp->m_id); lkerr++; } } @@ -396,21 +397,11 @@ int symeq(p1, p2) register char *p1, *p2; { - register int n; - - n = NCPS; - do { - #if CASE_SENSITIVE - if (*p1++ != *p2++) - return (0); + return (strncmp( p1, p2, NCPS ) == 0); #else - if (ccase[(unsigned char)(*p1++)] != ccase[(unsigned char)(*p2++)]) - return (0); + return (as_strncmpi( p1, p2, NCPS ) == 0); #endif - - } while (--n); - return (1); } /*)Function int hash(p) @@ -484,15 +475,11 @@ VOID * new(n) unsigned int n; { - register char *p,*q; - register unsigned int i; + register char *p; - if ((p = (char *) malloc(n)) == NULL) { + if ((p = (char *) calloc(n, 1)) == NULL) { fprintf(stderr, "Out of space!\n"); lkexit(1); } - for (i=0,q=p; i