moved mcs51 linker to as/link/mcs51
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 15 Sep 2006 06:52:50 +0000 (06:52 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 15 Sep 2006 06:52:50 +0000 (06:52 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4378 4a8a32a2-be11-0410-ad9d-d568d2c75423

55 files changed:
ChangeLog
Makefile.in
as/aslink.dsp [deleted file]
as/link/mcs51/Makefile.aslink [new file with mode: 0644]
as/link/mcs51/Makefile.bcc [new file with mode: 0644]
as/link/mcs51/Makefile.in [new file with mode: 0644]
as/link/mcs51/alloc.h [new file with mode: 0644]
as/link/mcs51/aslink.dsp [new file with mode: 0644]
as/link/mcs51/aslink.h [new file with mode: 0644]
as/link/mcs51/aslink.mak [new file with mode: 0644]
as/link/mcs51/clean.mk [new file with mode: 0644]
as/link/mcs51/conf.mk [new file with mode: 0644]
as/link/mcs51/lkaomf51.c [new file with mode: 0644]
as/link/mcs51/lkarea.c [new file with mode: 0644]
as/link/mcs51/lkdata.c [new file with mode: 0644]
as/link/mcs51/lkeval.c [new file with mode: 0644]
as/link/mcs51/lkhead.c [new file with mode: 0644]
as/link/mcs51/lkihx.c [new file with mode: 0644]
as/link/mcs51/lklex.c [new file with mode: 0644]
as/link/mcs51/lklibr.c [new file with mode: 0644]
as/link/mcs51/lklist.c [new file with mode: 0644]
as/link/mcs51/lkmain.c [new file with mode: 0644]
as/link/mcs51/lkmem.c [new file with mode: 0644]
as/link/mcs51/lknoice.c [new file with mode: 0644]
as/link/mcs51/lkrloc.c [new file with mode: 0644]
as/link/mcs51/lks19.c [new file with mode: 0644]
as/link/mcs51/lkstore.c [new file with mode: 0644]
as/link/mcs51/lksym.c [new file with mode: 0644]
as/link/mcs51/readme.390 [new file with mode: 0644]
as/link/mcs51/strcmpi.c [new file with mode: 0644]
as/link/mcs51/strcmpi.h [new file with mode: 0644]
as/mcs51/Makefile.aslink [deleted file]
as/mcs51/Makefile.bcc
as/mcs51/Makefile.in
as/mcs51/aslink.h [deleted file]
as/mcs51/aslink.mak [deleted file]
as/mcs51/clean.mk
as/mcs51/lkaomf51.c [deleted file]
as/mcs51/lkarea.c [deleted file]
as/mcs51/lkdata.c [deleted file]
as/mcs51/lkeval.c [deleted file]
as/mcs51/lkhead.c [deleted file]
as/mcs51/lkihx.c [deleted file]
as/mcs51/lklex.c [deleted file]
as/mcs51/lklibr.c [deleted file]
as/mcs51/lklist.c [deleted file]
as/mcs51/lkmain.c [deleted file]
as/mcs51/lkmem.c [deleted file]
as/mcs51/lknoice.c [deleted file]
as/mcs51/lkrloc.c [deleted file]
as/mcs51/lks19.c [deleted file]
as/mcs51/lkstore.c [deleted file]
as/mcs51/lksym.c [deleted file]
configure
sdcc.dsw

index 0e3315f240ffae7b4eed05553e09329c92fdea04..0207c5754b0fcc992df9a64fba168606afdb1ca4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2006-09-15 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       as/link/mcs51
+       as/aslink.dsp,                  as/link/mcs51/aslink.dsp,
+       as/link/mcs51/aslink.h,         as/mcs51/aslink.h,
+       as/link/mcs51/aslink.mak,       as/mcs51/aslink.mak,
+       as/link/mcs51/lkaomf51.c,       as/mcs51/lkaomf51.c,
+       as/link/mcs51/lkarea.c,         as/mcs51/lkarea.c,
+       as/link/mcs51/lkdata.c,         as/mcs51/lkdata.c,
+       as/link/mcs51/lkeval.c,         as/mcs51/lkeval.c,
+       as/link/mcs51/lkhead.c,         as/mcs51/lkhead.c,
+       as/link/mcs51/lkihx.c,          as/mcs51/lkihx.c,
+       as/link/mcs51/lklex.c,          as/mcs51/lklex.c,
+       as/link/mcs51/lklibr.c,         as/mcs51/lklibr.c,
+       as/link/mcs51/lklist.c,         as/mcs51/lklist.c,
+       as/link/mcs51/lkmain.c,         as/mcs51/lkmain.c,
+       as/link/mcs51/lkmem.c,          as/mcs51/lkmem.c,
+       as/link/mcs51/lknoice.c,        as/mcs51/lknoice.c,
+       as/link/mcs51/lkrloc.c,         as/mcs51/lkrloc.c,
+       as/link/mcs51/lks19.c,          as/mcs51/lks19.c,
+       as/link/mcs51/lkstore.c,        as/mcs51/lkstore.c,
+       as/link/mcs51/lksym.c,          as/mcs51/lksym.c,
+       as/link/mcs51/Makefile.aslink,  as/mcs51/Makefile.aslink,
+       as/link/mcs51/alloc.h,
+       as/link/mcs51/clean.mk,
+       as/link/mcs51/conf.mk,
+       as/link/mcs51/Makefile.bcc,
+       as/link/mcs51/Makefile.in,
+       as/link/mcs51/readme.390,
+       as/link/mcs51/strcmpi.c,
+       as/link/mcs51/strcmpi.h,
+       as/mcs51/clean.mk,
+       as/mcs51/Makefile.bcc,
+       as/mcs51/Makefile.in,
+       configure,
+       Makefile.in,
+       sdcc.dsw: moved mcs51 linker to as/link/mcs51
+
 2006-09-14 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * as/link,
index fd9410ad3d75da386b22c607b150f9b7ed41630d..54f76486f1d014b80db34321964b365e0ff54505 100644 (file)
@@ -25,7 +25,7 @@ SDCC_ASLINK     += as/hc08
 endif
 
 ifeq ($(OPT_DISABLE_MCS51), 0)
-SDCC_ASLINK     += as/mcs51
+SDCC_ASLINK     += as/mcs51 as/link/mcs51
 SDCC_MISC      += debugger/mcs51
 endif
 
diff --git a/as/aslink.dsp b/as/aslink.dsp
deleted file mode 100644 (file)
index d6d410a..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-# Microsoft Developer Studio Project File - Name="aslink" - Package Owner=<4>\r
-# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
-# ** DO NOT EDIT **\r
-\r
-# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
-\r
-CFG=aslink - Win32 Release\r
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "aslink.mak".\r
-!MESSAGE \r
-!MESSAGE You can specify a configuration when running NMAKE\r
-!MESSAGE by defining the macro CFG on the command line. For example:\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "aslink.mak" CFG="aslink - Win32 Release"\r
-!MESSAGE \r
-!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
-!MESSAGE "aslink - Win32 Debug" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "aslink - Win32 Release" (based on "Win32 (x86) Console Application")\r
-!MESSAGE \r
-\r
-# Begin Project\r
-# PROP AllowPerConfigDependencies 0\r
-# PROP Scc_ProjName ""\r
-# PROP Scc_LocalPath ""\r
-CPP=cl.exe\r
-RSC=rc.exe\r
-\r
-!IF  "$(CFG)" == "aslink - Win32 Debug"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "mcs51\Debug"\r
-# PROP BASE Intermediate_Dir "mcs51\Debug"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "mcs51\Debug"\r
-# PROP Intermediate_Dir "mcs51\Debug"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# 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\r
-# 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\r
-# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
-# ADD RSC /l 0x409 /d "_DEBUG"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\bin_vc\aslink.exe" /pdbtype:sept\r
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\bin_vc\aslink.exe" /pdbtype:sept\r
-\r
-!ELSEIF  "$(CFG)" == "aslink - Win32 Release"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "mcs51\Release"\r
-# PROP BASE Intermediate_Dir "mcs51\Release"\r
-# PROP BASE Ignore_Export_Lib 0\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "mcs51\Release"\r
-# PROP Intermediate_Dir "mcs51\Release"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# 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\r
-# ADD CPP /nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FD /c\r
-# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
-# ADD RSC /l 0x409 /d "NDEBUG"\r
-BSC32=bscmake.exe\r
-# ADD BASE BSC32 /nologo\r
-# ADD BSC32 /nologo\r
-LINK32=link.exe\r
-# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /out:"..\bin_vc\aslink.exe" /pdbtype:sept\r
-# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\bin_vc\aslink.exe" /pdbtype:sept\r
-\r
-!ENDIF \r
-\r
-# Begin Target\r
-\r
-# Name "aslink - Win32 Debug"\r
-# Name "aslink - Win32 Release"\r
-# Begin Group "Source Files"\r
-\r
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\lkaomf51.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkarea.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkdata.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkeval.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkhead.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkihx.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lklex.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lklibr.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lklist.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkmain.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\lkmem.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lknoice.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkrloc.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lks19.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lkstore.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=mcs51\lksym.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\strcmpi.c\r
-# End Source File\r
-# End Group\r
-# Begin Group "Header Files"\r
-\r
-# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\alloc.h\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\aslink.h\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\asm.h\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\i8051.h\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\mcs51\string.h\r
-# End Source File\r
-# End Group\r
-# End Target\r
-# End Project\r
diff --git a/as/link/mcs51/Makefile.aslink b/as/link/mcs51/Makefile.aslink
new file mode 100644 (file)
index 0000000..0aebe56
--- /dev/null
@@ -0,0 +1,68 @@
+CC=gcc
+LEX=flex
+YACC=bison
+INCROOT=.
+CFLAGS=-ggdb -O2 -I $(INCROOT)
+TARGETS=$(SDCCDIR)/bin/aslink
+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
+all:: $(TARGETS)
+
+clean::
+       rm -f $(TARGETS) $(ALLOBJECTS)
+
+lkmain.o : lkmain.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkmain.o lkmain.c
+
+lkhead.o : lkhead.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkhead.o lkhead.c
+
+lkarea.o : lkarea.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkarea.o lkarea.c
+
+lkdata.o : lkdata.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkdata.o lkdata.c
+
+lkeval.o : lkeval.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkeval.o lkeval.c
+
+lklex.o  : lklex.c  aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lklex.o lklex.c
+
+lksym.o  : lksym.c  aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lksym.o lksym.c
+
+lkrloc.o : lkrloc.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkrloc.o lkrloc.c
+
+lklibr.o : lklibr.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lklibr.o lklibr.c
+
+lklist.o : lklist.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lklist.o lklist.c
+
+lkihx.o  : lkihx.c  aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkihx.o lkihx.c
+
+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
+
+lknoice.o : lknoice.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lknoice.o lknoice.c
+
+strcmpi.o : strcmpi.c strcmpi.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o strcmpi.o strcmpi.c
+
+lkmem.o : lkmem.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkmem.o lkmem.c
+
+lkaomf51.o : lkaomf51.c aslink.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkaomf51.o lkaomf51.c
+
+$(TARGETS): $(ALLOBJECTS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(ALLOBJECTS) 
diff --git a/as/link/mcs51/Makefile.bcc b/as/link/mcs51/Makefile.bcc
new file mode 100644 (file)
index 0000000..a61786e
--- /dev/null
@@ -0,0 +1,17 @@
+# Makefile for Borland C++
+
+PRJDIR          = ../..
+
+!include $(PRJDIR)/Bcc.inc
+
+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
+
+ASLINK          = $(PRJDIR)/bin/aslink.exe
+
+all: $(ASLINK)
+
+$(ASLINK): $(LKOBJECTS)
+        $(CC) $(CFLAGS) -e$@ $(LKOBJECTS)
diff --git a/as/link/mcs51/Makefile.in b/as/link/mcs51/Makefile.in
new file mode 100644 (file)
index 0000000..90d52bd
--- /dev/null
@@ -0,0 +1,111 @@
+#
+#
+#
+
+VERSION         = @VERSION@
+VERSIONHI       = @VERSIONHI@
+VERSIONLO       = @VERSIONLO@
+VERSIONP        = @VERSIONP@
+
+SHELL          = /bin/sh
+CC             = @CC@
+CPP            = @CPP@
+INSTALL                = @INSTALL@
+STRIP           = @STRIP@
+
+top_builddir   = @top_builddir@
+top_srcdir     = @top_srcdir@
+
+srcdir         = @srcdir@
+prefix         = @prefix@
+exec_prefix     = @exec_prefix@
+bindir          = @bindir@
+libdir          = @libdir@
+datadir         = @datadir@
+includedir      = @includedir@
+mandir          = @mandir@
+man1dir         = $(mandir)/man1
+man2dir         = $(mandir)/man2
+infodir         = @info@
+
+EXEEXT          = @EXEEXT@
+
+VPATH           = @srcdir@
+
+CPPFLAGS       = @CPPFLAGS@ -I. -I$(srcdir)
+CFLAGS         = @CFLAGS@ -Wall -DINDEXLIB
+M_OR_MM                = @M_OR_MM@
+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
+LKSOURCES      = $(patsubst %.o,%.c,$(LKOBJECTS))
+
+ASLINK         = $(top_builddir)bin/aslink$(EXEEXT)
+
+transform       = @program_transform_name@
+
+# Compiling entire program or any subproject
+# ------------------------------------------
+all: checkconf $(ASLINK)
+
+$(ASLINK): $(LKOBJECTS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LKOBJECTS)
+
+# Compiling and installing everything and running test
+# ----------------------------------------------------
+install: all installdirs
+       $(INSTALL) $(ASLINK) `echo $(DESTDIR)$(bindir)/aslink$(EXEEXT)|sed '$(transform)'`
+       $(STRIP) `echo $(DESTDIR)$(bindir)/aslink$(EXEEXT)|sed '$(transform)'`
+
+# Deleting all the installed files
+# --------------------------------
+uninstall:
+       rm -f $(DESTDIR)$(bindir)/aslink$(EXEEXT)
+
+
+# Performing self-test
+# --------------------
+check:
+
+
+# Performing installation test
+# ----------------------------
+installcheck:
+
+
+# Creating installation directories
+# ---------------------------------
+installdirs:
+       $(INSTALL) -d $(DESTDIR)$(bindir)
+
+
+# Creating dependencies
+# ---------------------
+dep: Makefile.dep
+
+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 \
+                                   clean distclean mostlyclean realclean)" ""
+  include Makefile.dep
+endif
+include $(srcdir)/clean.mk
+
+# My rules
+# --------
+.c.o:
+       $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+
+# Remaking configuration
+# ----------------------
+checkconf:
+       @if [ -f $(top_builddir)devel ]; then\
+          $(MAKE) -f conf.mk srcdir="$(srcdir)" top_builddir="$(top_builddir)" freshconf;\
+        fi
+
+# End of Makefile
diff --git a/as/link/mcs51/alloc.h b/as/link/mcs51/alloc.h
new file mode 100644 (file)
index 0000000..dd404a8
--- /dev/null
@@ -0,0 +1,4 @@
+/* alloc.h */
+/* DECUS C */
+
+#include <stdlib.h>
diff --git a/as/link/mcs51/aslink.dsp b/as/link/mcs51/aslink.dsp
new file mode 100644 (file)
index 0000000..f19847e
--- /dev/null
@@ -0,0 +1,175 @@
+# Microsoft Developer Studio Project File - Name="aslink" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=aslink - Win32 Release\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "aslink.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "aslink.mak" CFG="aslink - Win32 Release"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "aslink - Win32 Debug" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "aslink - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "aslink - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mcs51\Debug"\r
+# PROP BASE Intermediate_Dir "mcs51\Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# 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\r
+# 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\r
+# ADD BASE RSC /l 0x409 /d "_DEBUG"\r
+# ADD RSC /l 0x409 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "aslink - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "mcs51\Release"\r
+# PROP BASE Intermediate_Dir "mcs51\Release"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# 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\r
+# ADD CPP /nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "INDEXLIB" /D "MLH_MAP" /D "SDK" /FD /c\r
+# ADD BASE RSC /l 0x409 /d "NDEBUG"\r
+# ADD RSC /l 0x409 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\aslink.exe" /pdbtype:sept\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "aslink - Win32 Debug"\r
+# Name "aslink - Win32 Release"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\lkaomf51.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkarea.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkdata.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkeval.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkhead.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkihx.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklex.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklibr.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklist.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkmain.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkmem.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lknoice.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkrloc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lks19.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkstore.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lksym.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\strcmpi.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\alloc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\aslink.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\strcmpi.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/as/link/mcs51/aslink.h b/as/link/mcs51/aslink.h
new file mode 100644 (file)
index 0000000..bcd921d
--- /dev/null
@@ -0,0 +1,788 @@
+/* aslink.h */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * 28-Oct-97 JLH:
+ *           - add proto for StoreString
+ *           - change s_id from [NCPS] to pointer
+ *           - change NCPS to 80
+ *           - case sensitive
+ *           - add R_J11 for 8051 assembler
+ * 31-Oct-97 JLH:
+ *           - add jflag and jfp for NoICE output
+ * 30-Jan-98 JLH:
+ *           - add memory space flags to a_flag for 8051
+ */
+
+#define VERSION "V01.70 + NoICE + SDCC Feb 1999"
+
+/*
+ * 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 <limits.h>
+#ifndef PATH_MAX                /* POSIX, but not required   */
+ #if defined(__BORLANDC__) || defined(_MSC_VER)
+  #include <stdlib.h>
+  #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.
+ */
+
+#define NCPS    80              /* characters per symbol (JLH: change from 8) */
+#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 */
+
+/*
+ *      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 Byte */
+#define R_USGN  0x10            /* Unsigned Byte */
+
+#define R_NOPAG 0x00            /* Page Mode */
+#define R_PAG0  0x20            /* Page '0' */
+#define R_PAG   0x40            /* Page 'nnn' */
+
+#define R_LSB   0x00            /* low byte */
+#define R_MSB   0x80            /* high byte */
+
+#define R_BYT3  0x100           /* if R_BYTE is set, this is a
+                                 * 3 byte address, of which
+                                 * the linker must select one byte.
+                                 */
+#define R_HIB   0x200           /* If R_BYTE & R_BYT3 are set, linker
+                                 * will select byte 3 of the relocated
+                                 * 24 bit address.
+                                 */
+
+#define R_BIT   0x400           /* Linker will convert from byte-addressable
+                                 * space to bit-addressable space.
+                                 */
+
+#define R_J11   (R_WORD|R_BYT2) /* JLH: 11 bit JMP and CALL (8051) */
+#define R_J19   (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */
+#define R_C24   (R_WORD|R_BYT1|R_MSB) /* 24 bit address (DS80C390) */
+#define R_J19_MASK (R_BYTE|R_BYT2|R_MSB)
+
+#define IS_R_J19(x) (((x) & R_J19_MASK) == R_J19)
+#define IS_R_J11(x) (((x) & R_J19_MASK) == R_J11)
+#define IS_C24(x) (((x) & R_J19_MASK) == R_C24)
+
+#define R_ESCAPE_MASK   0xf0    /* Used to escape relocation modes
+                                 * greater than 0xff in the .rel
+                                 * file.
+                                 */
+
+/*
+ * Global symbol types.
+ */
+#define S_REF   1               /* referenced */
+#define S_DEF   2               /* defined */
+
+/*
+ * 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 */
+
+/* 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 */
+
+/*
+ * File types
+ */
+#define F_STD   1               /* stdin */
+#define F_LNK   2               /* File.lnk */
+#define F_REL   3               /* File.rel */
+
+/*
+ *      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 */
+        Addr_T  a_unaloc;       /* Total number of unalocated bytes, for error reporting */
+        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;          /* Name: JLH change from [NCPS] */
+};
+
+/*
+ *      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 as_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    *jfp;           /*      NoICE 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  FILE    *dfp;           /*      File handle for debug info output
+                                 */
+extern  int     dflag;          /*      Output debug information flag
+                                 */
+extern  int     oflag;          /*      Output file type flag
+                                 */
+extern  int     mflag;          /*      Map output flag
+                                 */
+extern  int     sflag;          /*      JCF: Memory usage output flag
+                                 */
+extern  int     packflag;       /*      Pack data memory flag
+                                 */
+extern  int     stacksize;      /*      Pack data memory flag
+                                 */
+extern  int     jflag;          /*      NoICE output flag
+                                 */
+extern  int     xflag;          /*      Map file radix type flag
+                                 */
+extern  int     pflag;          /*      print linker command file flag
+                                 */
+extern  int     uflag;          /*      Listing relocation flag
+                                 */
+extern int      rflag;          /*      Extended linear address record 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
+                                 */
+extern  Addr_T iram_size;       /*      internal ram size
+                                 */
+extern  long xram_size;         /*      external ram size
+                                 */
+extern  long code_size;         /*      code size
+                                 */
+
+
+/* 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            iramsav();
+extern  VOID            xramsav();
+extern  VOID            codesav();
+extern  VOID            iramcheck();
+extern  VOID            link_main();
+extern  VOID            lkexit();
+extern  int             main();
+extern  VOID            map();
+extern  int             parse();
+extern  VOID            setbas();
+extern  VOID            setgbl();
+extern  VOID            usage();
+extern  VOID            copyfile();
+
+/* lklex.c */
+extern  char            endline();
+extern  char            get();
+extern  VOID            getfid();
+extern  VOID            getid();
+extern  VOID            getSid();
+extern  int             as_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            lnkarea2();
+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(register Addr_T v, register int i);
+extern  Addr_T          adb_bit(register Addr_T v, register int i);
+extern  Addr_T          adb_hi(Addr_T  v, int i);
+extern  Addr_T          adb_lo(Addr_T  v, int i);
+extern  Addr_T          adb_24_bit(register Addr_T v, register int i);
+extern  Addr_T          adb_24_hi(Addr_T v, int i);
+extern  Addr_T          adb_24_mid(Addr_T v, int i);
+extern  Addr_T          adb_24_lo(Addr_T v, int i);
+extern  Addr_T          adw_w(register Addr_T v, register int i);
+extern  Addr_T          adw_24(Addr_T v, int i);
+extern  Addr_T          adw_hi(Addr_T  v, int i);
+extern  Addr_T          adw_lo(Addr_T  v, int i);
+extern  Addr_T          evword(VOID);
+extern  VOID            rele(VOID);
+extern  VOID            reloc(char c);
+extern  VOID            relt(VOID);
+extern  VOID            relr(VOID);
+extern  VOID            relp(VOID);
+extern  VOID            relerr(char *str);
+extern  char *          errmsg[];
+extern  VOID            errdmp(FILE *fptr, char *str);
+extern  VOID            relerp(char *str);
+extern  VOID            erpdmp(FILE *fptr, char *str);
+extern  VOID            prntval(FILE *fptr, Addr_T v);
+extern  int             lastExtendedAddress;
+
+/* 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();
+extern  VOID            ihxEntendedLinearAddress(Addr_T);
+extern  VOID            newArea();
+
+/* lkstore.c */
+extern char             *StoreString( char *str );
+
+/* lknoice.c */
+extern void             DefineNoICE( char *name, Addr_T value, int page );
+
+/* JCF: lkmem.c */
+extern int summary(struct area * xp);
+extern int summary2(struct area * xp);
+
+/* JCF: lkaomf51.c */
+extern void SaveLinkedFilePath(char * filepath);
+extern void CreateAOMF51(void);
diff --git a/as/link/mcs51/aslink.mak b/as/link/mcs51/aslink.mak
new file mode 100644 (file)
index 0000000..300803d
--- /dev/null
@@ -0,0 +1,263 @@
+ORIGIN         = Symantec C++
+ORIGIN_VER     = Version 7.00
+VERSION                = RELEASE
+
+!IFDEF SUB_DEBUG
+DEBUG          = $(SUB_DEBUG)
+NDEBUG         = !$(SUB_DEBUG)
+!ELSE
+DEBUG          = 0
+NDEBUG         = 1
+!ENDIF
+
+PROJ           = ASLINK
+APPTYPE                = DOS EXE
+PROJTYPE       = EXE
+
+CC             = SC
+CPP            = SPP
+MAKE           = SMAKE
+RC             = RCC
+HC             = HC31
+ASM            = SC
+DISASM         = OBJ2ASM
+LNK            = LINK
+DLLS           = 
+
+HEADERS                = ..\linksrc\aslink.h 
+
+DEFFILE                = ASLINK.DEF
+
+!IF $(DEBUG)
+OUTPUTDIR      = .
+CREATEOUTPUTDIR        =
+TARGETDIR      = .
+CREATETARGETDIR        =
+
+LIBS           = 
+
+CFLAGS         =  -A -Jm -J -ms -o+time -S -2 -a2 -c 
+LFLAGS         =  /PACKF
+DEFINES                = -D_DEBUG=1
+!ELSE
+OUTPUTDIR      = .
+CREATEOUTPUTDIR        =
+TARGETDIR      = .
+CREATETARGETDIR        =
+
+LIBS           = 
+
+CFLAGS         =  -A -Jm -J -ms -o+time -S -2 -a2 -c 
+LFLAGS         =  /PACKF
+DEFINES                = 
+!ENDIF
+
+HFLAGS         = $(CFLAGS) 
+MFLAGS         = MASTERPROJ=$(PROJ) 
+LIBFLAGS       =  /C 
+RESFLAGS       =  
+DEBUGGERFLAGS  =  -LOADSYMBOLS 
+AFLAGS         = $(CFLAGS) 
+HELPFLAGS      = 
+
+MODEL          = S
+
+PAR            = PROJS BATS OBJS
+
+RCDEFINES      = 
+
+LIBDIRS                = 
+
+INCLUDES       = -Ic:\asxxxx\linksrc
+
+INCLUDEDOBJS   = 
+
+OBJS           =  $(OUTPUTDIR)\lkarea.OBJ  $(OUTPUTDIR)\lkdata.OBJ  $(OUTPUTDIR)\lkeval.OBJ  \
+                $(OUTPUTDIR)\lkhead.OBJ  $(OUTPUTDIR)\lkihx.OBJ  $(OUTPUTDIR)\lklex.OBJ  $(OUTPUTDIR)\lklibr.OBJ  \
+                $(OUTPUTDIR)\lklist.OBJ  $(OUTPUTDIR)\lkmain.OBJ  $(OUTPUTDIR)\lkrloc.OBJ  $(OUTPUTDIR)\lks19.OBJ  \
+                $(OUTPUTDIR)\lksym.OBJ 
+
+RCFILES                = 
+
+RESFILES       = 
+
+SYMS           = 
+
+HELPFILES      = 
+
+BATS           = 
+
+.SUFFIXES: .C .CP .CPP .CXX .CC .H .HPP .HXX .COM .EXE .DLL .LIB .RTF .DLG .ASM .RES .RC .OBJ 
+
+.C.OBJ:
+       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.c
+
+.CPP.OBJ:
+       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cpp
+
+.CXX.OBJ:
+       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cxx
+
+.CC.OBJ:
+       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cc
+
+.CP.OBJ:
+       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cp
+
+.H.SYM:
+       $(CC) $(HFLAGS) $(DEFINES) $(INCLUDES) -HF -o$(*B).sym $*.h
+
+.HPP.SYM:
+       $(CC) $(HFLAGS) $(DEFINES) $(INCLUDES) -HF -o$(*B).sym $*.hpp
+
+.HXX.SYM:
+       $(CC) $(HFLAGS) $(DEFINES) $(INCLUDES) -HF -o$(*B).sym $*.hxx
+
+.C.EXP:
+       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES)   $*.c   -o$*.lst
+
+.CPP.EXP:
+       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) $*.cpp -o$*.lst
+
+.CXX.EXP:
+       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) $*.cxx -o$*.lst
+
+.CP.EXP:
+       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES)  $*.cp  -o$*.lst
+
+.CC.EXP:
+       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES)  $*.cc  -o$*.lst
+
+.ASM.EXP:
+       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) $*.asm -o$*.lst
+
+.OBJ.COD:
+       $(DISASM) $*.OBJ >$*.cod
+
+.OBJ.EXE:
+       $(LNK) $(LFLAGS) @$(PROJ).LNK
+
+.RTF.HLP:
+       $(HC) $(HELPFLAGS) $*.HPJ
+
+.ASM.OBJ:
+       $(ASM) $(AFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.asm
+
+.RC.RES: 
+       $(RC) $(RCDEFINES) $(RESFLAGS) $(INCLUDES) $*.rc -o$*.res
+
+.DLG.RES:
+       echo ^#include "windows.h" >$$$*.rc
+       echo ^IF EXIST "$*.h" >>$$$*.rc
+       echo ^#include "$*.h" >>$$$*.rc
+       echo ^#include "$*.dlg" >>$$$*.rc
+       $(RC) $(RCDEFINES) $(RESFLAGS) $(INCLUDES) $$$*.rc
+       -del $*.res
+       -ren $$$*.res $*.res
+
+
+
+all:   createdir $(PRECOMPILE) $(SYMS) $(OBJS) $(INCLUDEDOBJS) $(POSTCOMPILE) $(TARGETDIR)\$(PROJ).$(PROJTYPE) $(POSTLINK) _done
+
+createdir:
+       $(CREATEOUTPUTDIR)
+       $(CREATETARGETDIR)
+
+$(TARGETDIR)\$(PROJ).$(PROJTYPE): $(OBJS) $(INCLUDEDOBJS) $(RCFILES) $(RESFILES) $(HELPFILES) 
+                       $(LNK) $(LFLAGS) @$(PROJ).LNK;
+                       -del $(TARGETDIR)\$(PROJ).$(PROJTYPE)
+                       -ren $(TARGETDIR)\$$SCW$$.$(PROJTYPE) $(PROJ).$(PROJTYPE)
+                       -echo $(TARGETDIR)\$(PROJ).$(PROJTYPE) built
+
+_done:
+               -echo $(PROJ).$(PROJTYPE) done
+
+buildall:      clean   all
+
+
+clean:
+               -del $(TARGETDIR)\$$SCW$$.$(PROJTYPE)
+               -del $(TARGETDIR)\$(PROJ).CLE
+               -del $(OUTPUTDIR)\SCPH.SYM
+               -del $(OBJS)
+
+cleanres:
+
+res:           cleanres $(RCFILES) all
+
+
+link:
+               $(LNK) $(LFLAGS) @$(PROJ).LNK;
+               -del $(TARGETDIR)\$(PROJ).$(PROJTYPE)
+               -ren $(TARGETDIR)\$$SCW$$.$(PROJTYPE) $(PROJ).$(PROJTYPE)
+
+
+
+
+!IF EXIST (ASLINK.dpd)
+!INCLUDE ASLINK.dpd
+!ENDIF
+
+
+
+$(OUTPUTDIR)\lkarea.OBJ:       ..\linksrc\lkarea.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkarea.obj ..\linksrc\lkarea.c
+
+
+
+$(OUTPUTDIR)\lkdata.OBJ:       ..\linksrc\lkdata.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkdata.obj ..\linksrc\lkdata.c
+
+
+
+$(OUTPUTDIR)\lkeval.OBJ:       ..\linksrc\lkeval.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkeval.obj ..\linksrc\lkeval.c
+
+
+
+$(OUTPUTDIR)\lkhead.OBJ:       ..\linksrc\lkhead.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkhead.obj ..\linksrc\lkhead.c
+
+
+
+$(OUTPUTDIR)\lkihx.OBJ:        ..\linksrc\lkihx.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkihx.obj ..\linksrc\lkihx.c
+
+
+
+$(OUTPUTDIR)\lklex.OBJ:        ..\linksrc\lklex.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lklex.obj ..\linksrc\lklex.c
+
+
+
+$(OUTPUTDIR)\lklibr.OBJ:       ..\linksrc\lklibr.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lklibr.obj ..\linksrc\lklibr.c
+
+
+
+$(OUTPUTDIR)\lklist.OBJ:       ..\linksrc\lklist.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lklist.obj ..\linksrc\lklist.c
+
+
+
+$(OUTPUTDIR)\lkmain.OBJ:       ..\linksrc\lkmain.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkmain.obj ..\linksrc\lkmain.c
+
+
+
+$(OUTPUTDIR)\lkrloc.OBJ:       ..\linksrc\lkrloc.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkrloc.obj ..\linksrc\lkrloc.c
+
+
+
+$(OUTPUTDIR)\lks19.OBJ:        ..\linksrc\lks19.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lks19.obj ..\linksrc\lks19.c
+
+
+
+$(OUTPUTDIR)\lksym.OBJ:        ..\linksrc\lksym.c
+               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lksym.obj ..\linksrc\lksym.c
+
+
+
+
diff --git a/as/link/mcs51/clean.mk b/as/link/mcs51/clean.mk
new file mode 100644 (file)
index 0000000..7b293ff
--- /dev/null
@@ -0,0 +1,25 @@
+# Deleting all files created by building the program
+# --------------------------------------------------
+include $(top_builddir)Makefile.common
+
+clean:
+       rm -f *core *[%~] *.[oa]
+       rm -f .[a-z]*~
+       rm -f $(top_builddir)bin/aslink$(EXEEXT) aslink$(EXEEXT)
+
+
+# Deleting all files created by configuring or building the program
+# -----------------------------------------------------------------
+distclean: clean
+       rm -f Makefile *.dep
+
+
+# Like clean but some files may still exist
+# -----------------------------------------
+mostlyclean: clean
+
+
+# Deleting everything that can reconstructed by this Makefile. It deletes
+# everything deleted by distclean plus files created by bison, etc.
+# -----------------------------------------------------------------------
+realclean: distclean
diff --git a/as/link/mcs51/conf.mk b/as/link/mcs51/conf.mk
new file mode 100644 (file)
index 0000000..e0e3431
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile targets to remake configuration
+#
+
+freshconf: Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_srcdir)/configure.in
+       cd $(top_prjdir) && $(SHELL) ./config.status
+
+# End of conf.mk
diff --git a/as/link/mcs51/lkaomf51.c b/as/link/mcs51/lkaomf51.c
new file mode 100644 (file)
index 0000000..7e65031
--- /dev/null
@@ -0,0 +1,987 @@
+/*-------------------------------------------------------------------------
+  lkaomf51.c - Create an absolute object memory format 51 file
+
+   Written By -  Jesus Calvino-Fraga, jesusc@ieee.org (2002)
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+-------------------------------------------------------------------------*/
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "aslink.h"
+
+#define EQ(A,B) !strcmp((A),(B))
+#define MEMSIZE 0x10000
+//#define DODUMP 1
+
+typedef struct
+{
+       char PathName[PATH_MAX];
+       char ModuleName[PATH_MAX];
+} _infn;
+
+int numin=0;
+_infn * infn=NULL;
+
+char ihxFileName[PATH_MAX];
+char aomf51FileName[PATH_MAX];
+
+typedef struct
+{
+   char name[0x100];
+   int FileNameNumber;
+   int Procedure;//If the symbol belongs to a function
+   int Static; //If the symbol is only public on its file
+   int Address;
+   int UsageType;
+} _symbol;
+
+int numsym=0;
+_symbol * symbol=NULL;
+
+typedef struct
+{
+   char name[0x100];
+   int FileNameNumber;
+   int BeginAdd;
+   int EndAdd;
+} _procedure;
+
+int numproc=0;
+_procedure * procedure=NULL;
+
+typedef struct
+{
+   int Number;
+   int Address;
+   int Procedure;
+   int FileNameNumber;
+} _linenum;
+
+int numlinenum=0;
+_linenum * linenum=NULL;
+#if 0
+typedef struct
+{
+       char * name;
+       int usage;
+}
+_UsageType;
+
+_UsageType UsageType[]=
+{
+       {"CSEG",                0},
+       {"GSINIT",              0},
+       {"GSINIT0",             0},
+       {"GSINIT1",             0},
+       {"GSINIT2",             0},
+       {"GSINIT3",             0},
+       {"GSINIT4",             0},
+       {"GSINIT5",             0},
+       {"GSFINAL",             0},
+       {"HOME",                0},
+       {"XINIT",               0},
+       {"XSEG",                1},
+       {"XISEG",               1},
+       {"REG_BANK_0",  2},
+       {"REG_BANK_1",  2},
+       {"REG_BANK_2",  2},
+       {"REG_BANK_3",  2},
+       {"DSEG",                2},
+       {"OSEG",                2},
+       {"SSEG",                2},
+       {"ISEG",                3},
+       {"BSEG",                4},
+       {"",                    5} /*A typeless number?*/
+};
+#endif
+char * UsageTypeName[]={"CODE", "XDATA", "DATA", "IDATA", "BIT", "NUMBER"};
+int AddNumber;
+unsigned char * ihxBuff=NULL;
+FILE * aomf51out;
+int GlobalChkSum=0;
+int HexSize, HexBegin=0x10000;
+
+
+void GetName(char * filepath, char * name)
+{
+       int j, k;
+       for(j=strlen(filepath); j>0; j--)
+               if( (filepath[j-1]=='/')||(filepath[j-1]=='\\') ) break;
+       for(k=0; (filepath[j]!=0)&&(filepath[j]!='.'); j++, k++)
+               name[k]=filepath[j];
+       name[k]=0;
+}
+
+void SaveLinkedFilePath(char * filepath) 
+{
+       int j;
+
+       if((dflag) && (!rflag))
+       {
+               infn=realloc(infn, sizeof(_infn)*(numin+1));
+
+               strcpy(infn[numin].PathName, filepath);
+               j=strlen(infn[numin].PathName);
+               
+               /*If there is an extension remove it*/
+               if(j>=4)
+               {
+                       if(EQ(&infn[numin].PathName[j-4], ".rel"))
+                       {
+                               infn[numin].PathName[j-4]=0;
+                       }
+               }
+
+               /*Get the module name=filename, no drive, no dir, no ext*/
+               GetName(infn[numin].PathName, infn[numin].ModuleName);
+               //printf("%s, %s\n", infn[numin].PathName, infn[numin].ModuleName);
+               
+               /*Check if this filename is already in*/
+               for(j=0; j<numin; j++)
+               {
+                       if(EQ(infn[numin].PathName, infn[j].PathName)) break;
+               }
+               if(j==numin) numin++;
+       }
+}
+
+void FreeAll(void)
+{
+       if(infn!=NULL)
+       {
+               free(infn);
+               numin=0;
+               infn=NULL;
+       }
+
+       if(symbol!=NULL)
+       {
+               free(symbol);
+               numsym=0;
+               symbol=NULL;
+       }
+
+       if(procedure!=NULL)
+       {
+               free(procedure);
+               numproc=0;
+               procedure=NULL;
+
+       }
+       if(linenum!=NULL)
+       {
+               free(linenum);
+               numlinenum=0;
+               linenum=NULL;
+       }
+
+       if(ihxBuff!=NULL)
+       {
+               free(ihxBuff);
+               ihxBuff=NULL;
+       }
+}
+
+void OutputByte(unsigned char value)
+{
+       GlobalChkSum+=value;
+       fwrite( &value, 1, 1, aomf51out );
+}
+
+void OutputWord(int value)
+{
+       OutputByte((unsigned char)(value%0x100));
+       OutputByte((unsigned char)(value/0x100));
+}
+
+void OutputName(char * name)
+{
+       int k;
+       OutputByte((unsigned char)strlen(name));
+       for(k=0; name[k]!=0; k++)
+               OutputByte((unsigned char)toupper(name[k]));
+}
+
+void OutputChkSum(void)
+{
+       OutputByte((unsigned char)(0x100-(GlobalChkSum%0x100)));
+       GlobalChkSum=0;
+}
+
+#ifdef DODUMP
+void DumpForDebug (void)
+{
+       char DumpFileName[PATH_MAX];
+       FILE * DumpFile;
+       int j, k;
+
+       strcpy(DumpFileName, infn[0].PathName);
+       strcat(DumpFileName, ".d51");
+
+       DumpFile=fopen(DumpFileName, "wb");
+       if(DumpFile==NULL)
+       {
+               printf("Couldn't create file %s\n", DumpFileName);
+               return;
+       }
+
+       fprintf(DumpFile,"SYMBOLS:\n");
+
+       for(j=0; j<numsym; j++)
+       {
+               k=symbol[j].UsageType&0xf;
+               fprintf(DumpFile, "%s, %s, %s, 0x%04x, %s\n",
+                       symbol[j].name,
+                       infn[symbol[j].FileNameNumber].PathName,
+                       (symbol[j].Procedure>=0)?procedure[symbol[j].Procedure].name:"GLOBAL",
+                       symbol[j].Address,
+                       k<6?UsageTypeName[k]:"???");
+       }
+       
+       fprintf(DumpFile,"\nPROCEDURES:\n");
+       for(j=0; j<numproc; j++)
+       {
+               fprintf(DumpFile, "%s, %s, 0x%04x-0x%04x\n",
+                       procedure[j].name,
+                       infn[procedure[j].FileNameNumber].PathName,
+                       procedure[j].BeginAdd,
+                       procedure[j].EndAdd);
+       }
+
+       fprintf(DumpFile,"\nLINE NUMBERS:\n");
+       for(j=0; j<numlinenum; j++)
+       {
+               fprintf(DumpFile, "%d:0x%04x, %s -> %s\n",
+                       linenum[j].Number,
+                       linenum[j].Address,
+                       infn[linenum[j].FileNameNumber].PathName,
+                       (linenum[j].Procedure>=0)?procedure[linenum[j].Procedure].name:"I don't know");
+       }
+
+       fclose(DumpFile);
+}
+#endif
+
+void OutputAOEMF51(void)
+{
+       int i, j, k, recsize;
+       char MHRname[0x100], Mname[0x100];
+
+       strcpy(aomf51FileName, infn[0].PathName);
+
+       aomf51out=fopen(aomf51FileName, "wb");
+       if(aomf51out==NULL)
+       {
+               printf("Couldn't create file %s\n", aomf51FileName);
+               return;
+       }
+
+       GetName(infn[0].PathName, MHRname);
+       GlobalChkSum=0;
+       
+       /*Module header record*/
+       OutputByte(0x02);/*REC TYPE*/
+       OutputWord((strlen(MHRname)+1)+3);/*Record Length*/
+       OutputName(MHRname);/*Module Name*/
+       OutputByte(0xff);/*TRN ID: RL51?*/
+       OutputByte(0x00);
+       OutputChkSum();
+
+       for(j=0; j<numin; j++)
+       {
+               GetName(infn[j].PathName, Mname);
+
+               /*Scope Definition record: begin module block*/
+               OutputByte(0x10);/*REC TYPE*/
+               OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+               OutputByte(0x00);/*BLK TYP: module block*/
+               OutputName(Mname);/*Module Name*/
+               OutputChkSum();
+
+               /*Public symbols defined in this module*/
+               recsize=2;
+               for(k=0; k<numsym; k++)/*Compute the record length*/
+                       if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+                                (symbol[k].Procedure==-1) &&
+                                (symbol[k].Static==-1) ) recsize+=((strlen(symbol[k].name)+1)+5);
+
+               if(recsize>2) /*If there are any symbols*/
+               {
+                       OutputByte(0x12);       /*REC TYPE*/
+                       OutputWord(recsize);/*Record Length*/
+                       OutputByte(0x01);       /*DEF TYPE: Public symbols*/
+                       for(k=0; k<numsym; k++)
+                       {
+                               if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+                                        (symbol[k].Procedure==-1) &&
+                                        (symbol[k].Static==-1) )
+                               {
+                                       OutputByte(0x00);/*SEG ID*/
+                                       OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
+                                       OutputWord(symbol[k].Address);/*Offset*/
+                                       OutputByte(0x00);
+                                       OutputName(symbol[k].name);/*Symbol name*/
+                               }
+                       }
+                       OutputChkSum();
+               }
+
+               /*Local symbols defined in this module*/
+               recsize=2;
+               for(k=0; k<numsym; k++)/*Compute the record length*/
+                       if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+                                (symbol[k].Procedure==-1) &&
+                                (symbol[k].Static==j) ) recsize+=((strlen(symbol[k].name)+1)+5);
+
+               if(recsize>2) /*If there are any symbols*/
+               {
+                       OutputByte(0x12);       /*REC TYPE*/
+                       OutputWord(recsize);/*Record Length*/
+                       OutputByte(0x00);       /*DEF TYPE: Local symbols*/
+                       for(k=0; k<numsym; k++)
+                       {
+                               if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
+                                        (symbol[k].Procedure==-1) &&
+                                        (symbol[k].Static==j) )
+                               {
+                                       OutputByte(0x00);/*SEG ID*/
+                                       OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
+                                       OutputWord(symbol[k].Address);/*Offset*/
+                                       OutputByte(0x00);
+                                       OutputName(symbol[k].name);/*Symbol name*/
+                               }
+                       }
+                       OutputChkSum();
+               }
+
+               /*Output the procedures of this module*/
+
+               for(k=0; k<numproc; k++)
+               {
+                       if(procedure[k].FileNameNumber==j)
+                       {
+                               /*Scope Definition record: begin PROCEDURE block*/
+                               OutputByte(0x10);/*REC TYPE*/
+                               OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
+                               OutputByte(0x02);/*BLK TYP: PROCEDURE block*/
+                               OutputName(procedure[k].name);/*Module Name*/
+                               OutputChkSum();
+
+                               /*Content Record*/
+                               OutputByte(0x06);/*REC TYPE*/
+                               if(procedure[k].EndAdd==-1) procedure[k].EndAdd=HexSize;
+                               recsize=procedure[k].EndAdd-procedure[k].BeginAdd+1+4;
+                               OutputWord(recsize);/*Record Length*/
+                               OutputByte(0x00);/*SEG ID*/
+                               OutputWord(procedure[k].BeginAdd); /*Offset*/
+                               for(i=procedure[k].BeginAdd; i<=procedure[k].EndAdd; i++)
+                                       OutputByte(ihxBuff[i]);
+                               OutputChkSum();
+
+                               /*Local Symbols*/
+                               
+                               recsize=2;
+                               for(i=0; i<numsym; i++)/*Get the record length*/
+                                       if(symbol[i].Procedure==k)
+                                               recsize+=((strlen(symbol[i].name)+1)+5);
+
+                               if(recsize>2) /*If there are any symbols*/
+                               {
+                                       OutputByte(0x12);       /*REC TYPE*/
+                                       OutputWord(recsize);/*Record Length*/
+                                       OutputByte(0x00);       /*DEF TYPE: Local symbols*/
+                                       for(i=0; i<numsym; i++)
+                                       {
+                                               if ( (symbol[i].Procedure==k) )
+                                               {
+                                                       OutputByte(0x00);/*SEG ID*/
+                                                       OutputByte((unsigned char)symbol[i].UsageType);/*SYM INFO*/
+                                                       OutputWord(symbol[i].Address);/*Offset*/
+                                                       OutputByte(0x00);
+                                                       OutputName(symbol[i].name);/*Symbol name*/
+                                               }
+                                       }
+                                       OutputChkSum();
+                               }
+
+                               /*Line Numbers*/
+                               recsize=2;
+                               for(i=0; i<numlinenum; i++)/*Get the record length*/
+                                       if(linenum[i].Procedure==k) recsize+=5;
+                               
+                               if(recsize>2) /*If there are any line numbers*/
+                               {
+                                       OutputByte(0x12);       /*REC TYPE*/
+                                       OutputWord(recsize);/*Record Length*/
+                                       OutputByte(0x03);       /*DEF TYPE: Line numbers*/
+                                       for(i=0; i<numlinenum; i++)
+                                       {
+                                               if ( (linenum[i].Procedure==k) )
+                                               {
+                                                       OutputByte(0x00);/*SEG ID*/
+                                                       OutputWord(linenum[i].Address);/*Offset*/
+                                                       OutputWord(linenum[i].Number);/*Line Number*/
+                                               }
+                                       }
+                                       OutputChkSum();
+                               }
+                       
+                               /*Scope Definition record: end PROCEDURE block*/
+                               OutputByte(0x10);/*REC TYPE*/
+                               OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
+                               OutputByte(0x05);/*BLK TYP: PROCEDURE end block*/
+                               OutputName(procedure[k].name);/*Module Name*/
+                               OutputChkSum();
+                       }
+               }
+
+               /*Scope Definition record: end module block*/
+               OutputByte(0x10);/*REC TYPE*/
+               OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+               OutputByte(0x03);/*BLK TYP: module end*/
+               OutputName(Mname);/*Module Name*/
+               OutputChkSum();
+       }
+
+       /*Content records for everything that is not in the above procedures*/
+       strcpy(Mname, "OTHER_SDCC_STUF");
+
+       /*Scope Definition record: begin module block*/
+       OutputByte(0x10);/*REC TYPE*/
+       OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+       OutputByte(0x00);/*BLK TYP: module block*/
+       OutputName(Mname);/*Module Name*/
+       OutputChkSum();
+
+       for(j=-1; j<numproc; j++)
+       {
+               if(numproc)
+               {
+                       if(j==-1)
+                       {
+                               i=HexBegin;
+                               k=procedure[0].BeginAdd;
+                       }
+                       else if(j==(numproc-1))
+                       {
+                               i=procedure[j].EndAdd+1;
+                               k=HexSize;
+                       }
+                       else
+                       {
+                               i=procedure[j].EndAdd+1;
+                               k=procedure[j+1].BeginAdd;
+                       }
+               }
+               else /*What, no procedures??? Ok, here it is the whole hex file*/
+               {
+                       i=HexBegin;
+                       k=HexSize;
+               }
+
+               if(i<k)
+               {
+                       /*Content Record*/
+                       OutputByte(0x06);/*REC TYPE*/
+                       OutputWord(k-i+4);/*Record Length*/
+                       OutputByte(0x00);/*SEG ID*/
+                       OutputWord(i); /*Offset*/
+                       for(; i<k; i++) OutputByte(ihxBuff[i]);
+                       OutputChkSum();
+               }
+       }
+       
+       /*Scope Definition record: end module block*/
+       OutputByte(0x10);/*REC TYPE*/
+       OutputWord((strlen(Mname)+1)+2);/*Record Length*/
+       OutputByte(0x03);/*BLK TYP: module end*/
+       OutputName(Mname);/*Module Name*/
+       OutputChkSum();
+
+       /*Module end record*/
+       OutputByte(0x04);/*REC TYPE*/
+       OutputWord((strlen(MHRname)+1)+5);/*Record Length*/
+       OutputName(MHRname);/*Module Name*/
+       OutputWord(0x00);
+       OutputByte(0x0f);/*REG MSK: All the register banks?*/
+       OutputByte(0x00);
+       OutputChkSum();
+
+       fclose(aomf51out);
+}
+
+void CollectInfoFromCDB(void)
+{
+       int i, j, k, CurrentModule;
+       FILE * CDBin;
+       char buff[0x1000];
+       char SourceName[PATH_MAX];
+
+       //"S:{G|F<filename>|L<functionName>}$<name>$<level>$<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>"
+       char Sfmt[]="%[^$] %c %[^$] %c %[^$] %c %s";
+       char c;
+       char scope[0x100];
+       char name[0x100];
+       char level[0x100];
+       char block[0x100];
+       char Bfmt[]="%[^)] %c %c %c %c %d %c %d";
+       char TypeInfo[0x100];
+       char AddressSpace;
+       int OnStack;
+       int StackOffset;
+       int Address, CLine;
+       
+       if(numin==0) return;
+
+       if (dfp != NULL)
+       {
+               fclose(dfp);
+               dfp=NULL;
+       }
+
+       /*Build the source filename*/
+       strcpy(SourceName, infn[0].PathName);
+       strcat(SourceName, ".cdb");
+       CDBin=fopen(SourceName, "r");
+       if(CDBin==NULL)
+       {
+               printf("Couldn't open file '%s'\n", SourceName);
+               lkexit(1);
+       }
+
+       CurrentModule=0; /*Set the active module as the first one*/
+       while(!feof(CDBin))
+       {
+               fgets(buff, sizeof(buff)-1, CDBin);
+
+               if(!feof(CDBin)) switch(buff[0])
+               {
+                       /*Example: "M:adq"*/
+                       case 'M':
+                               sscanf(&buff[2], "%s", name);
+                               for(j=0; j<numin; j++)
+                                       if(EQ(infn[j].ModuleName, name)) break;
+                               if(j<numin) CurrentModule=j;
+                       break;
+
+                       /* Example:
+                       "S:G$actual$0$0({7}ST__00010000:S),E,0,0"
+                       "S:Lmain$j$1$1({2}SI:S),E,0,0"
+                       "S:G$DS1306_Reset_SPI$0$0({2}DF,SV:S),C,0,0"
+                       "S:G$main$0$0({2}DF,SV:S),C,0,0"
+                       */
+
+                       case 'S':
+                               sscanf(buff, Sfmt,
+                                       scope, &c,
+                                       name, &c,
+                                       level, &c,
+                                       block);
+                               
+                               /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>*/
+                               sscanf(block, Bfmt,
+                                          TypeInfo, &c, &c,
+                                          &AddressSpace, &c,
+                                          &OnStack, &c, 
+                                          &StackOffset);
+
+                               i=-1; k=-1;
+                               switch(scope[2])
+                               {
+                                       case 'G': /*Global symbol*/
+                                       break;
+                                       case 'L': /*Local symbol of a procedure*/
+                                               for(j=0; j<numproc; j++)
+                                               {
+                                                       if(EQ(&scope[3], procedure[j].name)) break;
+                                               }
+                                               if(j<numproc) k=j; /*Local symbol*/
+                                       break;
+                                       case 'F': /*Local symbol to a module*/
+                                               for(j=0; j<numin; j++)
+                                               {
+                                                       if(EQ(&scope[3], infn[j].ModuleName)) break;
+                                               }
+                                               if(j<numin) i=j;
+                                       break;
+                               }
+
+                               /*This symbol may have been already defined*/
+                               for(j=0; j<numsym; j++)
+                               {
+                                       if( EQ(name, symbol[j].name) && 
+                                               (symbol[j].Procedure==k) &&
+                                               (symbol[j].Static==i) ) break;
+                               }
+                               if(j==numsym) /*New symbol*/
+                               {
+                                       symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
+                                       symbol[numsym].FileNameNumber=CurrentModule;
+                                       strcpy(symbol[numsym].name, name);
+                                       symbol[numsym].Procedure=k;
+                                       symbol[numsym].Static=i;
+                                       symbol[numsym].Address=-1;/*Collected later*/
+
+                                       switch(AddressSpace)
+                                       {
+                                               case 'C': /*Code*/ 
+                                               case 'D': /*Code/static segment*/ 
+                                               case 'Z': /*Functions and undefined code space*/ 
+                                                       symbol[numsym].UsageType=0x40;
+                                               break;
+
+                                               case 'F': /*External ram*/ 
+                                               case 'A': /*External stack*/
+                                                       symbol[numsym].UsageType=0x41;
+                                               break;
+
+                                               case 'E': /*Internal ram (lower 128) bytes*/ 
+                                               case 'I': /*SFR space*/ 
+                                               case 'R': /*Register Space*/ 
+                                                       symbol[numsym].UsageType=0x42;
+                                               break;
+
+                                               case 'B': /*Internal stack*/ 
+                                               case 'G': /*Internal ram*/ 
+                                                       symbol[numsym].UsageType=0x43;
+                                               break;
+
+                                               case 'H': /*Bit addressable*/ 
+                                               case 'J': /*SBIT space*/ 
+                                                       symbol[numsym].UsageType=0x44;
+                                               break;
+                                               
+                                               default:
+                                                       printf("Unknown scope information for: %s, AddressSpace:%c\n", symbol[numsym].name, AddressSpace);
+                                               break;
+                                       }
+                                       numsym++;
+                               }
+                       break;
+
+                       /*Examples:
+                       F:G$AsciiToHex$0$0({2}DF,SC:U),C,0,0,0,0,0
+                       F:G$main$0$0({2}DF,SV:S),C,0,0,0,0,0   */
+
+                       case 'F':
+                               sscanf(buff, "%[^$] %c %[^$]", scope, &c, name);
+                               /*The same may have been already defined */
+                               for(j=0; j<numproc; j++)
+                               {
+                                       if(EQ(name, procedure[j].name)) break;
+                               }
+                               if(j==numproc)
+                               {
+                                       procedure=realloc(procedure, sizeof(_procedure)*(numproc+1));
+                                       strcpy(procedure[numproc].name, name);
+                                       procedure[numproc].FileNameNumber=CurrentModule;
+                                       procedure[numproc].BeginAdd=-1;/*To be collected latter*/
+                                       procedure[numproc].EndAdd=-1;/*To be collected latter*/
+                                       numproc++;
+                               }
+                               
+                               /*This function name is also a global symbol*/
+                               for(j=0; j<numsym; j++)/*A global symbol may have been already defined*/
+                               {
+                                       if( EQ(name, symbol[j].name) && (symbol[j].Procedure==-1) ) break;
+                               }
+                               if(j==numsym)
+                               {
+                                       symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
+                                       symbol[numsym].FileNameNumber=CurrentModule;
+                                       strcpy(symbol[numsym].name, name);
+                                       symbol[numsym].UsageType=0x00;/*A procedure name symbol*/
+                                       symbol[numsym].Procedure=-1; /*Global symbol*/
+                                       symbol[numsym].Address=-1;/*Collected later*/
+                                       symbol[numsym].Static=-1; // o_gloom
+                                       numsym++;
+                               }
+                       break;
+
+                       case 'L':
+                               switch(buff[2])
+                               {
+                                       case 'G': /*Example L:G$P0$0$0:80*/
+                                               sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
+                                                       scope, &c, name, &c, level, &c, &Address);
+
+                                               for(j=0; j<numsym; j++)
+                                               {
+                                                       if(EQ(symbol[j].name, name))
+                                                       {
+                                                               if( (symbol[j].Address==-1) && (symbol[j].Procedure==-1) )
+                                                               {
+                                                                       symbol[j].Address=Address;
+                                                               }
+                                                               
+                                                               /*If the symbol is the name of a procedure, the address is also
+                                                               the begining of such procedure*/
+                                                               if((symbol[j].UsageType&0x0f)==0x00)
+                                                               {
+                                                                       for(k=0; k<numproc; k++)
+                                                                       {
+                                                                               if(EQ(symbol[j].name, procedure[k].name))
+                                                                               {
+                                                                                       if(procedure[k].BeginAdd==-1)
+                                                                                               procedure[k].BeginAdd=Address;
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               
+                                                               break;
+                                                       }
+                                               }
+                                       break;
+                                       
+                                       case 'F': /*Example L:Fadq$_str_2$0$0:57A*/
+                                               sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
+                                                       scope, &c, name, &c, level, &c, &Address);
+                                               
+                                               for(j=0; j<numsym; j++)
+                                               {
+                                                       if(EQ(symbol[j].name, name))
+                                                       {
+                                                               if( (symbol[j].Address==-1) ) symbol[j].Address=Address;
+                                                               break;
+                                                       }
+                                               }
+                                               
+                                               /*It could be also a static function*/
+                                               for(j=0; j<numproc; j++)
+                                               {
+                                                       if(EQ(procedure[j].name, name))
+                                                       {
+                                                               if( (procedure[j].BeginAdd==-1) ) procedure[j].BeginAdd=Address;
+                                                               break;
+                                                       }
+                                               }
+
+                                       break;
+                                       
+                                       case 'L': /*Example L:Lmain$j$1$1:29*/
+
+                                               /*
+                                               L:LDS1306_Write$Value$1$1:34
+                                               L:LDS1306_Burst_Read$count$1$1:35
+                                               L:LDS1306_Burst_Read$address$1$1:36
+                                               L:LDS1306_Burst_Write$count$1$1:37
+                                               L:LDS1306_Burst_Write$address$1$1:38
+                                               */
+                                               sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
+                                                       scope, &c, name, &c, level, &c, &Address);
+                                               
+                                               for(k=0; k<numproc; k++)
+                                               {
+                                                       if(EQ(procedure[k].name, scope)) break;
+                                               }
+                                               
+                                               if(k<numproc) for(j=0; j<numsym; j++)
+                                               {
+                                                       if( EQ(symbol[j].name, name) && (symbol[j].Procedure==k) )
+                                                       {
+                                                               if(symbol[j].Address==-1) symbol[j].Address=Address;
+                                                               break;
+                                                       }
+                                               }
+                                       break;
+                                       
+                                       /*Line Numbers*/
+                                       case 'C': /*Example L:C$adq.c$38$1$1:3E*/  /*L:C$hwinit.c$29$1$1:7AD*/
+                                               sscanf(&buff[4], "%[^.] %[^$] %c %d %[^:] %c %x",
+                                                       name, level, &c, &CLine, level, &c, &Address);
+
+                                               for(j=0; j<numin; j++)
+                                                       if(EQ(infn[j].ModuleName, name)) break;
+                                               if(j<numin)
+                                               {
+                                                       /*Check if this line is already defined*/
+                                                       for(k=0; k<numlinenum; k++)
+                                                       {
+                                                               if( (linenum[k].Number==CLine) &&
+                                                                       (linenum[k].FileNameNumber==j) )break;
+                                                       }
+                                                       if(k==numlinenum) /*New line number*/
+                                                       {
+                                                               linenum=realloc(linenum, sizeof(_linenum)*(numlinenum+1));
+                                                               linenum[numlinenum].Number=CLine;
+                                                               linenum[numlinenum].FileNameNumber=j;
+                                                               linenum[numlinenum].Procedure=-1;/*To be asigned later*/
+                                                               linenum[numlinenum].Address=Address;
+                                                               numlinenum++;
+                                                       }
+                                               }
+                                       break;
+                                       
+                                       case 'A': /*Example L:A$adq$424:40*/
+                                               /*No use for this one*/
+                                       break;
+                                       
+                                       /*The end of a procedure*/
+                                       case 'X': /*Example L:XG$AsciiToHex$0$0:88*/
+                                               sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
+                                                       scope, &c, name, &c, level, &c, &Address);
+
+                                               for(k=0; k<numproc; k++)
+                                               {
+                                                       if(EQ(procedure[k].name, name))
+                                                       {
+                                                               if(procedure[k].EndAdd==-1) procedure[k].EndAdd=Address;
+                                                               break;
+                                                       }
+                                               }
+                                       break;
+                               }
+                       break;
+
+                       default:
+                       break;
+               }
+       }
+
+       /*Make sure each procedure has an end*/
+       for(k=0; k<(numproc-1); k++)
+       {
+               if (procedure[k].EndAdd==-1) procedure[k].EndAdd=procedure[k+1].BeginAdd-1;
+       }
+       /*Asign each line number to a procedure*/
+       for(j=0; j<numlinenum; j++)
+       {
+               for(k=0; k<numproc; k++)
+               {
+                       if ( (linenum[j].Address>=procedure[k].BeginAdd) &&
+                                (linenum[j].Address<=procedure[k].EndAdd) &&
+                                (linenum[j].FileNameNumber==procedure[k].FileNameNumber) )
+                       {
+                               linenum[j].Procedure=k;
+                       }
+               }
+       }
+
+       fclose(CDBin);
+}
+
+int hex2dec (unsigned char hex_digit)
+{
+   if (isdigit (hex_digit))
+      return hex_digit-'0';
+   else
+      return toupper (hex_digit)-'A'+10;
+}
+
+unsigned char GetByte(char * buffer)
+{
+       return hex2dec(buffer[0])*0x10+hex2dec(buffer[1]);
+}
+
+unsigned short GetWord(char * buffer)
+{
+       return  hex2dec(buffer[0])*0x1000+
+                       hex2dec(buffer[1])*0x100+
+                       hex2dec(buffer[2])*0x10+
+                       hex2dec(buffer[3]);
+}
+
+int ReadHexFile(int * Begin)
+{
+       char buffer[1024];
+       FILE * filein;
+       int j;
+       unsigned char linesize, recordtype, rchksum, value;
+       unsigned short address;
+       int MaxAddress=0;
+       int chksum;
+
+       /*If the hexfile is already open, close it*/
+       if(ofp!=NULL)
+       {
+               fclose(ofp);
+               ofp=NULL;
+       }
+       
+       strcpy(ihxFileName, infn[0].PathName);
+       strcat(ihxFileName, ".ihx");
+
+       if ( (filein=fopen(ihxFileName, "r")) == NULL )
+       {
+          printf("Error: Can't open file `%s`.\r\n", ihxFileName);
+          return 0;
+       }
+   
+       ihxBuff=calloc(MEMSIZE, sizeof(unsigned char));
+       if(ihxBuff==NULL)
+       {
+               printf("Insufficient memory\n");
+               fclose(filein);
+               return -1;
+       }
+
+       for(j=0; j<MEMSIZE; j++) ihxBuff[j]=0xff;
+
+    while(1)
+    {
+               if(fgets(buffer, sizeof(buffer), filein)==NULL)
+               {
+                       printf("Error reading file '%s'\n", ihxFileName);
+                       break;
+               }
+       if(buffer[0]==':')
+       {
+                       linesize = GetByte(&buffer[1]);
+                       address = GetWord(&buffer[3]);
+                       recordtype = GetByte(&buffer[7]);
+                       rchksum = GetByte(&buffer[9]+(linesize*2));
+                       chksum=linesize+(address/0x100)+(address%0x100)+recordtype+rchksum;
+
+                       if (recordtype==1) break; /*End of record*/
+
+                       for(j=0; j<linesize; j++)
+                       {
+                               value=GetByte(&buffer[9]+(j*2));
+                               chksum+=value;
+                               ihxBuff[address+j]=value;
+                       }
+                       if(MaxAddress<(address+linesize-1)) MaxAddress=(address+linesize-1);
+                       if(address<*Begin) *Begin=address;
+
+                       if((chksum%0x100)!=0)
+                       {
+                               printf("ERROR: Bad checksum in file %s\n", ihxFileName);
+                               fclose(filein);
+                               return -1;
+                       }
+               }
+    }
+    fclose(filein);
+       
+    return MaxAddress;
+}
+
+void CreateAOMF51(void)
+{
+       if((dflag) && (!rflag))
+       {
+               CollectInfoFromCDB();
+               #ifdef DODUMP
+               DumpForDebug();
+               #endif
+               HexSize=ReadHexFile(&HexBegin)+1;
+               OutputAOEMF51();
+               FreeAll();
+       }
+}
diff --git a/as/link/mcs51/lkarea.c b/as/link/mcs51/lkarea.c
new file mode 100644 (file)
index 0000000..96a9130
--- /dev/null
@@ -0,0 +1,1079 @@
+/* lkarea.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ *  3-Nov-97 JLH:
+ *           - change lkparea to use a_type == 0 as "virgin area" flag
+ * 02-Apr-98 JLH: add code to link 8051 data spaces
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module   lkarea.c
+ *
+ *  The module lkarea.c contains the functions which
+ *  create and link together all area definitions read
+ *  from the .rel file(s).
+ *
+ *  lkarea.c contains the following functions:
+ *      VOID    lnkarea()
+ *      VOID    lnksect()
+ *      VOID    lkparea()
+ *      VOID    newarea()
+ *
+ *  lkarea.c contains no global variables.
+ */
+
+/*)Function VOID    newarea()
+ *
+ *  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 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
+ *  into the area flag variable.  For each occurence of
+ *  an A directive an areax structure is created and
+ *  linked to the areax structures associated with this
+ *  area.  The size of this area section is placed into
+ *  the areax structure.  The flag value for all subsequent
+ *  area definitions for the same area are compared and
+ *  flagged as an error if they are not identical.
+ *  The areax structure created for every occurence of
+ *  an A directive is loaded with a pointer to the base
+ *  area structure and a pointer to the associated
+ *  head structure.  And finally, a pointer to this
+ *  areax structure is loaded into the list of areax
+ *  structures in the head structure.  Refer to lkdata.c
+ *  for details of the structures and their linkage.
+ *
+ *  local variables:
+ *      areax **halp        pointer to an array of pointers
+ *      int     i           counter, loop variable, value
+ *      char    id[]        id string
+ *      int     narea       number of areas in this head structure
+ *      areax * taxp        pointer to an areax structure
+ *                          to areax structures
+ *
+ *  global variables:
+ *      area    *ap         Pointer to the current
+ *                          area structure
+ *      areax   *axp        Pointer to the current
+ *                          areax structure
+ *      head    *hp         Pointer to the current
+ *                          head structure
+ *      int     lkerr       error flag
+ *
+ *  functions called:
+ *      Addr_T  eval()      lkeval.c
+ *      VOID    exit()      c_library
+ *      int     fprintf()   c_library
+ *      VOID    getid()     lklex.c
+ *      VOID    lkparea()   lkarea.c
+ *      VOID    skip()      lklex.c
+ *
+ *  side effects:
+ *      The area and areax structures are created and
+ *      linked with the appropriate head structures.
+ *      Failure to allocate area or areax structure
+ *      space will terminate the linker.  Other internal
+ *      errors most likely caused by corrupted .rel
+ *      files will also terminate the linker.
+ */
+
+/*
+ * Create an area entry.
+ *
+ * A xxxxxx size nnnn flags mm
+ *   |           |          |
+ *   |           |          `--  ap->a_flag
+ *   |           `------------- axp->a_size
+ *   `-------------------------  ap->a_id
+ *
+ */
+VOID
+newarea()
+{
+    register int i, narea;
+    struct areax *taxp;
+    struct areax **halp;
+    char id[NCPS];
+
+    /*
+     * Create Area entry
+     */
+    getid(id, -1);
+    lkparea(id);
+    /*
+     * Evaluate area size
+     */
+    skip(-1);
+    axp->a_size = eval();
+    /*
+     * Evaluate flags
+     */
+    skip(-1);
+    i = 0;
+    taxp = ap->a_axp;
+    while (taxp->a_axp) {
+        ++i;
+        taxp = taxp->a_axp;
+    }
+    if (i == 0) {
+        ap->a_flag = eval();
+    } else {
+        i = eval();
+/*      if (i && (ap->a_flag != i)) { */
+/*          fprintf(stderr, "Conflicting flags in area %8s\n", id); */
+/*          lkerr++; */
+/*      } */
+    }
+    /*
+     * Evaluate area address
+     */
+    skip(-1);
+    axp->a_addr = eval();
+    /*
+     * Place pointer in header area list
+     */
+    if (headp == NULL) {
+        fprintf(stderr, "No header defined\n");
+        lkexit(1);
+    }
+    narea = hp->h_narea;
+    halp = hp->a_list;
+    for (i=0; i < narea ;++i) {
+        if (halp[i] == NULL) {
+            halp[i] = taxp;
+            return;
+        }
+    }
+    fprintf(stderr, "Header area list overflow\n");
+    lkexit(1);
+}
+
+/*)Function VOID    lkparea(id)
+ *
+ *      char *  id      pointer to the area name string
+ *
+ *  The function lkparea() searches the linked area structures
+ *  for a name match.  If the name is not found then an area
+ *  structure is created.  An areax structure is created and
+ *  appended to the areax structures linked to the area structure.
+ *  The associated base area and head structure pointers are
+ *  loaded into the areax structure.
+ *
+ *  local variables:
+ *      area *  tap         pointer to an area structure
+ *      areax * taxp        pointer to an areax structure
+ *
+ *  global variables:
+ *      area    *ap         Pointer to the current
+ *                          area structure
+ *      area    *areap      The pointer to the first
+ *                          area structure of a linked list
+ *      areax   *axp        Pointer to the current
+ *                          areax structure
+ *
+ *  functions called:
+ *      VOID *  new()       lksym()
+ *      char *  strcpy()    c_library
+ *      int     symeq()     lksym.c
+ *
+ *  side effects:
+ *      Area and/or areax structures are created.
+ *      Failure to allocate space for created structures
+ *      will terminate the linker.
+ */
+
+VOID
+lkparea(char *id)
+{
+    register struct area *tap;
+    register struct areax *taxp;
+
+    ap = areap;
+    axp = (struct areax *) new (sizeof(struct areax));
+    axp->a_addr = -1; /* default: no address yet */
+    while (ap) {
+        if (symeq(id, ap->a_id)) {
+            taxp = ap->a_axp;
+            while (taxp->a_axp)
+                taxp = taxp->a_axp;
+            taxp->a_axp = axp;
+            axp->a_bap = ap;
+            axp->a_bhp = hp;
+            return;
+        }
+        ap = ap->a_ap;
+    }
+    ap = (struct area *) new (sizeof(struct area));
+    if (areap == NULL) {
+        areap = ap;
+    } else {
+        tap = areap;
+        while (tap->a_ap)
+            tap = tap->a_ap;
+        tap->a_ap = ap;
+    }
+    ap->a_axp = axp;
+    axp->a_bap = ap;
+    axp->a_bhp = hp;
+    strncpy(ap->a_id, id, NCPS);
+    ap->a_addr = 0;
+}
+
+/*)Function VOID    lnkarea()
+ *
+ *  The function lnkarea() resolves all area addresses.
+ *  The function evaluates each area structure (and all
+ *  the associated areax structures) in sequence.  The
+ *  linking process supports four (4) possible area types:
+ *
+ *  ABS/OVR -   All sections (each individual areax
+ *          section) starts at the identical base
+ *          area address overlaying all other
+ *          areax sections for this area.  The
+ *          size of the area is largest of the area
+ *          sections.
+ *
+ *  ABS/CON -   All sections (each individual areax
+ *          section) are concatenated with the
+ *          first section starting at the base
+ *          area address.  The size of the area
+ *          is the sum of the section sizes.
+ *
+ *  NOTE:   Multiple absolute (ABS) areas are
+ *          never concatenated with each other,
+ *          thus absolute area A and absolute area
+ *          B will overlay each other if they begin
+ *          at the same location (the default is
+ *          always address 0 for absolute areas).
+ *
+ *  REL/OVR -   All sections (each individual areax
+ *          section) starts at the identical base
+ *          area address overlaying all other
+ *          areax sections for this area.  The
+ *          size of the area is largest of the area
+ *          sections.
+ *
+ *  REL/CON -   All sections (each individual areax
+ *          section) are concatenated with the
+ *          first section starting at the base
+ *          area address.  The size of the area
+ *          is the sum of the section sizes.
+ *
+ *  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
+ *          starting address of area A.  Within a
+ *          specific area each areax section may be
+ *          overlayed or concatenated with other
+ *          areax sections.
+ *
+ *
+ *  If a base address for an area is specified then the
+ *  area will start at that address.  Any relocatable
+ *  areas defined subsequently will be concatenated to the
+ *  previous relocatable area if it does not have a base
+ *  address specified.
+ *
+ *  The names s_<areaname> and l_<areaname> are created to
+ *  define the starting address and length of each area.
+ *
+ *  local variables:
+ *      Addr_T  rloc        ;current relocation address
+ *      char    temp[]      ;temporary string
+ *      struct symbol   *sp ;symbol structure
+ *
+ *  global variables:
+ *      area    *ap         Pointer to the current
+ *                          area structure
+ *      area    *areap      The pointer to the first
+ *                          area structure of a linked list
+ *
+ *  functions called:
+ *      int     fprintf()   c_library
+ *      VOID    lnksect()   lkarea.c
+ *      symbol *lkpsym()    lksym.c
+ *      char *  strncpy()   c_library
+ *      int     symeq()     lksym.c
+ *
+ *  side effects:
+ *      All area and areax addresses and sizes are
+ *      determined and saved in their respective
+ *      structures.
+ */
+
+/*
+ * Resolve all area addresses.
+ */
+VOID
+lnkarea()
+{
+    Addr_T rloc[4];
+    int  locIndex;
+    char temp[NCPS];
+    struct sym *sp;
+    /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
+    struct area *ta[5];
+    int j;
+
+    rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0;
+    ap = areap;
+    while (ap) {
+        if (ap->a_flag&A_ABS) {
+            /*
+             * Absolute sections
+             */
+            lnksect(ap);
+        } else {
+            /* Determine memory space */
+            locIndex = 0;
+            if (ap->a_flag & A_CODE) {
+                locIndex = 1;
+            }
+            if (ap->a_flag & A_XDATA) {
+                locIndex = 2;
+            }
+            if (ap->a_flag & A_BIT) {
+                locIndex = 3;
+            }
+            /*
+             * Relocatable sections
+             */
+            if (ap->a_type == 0) {  /* JLH */
+                ap->a_addr = rloc[ locIndex ];
+                ap->a_type = 1;
+            }
+            lnksect(ap);
+            rloc[ locIndex ] = ap->a_addr + ap->a_size;
+        }
+
+        /*
+         * Create symbols called:
+         *  s_<areaname>    the start address of the area
+         *  l_<areaname>    the length of the area
+         */
+
+        if (! symeq(ap->a_id, _abs_)) {
+            strncpy(temp+2,ap->a_id,NCPS-2);
+            *(temp+1) = '_';
+
+            *temp = 's';
+            sp = lkpsym(temp, 1);
+            sp->s_addr = ap->a_addr ;
+            /* sp->s_axp = ap->a_axp;  JLH: was NULL; */
+            sp->s_type |= S_DEF;
+
+            *temp = 'l';
+            sp = lkpsym(temp, 1);
+            sp->s_addr = ap->a_size;
+            sp->s_axp = NULL;
+            sp->s_type |= S_DEF;
+
+        }
+
+        /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
+        to compute the byte size of BSEG_BYTES: */
+        if (!strcmp(ap->a_id, "BSEG")) {
+            ap->a_ap->a_axp->a_size += ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
+        }
+        else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
+        else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
+        else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
+        else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
+        else if (!strcmp(ap->a_id, "BSEG_BYTES"))
+        {
+            ta[4]=ap;
+            for(j=4; j>1; j--)
+            {
+                /*If upper register banks are not used roll back the relocation counter*/
+                if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
+                {
+                    rloc[0]-=8;
+                }
+                else break;
+            }
+        }
+        ap = ap->a_ap;
+    }
+}
+
+/*)Function VOID    lnksect()
+ *
+ *      area *  tap         pointer to an area structure
+ *
+ *  The function lnksect() is the function called by
+ *  lnkarea() to resolve the areax addresses.  Refer
+ *  to the function lnkarea() for more detail. Pageing
+ *  boundary and length errors will be reported by this
+ *  function.
+ *
+ *  local variables:
+ *      Addr_T  size        size of area
+ *      Addr_T  addr        address of area
+ *      areax * taxp        pointer to an areax structure
+ *
+ *  global variables:
+ *      int     lkerr       error flag
+ *
+ *  functions called:
+ *      none
+ *
+ *  side effects:
+ *      All area and areax addresses and sizes area determined
+ *      and linked into the structures.
+ */
+
+VOID
+lnksect(register struct area *tap)
+{
+    register Addr_T size, addr;
+    register struct areax *taxp;
+
+    size = 0;
+    addr = tap->a_addr;
+#if 0
+    if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
+        fprintf(stderr,
+        "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+        lkerr++;
+    }
+#endif
+    taxp = tap->a_axp;
+    if (tap->a_flag&A_OVR) {
+        /*
+         * Overlayed sections
+         */
+        while (taxp) {
+            taxp->a_addr = addr;
+            if (taxp->a_size > size)
+                size = taxp->a_size;
+            taxp = taxp->a_axp;
+        }
+    } else {
+        /*
+         * Concatenated sections
+         */
+        while (taxp) {
+            taxp->a_addr = addr;
+            addr += taxp->a_size;
+            size += taxp->a_size;
+            taxp = taxp->a_axp;
+        }
+    }
+    tap->a_size = size;
+    if ((tap->a_flag&A_PAG) && (size > 256)) {
+        fprintf(stderr,
+        "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
+        lkerr++;
+    }
+    if ((tap->a_flag&A_PAG) && (tap->a_size) &&
+        ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
+    {
+        fprintf(stderr,
+        "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+        lkerr++;
+    }
+}
+
+Addr_T lnksect2 (struct area *tap, int locIndex);
+char idatamap[256];
+unsigned long codemap[524288];
+unsigned long xdatamap[131072];
+
+/*Modified version of the functions for packing variables in internal data memory*/
+VOID lnkarea2 (void)
+{
+    Addr_T rloc[4]={0, 0, 0, 0};
+    Addr_T gs_size = 0;
+    int  locIndex;
+    char temp[NCPS];
+    struct sym *sp;
+    int j;
+    struct area *dseg_ap = NULL;
+    struct area *abs_ap = NULL;
+    struct area *gs0_ap = NULL;
+    struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
+
+    for(j=0; j<256; j++) idatamap[j]=' ';
+    memset(codemap, 0, sizeof(codemap));
+    memset(xdatamap, 0, sizeof(xdatamap));
+
+    /* 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;
+
+    ap = areap;
+    while (ap)
+    {
+        /* Determine memory space */
+             if (ap->a_flag & A_CODE)  locIndex = 1;
+        else if (ap->a_flag & A_XDATA) locIndex = 2;
+        else if (ap->a_flag & A_BIT)   locIndex = 3;
+        else locIndex = 0;
+
+        if (ap->a_flag & A_ABS) /* Absolute sections */
+        {
+            lnksect2(ap, locIndex);
+        }
+        else /* Relocatable sections */
+        {
+            if (ap->a_type == 0)
+            {
+                ap->a_addr = rloc[locIndex];
+                ap->a_type = 1;
+            }
+
+            rloc[locIndex] = lnksect2(ap, locIndex);
+        }
+
+        /*
+         * Create symbols called:
+         *  s_<areaname>    the start address of the area
+         *  l_<areaname>    the length of the area
+         */
+
+        if (! symeq(ap->a_id, _abs_))
+        {
+            strncpy(temp+2,ap->a_id,NCPS-2);
+            *(temp+1) = '_';
+
+            *temp = 's';
+            sp = lkpsym(temp, 1);
+            sp->s_addr = ap->a_addr ;
+            sp->s_type |= S_DEF;
+            if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
+
+            *temp = 'l';
+            sp = lkpsym(temp, 1);
+            sp->s_addr = ap->a_size;
+            sp->s_axp = NULL;
+            sp->s_type |= S_DEF;
+            if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
+        }
+
+        /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
+        to compute the byte size of BSEG_BYTES: */
+        if (!strcmp(ap->a_id, "BSEG"))
+        {
+            ap->a_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
+        }
+        else if (!strcmp(ap->a_id, "DSEG"))
+        {
+            dseg_ap=ap; /*Need it later to set its correct size*/
+        }
+        ap = ap->a_ap;
+    }
+
+    /*Compute the size of DSEG*/
+    if(dseg_ap!=NULL)
+    {
+        dseg_ap->a_addr=0;
+        dseg_ap->a_size=0;
+        for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
+    }
+    if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
+    if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
+}
+
+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;
+}
+
+Addr_T lnksect2 (struct area *tap, int locIndex)
+{
+    register Addr_T size, addr;
+    register struct areax *taxp;
+    int j, k, ramlimit;
+    char fchar=' ', dchar='a';
+    char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
+                  " in internal RAM for area %s.\n";
+
+    tap->a_unaloc=0;
+
+    /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
+    if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
+    {
+        if((iram_size<=0)||(iram_size>0x100))
+            ramlimit=0x100;
+        else
+            ramlimit=iram_size;
+    }
+    else
+    {
+        if((iram_size<=0)||(iram_size>0x80))
+            ramlimit=0x80;
+        else
+            ramlimit=iram_size;
+    }
+
+    size = 0;
+    addr = tap->a_addr;
+#if 0
+    if ((tap->a_flag&A_PAG) && (addr & 0xFF))
+    {
+        fprintf(stderr,
+          "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+        lkerr++;
+    }
+#endif
+    taxp = tap->a_axp;
+
+    /*Use a letter to identify each area in the internal RAM layout map*/
+    if (locIndex==0)
+    {
+        /**/ if(!strcmp(tap->a_id, "DSEG"))
+            fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/
+        else if(!strcmp(tap->a_id, "ISEG"))
+            fchar='I';
+        else if(!strcmp(tap->a_id, "SSEG"))
+            fchar='S';
+        else if(!strcmp(tap->a_id, "OSEG"))
+            fchar='Q';
+        else if(!strcmp(tap->a_id, "REG_BANK_0"))
+            fchar='0';
+        else if(!strcmp(tap->a_id, "REG_BANK_1"))
+            fchar='1';
+        else if(!strcmp(tap->a_id, "REG_BANK_2"))
+            fchar='2';
+        else if(!strcmp(tap->a_id, "REG_BANK_3"))
+            fchar='3';
+        else if(!strcmp(tap->a_id, "BSEG_BYTES"))
+            fchar='B';
+        else if(!strcmp(tap->a_id, "BIT_BANK"))
+            fchar='T';
+        else
+            fchar=' ';/*???*/
+    }
+    else if (locIndex == 1)
+    {
+        /**/ if(!strcmp(tap->a_id, "GSINIT"))
+            fchar='G';
+    }
+    else if (locIndex == 2)
+    {
+        /**/ if(!strcmp(tap->a_id, "XSTK"))
+            fchar='K';
+    }
+
+    if (tap->a_flag&A_OVR) /* Overlayed sections */
+    {
+        while (taxp)
+        {
+            if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/
+            {
+                addr=(fchar-'0')*8;
+                taxp->a_addr=addr;
+                size=taxp->a_size;
+                for(j=addr; (j<(int)(addr+taxp->a_size)) && (j<ramlimit); j++)
+                    idatamap[j]=fchar;
+            }
+            else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
+            {
+                /*Find the size of the space currently used for this areax overlay*/
+                for(j=0, size=0; j<ramlimit; j++)
+                    if(idatamap[j]==fchar) size++;
+
+                if( (fchar=='S') && (stacksize==0) )
+                {
+                   /*Search for the largest space available and use it for stack*/
+                    for(j=0, k=0, taxp->a_size=0; j<ramlimit; j++)
+                    {
+                        if(idatamap[j]==' ')
+                        {
+                            if((++k)>(int)taxp->a_size) taxp->a_size=k;
+                        }
+                        else
+                        {
+                            k=0;
+                        }
+                    }
+                    stacksize=taxp->a_size;
+                }
+
+                /*If more space required, release the previously allocated areax in
+                internal RAM and search for a bigger one*/
+                if((int)taxp->a_size>size)
+                {
+                    size=(int)taxp->a_size;
+
+                    for(j=0; j<ramlimit; j++)
+                        if(idatamap[j]==fchar) idatamap[j]=' ';
+
+                    /*Search for a space large enough in data memory for this overlay areax*/
+                    for(j=0, k=0; j<ramlimit; j++)
+                    {
+                        if(idatamap[j]==' ')
+                            k++;
+                        else
+                            k=0;
+                        if(k==(int)taxp->a_size) break;
+                    }
+
+                    if(k==(int)taxp->a_size)
+                    {
+                        taxp->a_addr = j-k+1;
+                        if(addr<(unsigned int)ramlimit)
+                        {
+                            for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
+                            if(j>=0) addr=j+1;
+                        }
+                    }
+
+                    /*Mark the memory used for overlay*/
+                    if(k==(int)taxp->a_size)
+                    {
+                        for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
+                            idatamap[j]=fchar;
+
+                        /*Set the new size of the data memory area*/
+                        size=ramlimit-addr;
+                    }
+                    else /*Couldn't find a chunk big enough: report the problem.*/
+                    {
+                        tap->a_unaloc=taxp->a_size;
+                        fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
+                        lkerr++;
+                    }
+                }
+
+                for(j=0; j<ramlimit; j++)
+                {
+                    if (idatamap[j]==fchar)
+                    {
+                        addr=j;
+                        tap->a_addr=addr;
+                        taxp->a_addr=addr;
+                        break;
+                    }
+                }
+            }
+            else if (fchar=='T') /*Bit addressable bytes in internal RAM*/
+            {
+                /*Find the size of the space currently used for this areax overlay*/
+                for(j=0x20, size=0; j<0x30; j++)
+                    if(idatamap[j]==fchar) size++;
+
+                /*If more space required, release the previously allocated areax in
+                internal RAM and search for a bigger one*/
+                if((int)taxp->a_size>size)
+                {
+                    size=(int)taxp->a_size;
+
+                    for(j=0x20; j<0x30; j++)
+                        if(idatamap[j]==fchar) idatamap[j]=' ';
+
+                    /*Search for a space large enough in data memory for this overlay areax*/
+                    for(j=0x20, k=0; j<0x30; j++)
+                    {
+                        if(idatamap[j]==' ')
+                            k++;
+                        else
+                            k=0;
+                        if(k==(int)taxp->a_size) break;
+                    }
+
+                    if(k==(int)taxp->a_size)
+                    {
+                        taxp->a_addr = j-k+1;
+                        if(addr<(unsigned int)0x30)
+                        {
+                            for(j=0x2F; (j>=0x20)&&(idatamap[j]==' '); j--);
+                            if(j>=0x20) addr=j+1;
+                        }
+                    }
+
+                    /*Mark the memory used for overlay*/
+                    if(k==(int)taxp->a_size)
+                    {
+                        for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++)
+                            idatamap[j]=fchar;
+
+                        /*Set the new size of the data memory area*/
+                        size=ramlimit-addr;
+                    }
+                    else /*Couldn't find a chunk big enough: report the problem.*/
+                    {
+                        tap->a_unaloc=taxp->a_size;
+                        fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
+                        lkerr++;
+                    }
+                }
+
+                for(j=0x20; j<0x30; j++)
+                {
+                    if (idatamap[j]==fchar)
+                    {
+                        addr=j;
+                        tap->a_addr=addr;
+                        taxp->a_addr=addr;
+                        break;
+                    }
+                }
+            }
+            else /*Overlay areas not in internal ram*/
+            {
+                taxp->a_addr = addr;
+                if (taxp->a_size > size) size = taxp->a_size;
+            }
+            taxp = taxp->a_axp;
+        }
+    }
+    else if (tap->a_flag & A_ABS) /* Absolute sections */
+    {
+        while (taxp)
+        {
+            if (locIndex == 0)
+            {
+                for (j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
+                    idatamap[j] = 'A';
+            }
+            if (locIndex == 1)
+            {
+                allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap);
+            }
+            if (locIndex == 2)
+            {
+                allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, xdatamap);
+            }
+            taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
+            size += taxp->a_size;
+            taxp = taxp->a_axp;
+        }
+    }
+    else /* Concatenated sections */
+    {
+        if ((locIndex == 1) && tap->a_size)
+        {
+            addr = find_empty_space(addr, tap->a_size, codemap);
+        }
+        if ((locIndex == 2) && tap->a_size)
+        {
+            addr = find_empty_space(addr, tap->a_size, xdatamap);
+        }
+        while (taxp)
+        {
+            if( (fchar=='D') || (fchar=='I') )
+            {
+                if(taxp->a_size)
+                {
+                    /*Search for a space large enough in internal RAM for this areax*/
+                    for(j=0, k=0; j<ramlimit; j++)
+                    {
+                        if(idatamap[j]==' ')
+                            k++;
+                        else
+                            k=0;
+                        if(k==(int)taxp->a_size) break;
+                    }
+
+                    if(k==(int)taxp->a_size)
+                    {
+                        taxp->a_addr = j-k+1;
+                        if(addr<(unsigned int)ramlimit)
+                        {
+                            for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
+                            if(j>=0) addr=j+1;
+                            size=ramlimit-addr;
+                        }
+
+                        for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
+                            idatamap[j]=(fchar=='D')?dchar:fchar;
+                        if((taxp->a_size>0)&&(fchar=='D'))dchar++;
+                        if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
+                    }
+                    else /*We are in trouble, there is not enough memory for an areax chunk*/
+                    {
+                        taxp->a_addr = addr;
+                        addr += taxp->a_size;
+                        size += taxp->a_size;
+                        tap->a_unaloc+=taxp->a_size;
+                        fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
+                        lkerr++;
+                    }
+               }
+               taxp = taxp->a_axp;
+            }
+            else if(fchar=='B')
+            {
+                if(taxp->a_size!=0)
+                {
+                    for(j=addr; j<((int)(addr+taxp->a_size)); j++)
+                        idatamap[j]=fchar;
+                }
+
+                taxp->a_addr = addr;
+                addr += taxp->a_size;
+                size += taxp->a_size;
+                taxp = taxp->a_axp;
+            }
+            else /*For concatenated BIT, CODE, and XRAM areax's*/
+            {
+                if((fchar=='K') && (taxp->a_size == 1))
+                {
+                    taxp->a_size = 256-(addr & 0xFF);
+                }
+                //find next unused address now
+                if ((locIndex == 1) && taxp->a_size)
+                {
+                    addr = find_empty_space(addr, taxp->a_size, codemap);
+                    allocate_space(addr, taxp->a_size, tap->a_id, codemap);
+                }
+                if ((locIndex == 2) && taxp->a_size)
+                {
+                    addr = find_empty_space(addr, taxp->a_size, xdatamap);
+                    allocate_space(addr, taxp->a_size, tap->a_id, xdatamap);
+                }
+                taxp->a_addr = addr;
+                addr += taxp->a_size;
+                size += taxp->a_size;
+                taxp = taxp->a_axp;
+            }
+        }
+    }
+    tap->a_size = size;
+
+    if ((tap->a_flag&A_PAG) && (size > 256))
+    {
+        fprintf(stderr,
+        "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
+        lkerr++;
+    }
+    if ((tap->a_flag&A_PAG) && (tap->a_size) &&
+        ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
+    {
+        fprintf(stderr,
+        "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
+        lkerr++;
+    }
+    return addr;
+}
diff --git a/as/link/mcs51/lkdata.c b/as/link/mcs51/lkdata.c
new file mode 100644 (file)
index 0000000..64af18b
--- /dev/null
@@ -0,0 +1,495 @@
+/* lkdata.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * 28-Oct-97 JLH:
+ *           - change s_id from [NCPS] to pointer (comment)
+ * 31-Oct-97 JLH:
+ *           - add jflag and jfp for NoICE output
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module       lkdata.c
+ *
+ *      The module lkdata contains the global variables
+ *      and structures used in the linker aslink.
+ */
+
+/*
+ *      Definitions for all Global Variables
+ */
+
+char    *_abs_  = { ".  .ABS." };
+
+int     lkerr;          /*      Linker error flag
+                         */
+char    *ip;            /*      Pointer into the REL file text line in ib[]
+                         */
+char    ib[NINPUT];     /*      REL file text line
+                         */
+char    *rp;            /*      pointer into the LST file
+                         *      text line in rb[]
+                         */
+char    rb[NINPUT];     /*      LST file text line being
+                         *      address relocated
+                         */
+
+char sdccopt[NINPUT]="";
+char sdccopt_module[NINPUT]="";
+char curr_module[NINPUT]="";
+
+int     dflag;          /*      Debug information output flag
+                         */
+int     oflag;          /*      Output file type flag
+                         */
+int     mflag;          /*      Map output flag
+                         */
+int     sflag;          /*      JCF: Memory usage output flag
+                         */
+int     packflag=0;     /*      JCF: Pack internal memory flag
+                         */
+int     stacksize=0;    /*      JCF: Stack size
+                         */
+int     aflag;          /*      Overlapping area warning flag
+                         */
+int     jflag;          /*      NoICE output flag
+                         */
+int     xflag;          /*      Map file radix type flag
+                         */
+int     pflag;          /*      print linker command file flag
+                         */
+int     uflag;          /*      Listing relocation flag
+                         */
+int     rflag;          /*      Extended linear address record flag.
+                         */
+int     radix;          /*      current number conversion radix:
+                         *      2 (binary), 8 (octal), 10 (decimal),
+                         *      16 (hexadecimal)
+                         */
+int     line;           /*      current line number
+                         */
+int     page;           /*      current page number
+                         */
+int     lop;            /*      current line number on page
+                         */
+int     pass;           /*      linker pass number
+                         */
+int     rtcnt;          /*      count of elements in the
+                         *      rtval[] and rtflg[] arrays
+                         */
+Addr_T  rtval[NTXT];    /*      data associated with relocation
+                         */
+int     rtflg[NTXT];    /*      indicates if rtval[] value is
+                         *      to be sent to the output file.
+                         *      (always set in this linker)
+                         */
+int     hilo;           /*      REL file byte ordering
+                         */
+int     gline;          /*      LST file relocation active
+                         *      for current line
+                         */
+int     gcntr;          /*      LST file relocation active
+                         *      counter
+                         */
+Addr_T  iram_size;      /*      internal ram size
+                         */
+long    xram_size=-1;   /*      external ram size
+                         */
+long    code_size=-1;   /*      code size
+                         */
+
+/*
+ *      The structure lfile contains a pointer to a
+ *      file specification string, the file type, and
+ *      a link to the next lfile structure.
+ *
+ *      struct  lfile
+ *      {
+ *              struct  lfile   *f_flp;         lfile link
+ *              int     f_type;                 File type
+ *              char    *f_idp;                 Pointer to file spec
+ *      };
+ */
+struct  lfile   *filep; /*      The pointers (lfile *) filep,
+                         *      (lfile *) cfp, and (FILE *) sfp
+                         *      are used in conjunction with
+                         *      the routine as_getline() to read
+                         *      asmlnk commands from
+                         *      (1) the standard input or
+                         *      (2) or a command file
+                         *      and to read the REL files
+                         *      sequentially as defined by the
+                         *      asmlnk input commands.
+                         *
+                         *      The pointer *filep points to the
+                         *      beginning of a linked list of
+                         *      lfile structures.
+                         */
+struct  lfile   *cfp;   /*      The pointer *cfp points to the
+                         *      current lfile structure
+                         */
+struct  lfile   *startp;/*      asmlnk startup file structure
+                         */
+struct  lfile   *linkp; /*      pointer to first lfile structure
+                         *      containing an input REL file
+                         *      specification
+                         */
+struct  lfile   *lfp;   /*      pointer to current lfile structure
+                         *      being processed by parse()
+                         */
+FILE    *ofp;           /*      Output file handle
+                         *      for word formats
+                         */
+FILE    *mfp;           /*      Map output file handle
+                         */
+FILE    *jfp;           /*      NoICE output file handle
+                         */
+FILE    *rfp;           /*      File handle for output
+                         *      address relocated ASxxxx
+                         *      listing file
+                         */
+FILE    *sfp;           /*      The file handle sfp points to the
+                         *      currently open file
+                         */
+FILE    *tfp;           /*      File handle for input
+                         *      ASxxxx listing file
+                         */
+FILE    *dfp = NULL ;   /*
+                         *      File handle for debug
+                         *      information output file
+                         */
+/*
+ *      The structures of head, area, areax, and sym are created
+ *      as the REL files are read during the first pass of the
+ *      linker.  The struct head is created upon encountering a
+ *      H directive in the REL file.  The structure contains a
+ *      link to a link file structure (struct lfile) which describes
+ *      the file containing the H directive, the number of data/code
+ *      areas contained in this header segment, the number of
+ *      symbols referenced/defined in this header segment, a pointer
+ *      to an array of pointers to areax structures (struct areax)
+ *      created as each A directive is read, and a pointer to an
+ *      array of pointers to symbol structures (struct sym) for
+ *      all referenced/defined symbols.  As H directives are read
+ *      from the REL files a linked list of head structures is
+ *      created by placing a link to the new head structure
+ *      in the previous head structure.
+ *
+ *      struct  head
+ *      {
+ *              struct  head   *h_hp;           Header link
+ *              struct  lfile  *h_lfile;        Associated file
+ *              int     h_narea;                # of areas
+ *              struct  areax **a_list;         Area list
+ *              int     h_nglob;                # of global symbols
+ *              struct  sym   **s_list;         Global symbol list
+ *              char    m_id[NCPS];             Module name
+ *      };
+ */
+struct  head    *headp; /*      The pointer to the first
+                         *      head structure of a linked list
+                         */
+struct  head    *hp;    /*      Pointer to the current
+                         *      head structure
+                         */
+
+/*
+ *      A structure area is created for each 'unique' data/code
+ *      area definition found as the REL files are read.  The
+ *      struct area contains the name of the area, a flag byte
+ *      which contains the area attributes (REL/CON/OVR/ABS),
+ *      an area subtype (not used in this assembler), and the
+ *      area base address and total size which will be filled
+ *      in at the end of the first pass through the REL files.
+ *      As A directives are read from the REL files a linked
+ *      list of unique area structures is created by placing a
+ *      link to the new area structure in the previous area structure.
+ *
+ *      struct  area
+ *      {
+ *              struct  area    *a_ap;          Area link
+ *              struct  areax   *a_axp;         Area extension link
+ *              Addr_T  a_addr;                 Beginning address of area
+ *              Addr_T  a_size;                 Total size of the area
+ *              char    a_type;                 Area subtype
+ *              char    a_flag;                 Flag byte
+ *              char    a_id[NCPS];             Name
+ *      };
+ */
+struct  area    *areap; /*      The pointer to the first
+                         *      area structure of a linked list
+                         */
+struct  area    *ap;    /*      Pointer to the current
+                         *      area structure
+                         */
+
+/*
+ *      An areax structure is created for every A directive found
+ *      while reading the REL files.  The struct areax contains a
+ *      link to the 'unique' area structure referenced by the A
+ *      directive and to the head structure this area segment is
+ *      a part of.  The size of this area segment as read from the
+ *      A directive is placed in the areax structure.  The beginning
+ *      address of this segment will be filled in at the end of the
+ *      first pass through the REL files.  As A directives are read
+ *      from the REL files a linked list of areax structures is
+ *      created for each unique area.  The final areax linked
+ *      list has at its head the 'unique' area structure linked
+ *      to the linked areax structures (one areax structure for
+ *      each A directive for this area).
+ *
+ *      struct  areax
+ *      {
+ *              struct  areax   *a_axp;         Area extension link
+ *              struct  area    *a_bap;         Base area link
+ *              struct  head    *a_bhp;         Base header link
+ *              Addr_T  a_addr;                 Beginning address of section
+ *              Addr_T  a_size;                 Size of the area in section
+ *      };
+ */
+struct  areax   *axp;   /*      Pointer to the current
+                         *      areax structure
+                         */
+
+/*
+ *      A sym structure is created for every unique symbol
+ *      referenced/defined while reading the REL files.  The
+ *      struct sym contains the symbol's name, a flag value
+ *      (not used in this linker), a symbol type denoting
+ *      referenced/defined, and an address which is loaded
+ *      with the relative address within the area in which
+ *      the symbol was defined.  The sym structure also
+ *      contains a link to the area where the symbol was defined.
+ *      The sym structures are linked into linked lists using
+ *      the symbol link element.
+ *
+ *      struct  sym
+ *      {
+ *              struct  sym     *s_sp;          Symbol link
+ *              struct  areax   *s_axp;         Symbol area link
+ *              char    s_type;                 Symbol subtype
+ *              char    s_flag;                 Flag byte
+ *              Addr_T  s_addr;                 Address
+ *              char    *s_id;                  Name (JLH)
+ *      };
+ */
+struct  sym *symhash[NHASH]; /* array of pointers to NHASH
+                              * linked symbol lists
+                              */
+/*
+ *      The struct base contains a pointer to a
+ *      base definition string and a link to the next
+ *      base structure.
+ *
+ *      struct  base
+ *      {
+ *              struct  base  *b_base;          Base link
+ *              char          *b_strp;          String pointer
+ *      };
+ */
+struct  base    *basep; /*      The pointer to the first
+                         *      base structure
+                         */
+struct  base    *bsp;   /*      Pointer to the current
+                         *      base structure
+                         */
+
+/*
+ *      The struct globl contains a pointer to a
+ *      global definition string and a link to the next
+ *      global structure.
+ *
+ *      struct  globl
+ *      {
+ *              struct  globl *g_globl;         Global link
+ *              char          *g_strp;          String pointer
+ *      };
+ */
+struct  globl   *globlp;/*      The pointer to the first
+                         *      globl structure
+                         */
+struct  globl   *gsp;   /*      Pointer to the current
+                         *      globl structure
+                         */
+
+/*
+ *      A structure sdp is created for each 'unique' paged
+ *      area definition found as the REL files are read.
+ *      As P directives are read from the REL files a linked
+ *      list of unique sdp structures is created by placing a
+ *      link to the new sdp structure in the previous area structure.
+ *
+ *      struct  sdp
+ *      {
+ *              struct  area  *s_area;  Paged Area link
+ *              struct  areax *s_areax; Paged Area Extension Link
+ *              Addr_T  s_addr;         Page address offset
+ *      };
+ */
+struct  sdp     sdp;    /* Base Page Structure */
+
+/*
+ *      The structure rerr is loaded with the information
+ *      required to report an error during the linking
+ *      process.  The structure contains an index value
+ *      which selects the areax structure from the header
+ *      areax structure list, a mode value which selects
+ *      symbol or area relocation, the base address in the
+ *      area section, an area/symbol list index value, and
+ *      an area/symbol offset value.
+ *
+ *      struct  rerr
+ *      {
+ *              int     aindex;         Linking area
+ *              int     mode;           Relocation mode
+ *              Addr_T  rtbase;         Base address in section
+ *              int     rindex;         Area/Symbol reloaction index
+ *              Addr_T  rval;           Area/Symbol offset value
+ *      };
+ */
+struct  rerr    rerr;   /*      Structure containing the
+                         *      linker error information
+                         */
+
+/*
+ *      The structure lbpath is created for each library
+ *      path specification input by the -k option.  The
+ *      lbpath structures are linked into a list using
+ *      the next link element.
+ *
+ *      struct lbpath {
+ *              struct  lbpath  *next;
+ *              char            *path;
+ *      };
+ */
+struct  lbpath  *lbphead;       /*      pointer to the first
+                                 *      library path structure
+                                 */
+
+/*
+ *      The structure lbname is created for all combinations of the
+ *      library path specifications (input by the -k option) and the
+ *      library file specifications (input by the -l option) that
+ *      lead to an existing file.  The element path points to
+ *      the path string, element libfil points to the library
+ *      file string, and the element libspc is the concatenation
+ *      of the valid path and libfil strings.
+ *
+ *      The lbpath structures are linked into a list
+ *      using the next link element.
+ *
+ *      Each library file contains a list of object files
+ *      that are contained in the particular library. e.g.:
+ *
+ *              \iolib\termio
+ *              \inilib\termio
+ *
+ *      Only one specification per line is allowed.
+ *
+ *      struct lbname {
+ *              struct  lbname  *next;
+ *              char            *path;
+ *              char            *libfil;
+ *              char            *libspc;
+ *      };
+ */
+struct  lbname  *lbnhead;       /*      pointer to the first
+                                 *      library name structure
+                                 */
+
+/*
+ *      The function fndsym() searches through all combinations of the
+ *      library path specifications (input by the -k option) and the
+ *      library file specifications (input by the -l option) that
+ *      lead to an existing file for a symbol definition.
+ *
+ *      The structure lbfile is created for the first library
+ *      object file which contains the definition for the
+ *      specified undefined symbol.
+ *
+ *      The element libspc points to the library file path specification
+ *      and element relfil points to the object file specification string.
+ *      The element filspc is the complete path/file specification for
+ *      the library file to be imported into the linker.  The
+ *      file specicifation may be formed in one of two ways:
+ *
+ *      (1)     If the library file contained an absolute
+ *              path/file specification then this becomes filspc.
+ *              (i.e. C:\...)
+ *
+ *      (2)     If the library file contains a relative path/file
+ *              specification then the concatenation of the path
+ *              and this file specification becomes filspc.
+ *              (i.e. \...)
+ *
+ *      The lbpath structures are linked into a list
+ *      using the next link element.
+ *
+ *      struct lbfile {
+ *              struct  lbfile  *next;
+ *              char            *libspc;
+ *              char            *relfil;
+ *              char            *filspc;
+ *      };
+ */
+struct  lbfile  *lbfhead;       /*      pointer to the first
+                                 *      library file structure
+                                 */
+
+/*
+ *      array of character types, one per
+ *      ASCII character
+ */
+unsigned char   ctype[128] = {
+/*NUL*/ ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
+/*BS*/  ILL,    SPACE,  ILL,    ILL,    SPACE,  ILL,    ILL,    ILL,
+/*DLE*/ ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
+/*CAN*/ ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
+/*SPC*/ SPACE,  ETC,    ETC,    ETC,    LETTER, BINOP,  BINOP,  ETC,
+/*(*/   ETC,    ETC,    BINOP,  BINOP,  ETC,    BINOP,  LETTER, BINOP,
+/*0*/   DGT2,   DGT2,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,
+/*8*/   DGT10,  DGT10,  ETC,    ETC,    BINOP,  ETC,    BINOP,  ETC,
+/*@*/   ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
+/*H*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*P*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*X*/   LETTER, LETTER, LETTER, BINOP,  ETC,    ETC,    BINOP,  LETTER,
+/*`*/   ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
+/*h*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*p*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*x*/   LETTER, LETTER, LETTER, ETC,    BINOP,  ETC,    ETC,    ETC
+};
+
+/*
+ *      an array of characters which
+ *      perform the case translation function
+ */
+#if     CASE_SENSITIVE
+#else
+char    ccase[128] = {
+/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+/*BS*/  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+/*(*/   '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+/*0*/   '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+/*8*/   '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+/*@*/   '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+/*H*/   '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+/*P*/   '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+/*X*/   '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+/*`*/   '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+/*h*/   '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+/*p*/   '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+/*x*/   '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177'
+};
+#endif
diff --git a/as/link/mcs51/lkeval.c b/as/link/mcs51/lkeval.c
new file mode 100644 (file)
index 0000000..90df003
--- /dev/null
@@ -0,0 +1,396 @@
+/* lkeval.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module      lkeval.c
+ *
+ *     The module lkeval.c contains the routines to evaluate
+ *     arithmetic/numerical expressions.  The functions in
+ *     lkeval.c perform a recursive evaluation of the arithmetic
+ *     expression read from the input text line.
+ *     The expression may include binary/unary operators, brackets,
+ *     symbols, labels, and constants in hexadecimal, decimal, octal
+ *     and binary.  Arithmetic operations are prioritized and
+ *     evaluated by normal arithmetic conventions.
+ *
+ *     lkeval.c contains the following functions:
+ *             int     digit()
+ *             Addr_T  eval()
+ *             Addr_T  expr()
+ *             int     oprio()
+ *             Addr_T  term()
+ *
+ *     lkeval.c contains no local/static variables
+ */
+
+/*)Function    Addr_T  eval()
+ *
+ *     The function eval() evaluates a character string to a
+ *     numerical value.
+ *
+ *     local variables:
+ *             int     c               character from input string
+ *             int     v               value of character in current radix
+ *             Addr_T  n               evaluation value
+ *
+ *     global variables:
+ *             int     radix           current number conversion radix
+ *
+ *     functions called:
+ *             int     digit()         lkeval.c
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             Input test is scanned and evaluated to a
+ *             numerical value.
+ */
+
+Addr_T
+eval()
+{
+       register int c, v;
+       register Addr_T n;
+
+       c = getnb();
+       n = 0;
+       while ((v = digit(c, radix)) >= 0) {
+               n = n*radix + v;
+               c = get();
+       }
+       unget(c);
+       return(n);
+}
+
+/*)Function    Addr_T  expr(n)
+ *
+ *             int     n               a firewall priority; all top
+ *                                     level calls (from the user)
+ *                                     should be made with n set to 0.
+ *
+ *     The function expr() evaluates an expression and
+ *     returns the value.
+ *
+ *     local variables:
+ *             int     c               current input text character
+ *             int     p               current operator priority
+ *             Addr_T  v               value returned by term()
+ *             Addr_T  ve              value returned by a
+ *                                     recursive call to expr()
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             int     lkerr           error flag
+ *             FILE *  stderr          c_library
+ *
+ *     functions called:
+ *             VOID    expr()          lkeval.c
+ *             int     fprintf()       c_library
+ *             int     getnb()         lklex.c
+ *             int     oprio()         lkeval.c
+ *             VOID    term()          lkeval.c
+ *             VOID    unget()         lklex.c
+ *
+ *
+ *     side effects:
+ *             An expression is evaluated by scanning the input
+ *             text string.
+ */
+
+Addr_T
+expr (n)
+{
+       register int c, p;
+       register Addr_T v, ve;
+
+       v = term();
+       while (ctype[c = getnb()] & BINOP) {
+               if ((p = oprio(c)) <= n)
+                       break;
+               if ((c == '>' || c == '<') && c != get()) {
+                       fprintf(stderr, "Invalid expression");
+                       lkerr++;
+                       return(v);
+               }
+               ve = expr(p);
+               if (c == '+') {
+                       v += ve;
+               } else
+               if (c == '-') {
+                       v -= ve;
+               } else {
+                       switch (c) {
+
+                       case '*':
+                               v *= ve;
+                               break;
+
+                       case '/':
+                               v /= ve;
+                               break;
+
+                       case '&':
+                               v &= ve;
+                               break;
+
+                       case '|':
+                               v |= ve;
+                               break;
+
+                       case '%':
+                               v %= ve;
+                               break;
+
+                       case '^':
+                               v ^= ve;
+                               break;
+
+                       case '<':
+                               v <<= ve;
+                               break;
+
+                       case '>':
+                               v >>= ve;
+                               break;
+                       }
+               }
+       }
+       unget(c);
+       return(v);
+}
+
+/*)Function    Addr_T  term()
+ *
+ *     The function term() evaluates a single constant
+ *     or symbol value prefaced by any unary operator
+ *     ( +, -, ~, ', ", >, or < ).
+ *
+ *     local variables:
+ *             int     c               current character
+ *             char    id[]            symbol name
+ *             int     n               value of digit in current radix
+ *             int     r               current evaluation radix
+ *             sym *   sp              pointer to a sym structure
+ *             Addr_T  v               evaluation value
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             int     lkerr           error flag
+ *
+ *     functions called:
+ *             int     digit()         lkeval.c
+ *             VOID    expr()          lkeval.c
+ *             int     fprintf()       c_library
+ *             int     get()           lklex.c
+ *             VOID    getid()         lklex.c
+ *             int     getmap()        lklex.c
+ *             int     getnb()         lklex.c
+ *             sym *   lkpsym()        lksym.c
+ *             Addr_T  symval()        lksym.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             An arithmetic term is evaluated by scanning input text.
+ */
+
+Addr_T
+term()
+{
+       register int c, r, n;
+       register Addr_T v;
+       struct sym *sp;
+       char id[NCPS];
+
+       c = getnb();
+       if (c == '#') { c = getnb(); }
+       if (c == '(') {
+               v = expr(0);
+               if (getnb() != ')') {
+                       fprintf(stderr, "Missing delimiter");
+                       lkerr++;
+               }
+               return(v);
+       }
+       if (c == '-') {
+               return(0-expr(100));
+       }
+       if (c == '~') {
+               return(~expr(100));
+       }
+       if (c == '\'') {
+               return(getmap(-1)&0377);
+       }
+       if (c == '\"') {
+               if (hilo) {
+                       v  = (getmap(-1)&0377)<<8;
+                       v |=  getmap(-1)&0377;
+               } else {
+                       v  =  getmap(-1)&0377;
+                       v |= (getmap(-1)&0377)<<8;
+               }
+               return(v);
+       }
+       if (c == '>' || c == '<') {
+               v = expr(100);
+               if (c == '>')
+                       v >>= 8;
+               return(v&0377);
+       }
+       if (ctype[c] & DIGIT) {
+               r = 10;
+               if (c == '0') {
+                       c = get();
+                       switch (c) {
+                       case 'b':
+                       case 'B':
+                               r = 2;
+                               c = get();
+                               break;
+                       case '@':
+                       case 'o':
+                       case 'O':
+                       case 'q':
+                       case 'Q':
+                               r = 8;
+                               c = get();
+                               break;
+                       case 'd':
+                       case 'D':
+                               r = 10;
+                               c = get();
+                               break;
+                       case 'h':
+                       case 'H':
+                       case 'x':
+                       case 'X':
+                               r = 16;
+                               c = get();
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               v = 0;
+               while ((n = digit(c, r)) >= 0) {
+                       v = r*v + n;
+                       c = get();
+               }
+               unget(c);
+               return(v);
+       }
+       if (ctype[c] & LETTER) {
+               getid(id, c);
+               if ((sp = lkpsym(id, 0)) == NULL) {
+                       fprintf(stderr, "Undefined symbol %8s\n", id);
+                       lkerr++;
+                       return(0);
+               } else {
+                       return(symval(sp));
+               }
+       }
+       return(0);
+}
+
+/*)Function    int     digit(c, r)
+ *
+ *             int     c               digit character
+ *             int     r               current radix
+ *
+ *     The function digit() returns the value of c
+ *     in the current radix r.  If the c value is not
+ *     a number of the current radix then a -1 is returned.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+int
+digit(c, r)
+register int c, r;
+{
+       if (r == 16) {
+               if (ctype[c] & RAD16) {
+                       if (c >= 'A' && c <= 'F')
+                               return (c - 'A' + 10);
+                       if (c >= 'a' && c <= 'f')
+                               return (c - 'a' + 10);
+                       return (c - '0');
+               }
+       } else
+       if (r == 10) {
+               if (ctype[c] & RAD10)
+                       return (c - '0');
+       } else
+       if (r == 8) {
+               if (ctype[c] & RAD8)
+                       return (c - '0');
+       } else
+       if (r == 2) {
+               if (ctype[c] & RAD2)
+                       return (c - '0');
+       }
+       return (-1);
+}
+
+/*)Function    int     oprio(c)
+ *
+ *             int     c               operator character
+ *
+ *     The function oprio() returns a relative priority
+ *     for all valid unary and binary operators.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+int
+oprio(c)
+register int c;
+{
+       if (c == '*' || c == '/' || c == '%')
+               return (10);
+       if (c == '+' || c == '-')
+               return (7);
+       if (c == '<' || c == '>')
+               return (5);
+       if (c == '^')
+               return (4);
+       if (c == '&')
+               return (3);
+       if (c == '|')
+               return (1);
+       return (0);
+}
diff --git a/as/link/mcs51/lkhead.c b/as/link/mcs51/lkhead.c
new file mode 100644 (file)
index 0000000..41a5198
--- /dev/null
@@ -0,0 +1,153 @@
+/* lkhead.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*Module       lkhead.c
+ *
+ *     The module lkhead.c contains the function newhead() which
+ *     creates a head structure and the function module() which
+ *     loads the module name into the current head structure.
+ *
+ *     lkhead.c contains the following functions:
+ *             VOID    newhead()
+ *             VOID    module()
+ *
+ *     lkhead.c contains no local variables.
+ */
+
+/*)Function    VOID    newhead()
+ *
+ *     The function newhead() creates a head structure.  All head
+ *     structures are linked to form a linked list of head structures
+ *     with the current head structure at the tail of the list.
+ *
+ *     local variables:
+ *             int     i               evaluation value
+ *             head *  thp             temporary pointer
+ *                                     to a header structure
+ *
+ *     global variables:
+ *             area    *ap             Pointer to the current
+ *                                     area structure
+ *             lfile   *cfp            The pointer *cfp points to the
+ *                                     current lfile structure
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             head    *hp             Pointer to the current
+ *                                     head structure
+ *
+ *     functions called:
+ *             Addr_T  expr()          lkeval.c
+ *             VOID *  new()           lksym.c
+ *             VOID    lkparea()       lkarea.c
+ *
+ *     side effects:
+ *             A new head structure is created and linked to any
+ *             existing linked head structure.  The head structure
+ *             parameters of file handle, number of areas, and number
+ *             of global symbols are loaded into the structure.
+ *             The default area "_abs_" is created when the first
+ *             head structure is created and an areax structure is
+ *             created for every head structure called.
+ */
+
+/*
+ * Create a new header entry.
+ *
+ * H n areas n global symbols
+ *   |       |
+ *   |       `---- hp->h_nglob
+ *   `------------ hp->h_narea
+ *
+ */
+VOID
+newhead()
+{
+       register int i;
+       struct head *thp;
+
+       hp = (struct head *) new (sizeof(struct head));
+       if (headp == NULL) {
+               headp = hp;
+       } else {
+               thp = headp;
+               while (thp->h_hp)
+                       thp = thp->h_hp;
+               thp->h_hp = hp;
+       }
+       /*
+        * Set file pointer
+        */
+       hp->h_lfile = cfp;
+       /*
+        * Evaluate and build Area pointer list
+        */
+       i = hp->h_narea = eval();
+       if (i)
+               hp->a_list = (struct areax **) new (i*sizeof(struct areax *));
+       /*
+        * Evaluate and build Global symbol pointer list
+        */
+       skip(-1);
+       i = hp->h_nglob = eval();
+       if (i)
+               hp->s_list = (struct sym **) new (i*sizeof(struct sym *));
+       /*
+        * Setup Absolute DEF linkage.
+        */
+       lkparea(_abs_);
+       ap->a_flag = A_ABS;
+}
+
+/*)Function    VOID    module()
+ *
+ *     The function module() copies the module name into
+ *     the current head structure.
+ *
+ *     local variables:
+ *             char    id[]            module id string
+ *
+ *     global variables:
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             head    *hp             Pointer to the current
+ *                                     head structure
+ *             int     lkerr           error flag
+ *             FILE *  stderr          c_library
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    getid()         lklex.c
+ *             char *  strncpy()       c_library
+ *
+ *     side effects:
+ *             The module name is copied into the head structure.
+ */
+
+/*
+ * Module Name
+ */
+VOID
+module()
+{
+       char id[NCPS];
+
+       if (headp) {
+               getid(id, -1);
+               strncpy(hp->m_id, id, NCPS);
+       } else {
+               fprintf(stderr, "No header defined\n");
+               lkerr++;
+       }
+}
diff --git a/as/link/mcs51/lkihx.c b/as/link/mcs51/lkihx.c
new file mode 100644 (file)
index 0000000..8a5aa3e
--- /dev/null
@@ -0,0 +1,258 @@
+/* lkihx.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module      lkihx.c
+ *
+ *     The module lkihx.c contains the function to
+ *     output the relocated object code in the
+ *     Intel Hex format.
+ *
+ *     lkihx.c contains the following functions:
+ *             VOID    hexRecord(addr, rtvalIndex)
+ *             VOID    ihx(i)
+ *             VOID    ihxEntendedLinearAddress(a)
+ *
+ *     local variables: hexPageOverrun, lastHexAddr
+ */
+
+/*Intel Hex Format
+ *      Record Mark Field    -  This  field  signifies  the  start  of a
+ *                              record, and consists of an  ascii  colon
+ *                              (:).  
+ *
+ *      Record Length Field  -  This   field   consists   of  two  ascii
+ *                              characters which indicate the number  of
+ *                              data   bytes   in   this   record.   The
+ *                              characters are the result of  converting
+ *                              the  number  of  bytes  in binary to two
+ *                              ascii characters, high digit first.   An
+ *                              End  of  File  record contains two ascii
+ *                              zeros in this field.  
+ *
+ *      Load Address Field   -  This  field  consists  of the four ascii
+ *                              characters which result from  converting
+ *                              the  the  binary value of the address in
+ *                              which to begin loading this record.  The
+ *                              order is as follows:  
+ *
+ *                                  High digit of high byte of address. 
+ *                                  Low digit of high byte of address.  
+ *                                  High digit of low byte of address.  
+ *                                  Low digit of low byte of address.  
+ *
+ *                              In an End of File record this field con-
+ *                              sists of either four ascii zeros or  the
+ *                              program  entry  address.   Currently the
+ *                              entry address option is not supported.  
+ *
+ *      Record Type Field    -  This  field  identifies the record type,
+ *                              which is either 0 for data records or  1
+ *                              for  an End of File record.  It consists
+ *                              of two ascii characters, with  the  high
+ *                              digit of the record type first, followed
+ *                              by the low digit of the record type.  
+ *
+ *      Data Field           -  This  field consists of the actual data,
+ *                              converted to two ascii characters,  high
+ *                              digit first.  There are no data bytes in
+ *                              the End of File record.  
+ *
+ *      Checksum Field       -  The  checksum  field is the 8 bit binary
+ *                              sum of the record length field, the load
+ *                              address  field,  the  record type field,
+ *                              and the data field.  This  sum  is  then
+ *                              negated  (2's  complement) and converted
+ *                              to  two  ascii  characters,  high  digit
+ *                              first.  
+ */
+
+/* Static variable which holds the count of hex page overruns
+ * (crossings of the 64kB boundary). Cleared at explicit extended
+ * address output.
+ */
+static int hexPageOverrun = 0;
+
+/* Global which holds the last (16 bit) address of hex record.
+ * Cleared at begin of new area or when the extended address is output.
+ */
+unsigned int lastHexAddr = 0;
+
+
+/*)Function    hexRecord(addr, rtvalIndex)
+ *
+ *             unsigned addr   starting address of hex record
+ *             int rtvalIndex  starting index into the rtval[] array
+ *
+ *     The function hexRecord() outputs the relocated data
+ *     in the standard Intel Hex format (with inserting
+ *     the extended address record if necessary).
+ *
+ *     local variables:
+ *             Addr_T  chksum          byte checksum
+ *             int             i                       index for loops
+ *             int             overrun         temporary storage for hexPageOverrun
+ *             int             bytes           counter for bytes written
+ *
+ *     global variables:
+ *             FILE *  ofp             output file handle
+ *             int     rtcnt           count of data words
+ *             int     rtflg[]         output the data flag
+ *             Addr_T  rtval[]         relocated data
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             ihxEntendedLinearAddress()      lkihx.c
+ *             hexRecord()             lkihx.c         (recursion)
+ *
+ *     side effects:
+ *             hexPageOverrun is eventually incremented,
+ *             lastHexAddr is updated
+ */
+
+VOID
+hexRecord(unsigned addr, int rtvalIndex)
+{
+       Addr_T chksum;
+       int i, overrun, bytes;
+
+       for (i = rtvalIndex, chksum = 0; i < rtcnt; i++) {
+               if (rtflg[i]) {
+                       if (addr + ++chksum > 0xffff)
+                               break;
+               }
+       }
+       if (chksum == 0)
+               return;                 // nothing to output
+
+       if ( (lastHexAddr > addr) && (rflag) ) {
+               overrun = hexPageOverrun + 1;
+               ihxEntendedLinearAddress(lastExtendedAddress + overrun);
+               hexPageOverrun = overrun;
+               hexRecord(addr, rtvalIndex);
+               return;
+       }
+
+       lastHexAddr = addr;
+       fprintf(ofp, ":%02X%04X00", chksum, addr);
+       chksum += (addr >> 8) + (addr & 0xff);
+       for (i = rtvalIndex, bytes = 0; i < rtcnt; i++) {
+               if (rtflg[i]) {
+                   fprintf(ofp, "%02X", rtval[i]);
+                   chksum += rtval[i];
+                       if (addr + ++bytes > 0xffff) {
+                               if (rflag) {
+                                       fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
+                                       overrun = hexPageOverrun + 1;
+                                       ihxEntendedLinearAddress(lastExtendedAddress + overrun);
+                                       hexPageOverrun = overrun;
+                                       hexRecord(0, i + 1);
+                                       return;
+                               } else {
+                                       fprintf(stderr, 
+                                               "warning: extended linear address encountered; "
+                                               "you probably want the -r flag.\n");
+                               }
+                       }
+               }
+       }
+       fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
+}
+
+/*)Function    ihx(i)
+ *
+ *             int     i               0 - process data
+ *                                     1 - end of data
+ *
+ *     The function ihx() calls the hexRecord() function for processing data
+ *     or writes the End of Data record to the file defined by ofp.
+ *
+ *     local variables:
+ *             Addr_T  n               auxiliary variable
+ *
+ *     global variables:
+ *             int     hilo            byte order
+ *             FILE *  ofp             output file handle
+ *             Addr_T  rtval[]         relocated data
+ *
+ *     functions called:
+ *             VOID hexRecord()        lkihx.c
+ *             int     fprintf()               c_library
+ *
+ *     side effects:
+ *             The sequence of rtval[0], rtval[1] is eventually changed.
+ */
+
+VOID
+ihx(i)
+{
+       Addr_T n;
+       if (i) {
+               if (hilo == 0) {
+                       n = rtval[0];
+                       rtval[0] = rtval[1];
+                       rtval[1] = n;
+               }
+               hexRecord((rtval[0]<<8) + rtval[1], 2);
+       } else {
+               fprintf(ofp, ":00000001FF\n");
+       }
+}
+
+/*)Function    newArea(i)
+ * The function newArea() is called when processing of new area is started.
+ * It resets the value of lastHexAddr.
+ */ 
+
+VOID
+newArea()
+{
+       lastHexAddr = 0;
+}
+
+/*)Function    ihxEntendedLinearAddress(i)
+ *
+ *             Addr_T  i               16 bit extended linear address.
+ *
+ *     The function ihxEntendedLinearAddress() writes an extended
+ *     linear address record (type 04) to the output file.
+ *
+ *     local variables:
+ *             Addr_T  chksum          byte checksum
+ *
+ *     global variables:
+ *             FILE *  ofp             output file handle
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *
+ *     side effects:
+ *             The data is output to the file defined by ofp.
+ *             hexPageOverrun and lastHexAddr is cleared
+ */
+VOID
+ihxEntendedLinearAddress(Addr_T a)
+{
+    Addr_T     chksum;
+  
+    /* The checksum is the complement of the bytes in the
+     * record: the 2 is record length, 4 is the extended linear
+     * address record type, plus the two address bytes.
+     */ 
+    chksum = 2 + 4 + (a & 0xff) + ((a >> 8) & 0xff);    
+    
+    fprintf(ofp, ":02000004%04X%02X\n", a & 0xffff, (0-chksum) & 0xff);
+       hexPageOverrun = 0;
+       lastHexAddr = 0;
+}
diff --git a/as/link/mcs51/lklex.c b/as/link/mcs51/lklex.c
new file mode 100644 (file)
index 0000000..7c48130
--- /dev/null
@@ -0,0 +1,640 @@
+/* lklex.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module      lklex.c
+ *
+ *     The module lklex.c contains the general lexical analysis
+ *     functions used to scan the text lines from the .rel files.
+ *
+ *     lklex.c contains the fllowing functions:
+ *             char    endline()
+ *             char    get()
+ *             VOID    getfid()
+ *             VOID    getid()
+ *             VOID    getSid()
+ *             int     as_getline()
+ *             int     getmap()
+ *             char    getnb()
+ *             int     more()
+ *             VOID    skip()
+ *             VOID    unget()
+ *
+ *     lklex.c contains no local variables.
+ */
+
+/*)Function    VOID    getid(id,c)
+ *
+ *             char *  id              a pointer to a string of
+ *                                     maximum length NCPS
+ *             int     c               mode flag
+ *                                     >=0     this is first character to
+ *                                             copy to the string buffer
+ *                                     <0      skip white space
+ *
+ *     The function getid() scans the current input text line
+ *     from the current position copying the next LETTER | DIGIT string
+ *     into the external string buffer (id).  The string ends when a non
+ *     LETTER or DIGIT character is found. The maximum number of
+ *     characters copied is NCPS.  If the input string is larger than
+ *     NCPS characters then the string is truncated, if the input string
+ *     is shorter than NCPS characters then the string is NULL filled.
+ *     If the mode argument (c) is >=0 then (c) is the first character
+ *     copied to the string buffer, if (c) is <0 then intervening white
+ *     space (SPACES and TABS) are skipped.
+ *
+ *     local variables:
+ *             char *  p               pointer to external string buffer
+ *             int     c               current character value
+ *
+ *     global variables:
+ *             char    ctype[]         a character array which defines the
+ *                                     type of character being processed.
+ *                                     This index is the character
+ *                                     being processed.
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of getnb(), get(), and unget() updates the
+ *             global pointer ip the position in the current
+ *             input text line.
+ */
+
+VOID
+getid(id, c)
+register int c;
+char *id;
+{
+       register char *p;
+
+       if (c < 0) {
+               c = getnb();
+       }
+       p = id;
+       do {
+               if (p < &id[NCPS])
+                       *p++ = c;
+       } while (ctype[c=get()] & (LETTER|DIGIT));
+       unget(c);
+       while (p < &id[NCPS])
+               *p++ = 0;
+}
+
+/*)Function    VOID    getSid (char *id)
+ *
+ *             char *  id              a pointer to a string of
+ *                                     maximum length NCPS
+ *
+ *  getSid is derived from getid. It is called from newsym()
+ *  in lksym.c, when an S-record has to be scanned. getSid accepts
+ *  much more characters than getid, which is necessary for SDCC.
+ * 
+ *     The function getSid() scans the current input text line
+ *     from the current position copying the next string
+ *     into the external string buffer (id).  The string ends when a space
+ *  character (space, tab, \0) is found. The maximum number of
+ *     characters copied is NCPS.  If the input string is larger than
+ *     NCPS characters then the string is truncated, if the input string
+ *     is shorter than NCPS characters then the string is NULL filled.
+ *     Intervening white space (SPACES and TABS) are skipped.
+ *
+ *     local variables:
+ *             char *  p               pointer to external string buffer
+ *             int     c               current character value
+ *
+ *     global variables:
+ *             char    ctype[]         a character array which defines the
+ *                                     type of character being processed.
+ *                                     This index is the character
+ *                                     being processed.
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of getnb(), get(), and unget() updates the
+ *             global pointer ip the position in the current
+ *             input text line.
+ */
+
+VOID
+getSid (id)
+char *id;
+{
+  register int c;
+       register char *p;
+
+  c = getnb();
+       p = id;
+       do {
+               if (p < &id[NCPS])
+                       *p++ = c;
+               c = get();
+       } while (c != '\0' && c != ' ' && c != '\t');
+       unget(c);
+       while (p < &id[NCPS])
+               *p++ = 0;
+}
+
+/*)Function    VOID    getfid(fid,c)
+ *
+ *             char *  str             a pointer to a string of
+ *                                     maximum length PATH_MAX
+ *             int     c               this is first character to
+ *                                     copy to the string buffer
+ *
+ *     The function getfid() scans the current input text line from
+ *     the current position copying the next string into the external
+ *     string buffer (str).  The string ends when end of line is found.
+ *     Trailing spacers are removed. The maximum number of characters
+ *     copied is PATH_MAX. If the input string is larger than PATH_MAX
+ *     characters then the string is truncated. The string is NULL
+ *     terminated.
+ *
+ *     local variables:
+ *             char *  p               pointer to external string buffer
+ *             int     c               current character value
+ *
+ *     global variables:
+ *             char    ctype[]         a character array which defines the
+ *                                     type of character being processed.
+ *                                     This index is the character
+ *                                     being processed.
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *
+ *     side effects:
+ *             use of get() updates the global pointer ip
+ *             the position in the current input text line.
+ */
+
+VOID
+getfid(str, c)
+register int c;
+char *str;
+{
+       register char *p;
+
+       p = str;
+       do
+       {
+               if (p < &str[PATH_MAX-1])
+                       *p++ = c;
+               c = get();
+               if (c == ';')
+                       while (c)
+                               c = get();
+       } while (c);
+       /* trim trailing spaces */
+       --p;
+       while (p >= str && ctype[(int)*p] == SPACE)
+               --p;
+       /* terminate the string */
+       *(++p) = '\0';
+}
+
+/*)Function    char    getnb()
+ *
+ *     The function getnb() scans the current input text
+ *     line returning the first character not a SPACE or TAB.
+ *
+ *     local variables:
+ *             int     c               current character from input
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *
+ *     side effects:
+ *             use of get() updates the global pointer ip, the position
+ *             in the current input text line
+ */
+
+char
+getnb()
+{
+       register int c;
+
+       while ((c=get())==' ' || c=='\t')
+               ;
+       return (c);
+}
+
+/*)Function    VOID    skip()
+ *
+ *     The function skip() scans the input text skipping all
+ *     letters and digits.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             
+ *     functions called:
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             Input letters and digits are skipped.
+ */
+
+VOID
+skip(c)
+register int c;
+{
+       if (c < 0)
+               c = getnb();
+       while (ctype[c=get()] & (LETTER|DIGIT)) { ; }
+       unget(c);
+}
+
+/*)Function    char    get()
+ *
+ *     The function get() returns the next character in the
+ *     input text line, at the end of the line a
+ *     NULL character is returned.
+ *
+ *     local variables:
+ *             int     c               current character from
+ *                                     input text line
+ *
+ *     global variables:
+ *             char *  ip              pointer into the current
+ *                                     input text line
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             updates ip to the next character position in the
+ *             input text line.  If ip is at the end of the
+ *             line, ip is not updated.
+ */
+
+char
+get()
+{
+       register int c;
+
+       if ((c = *ip) != 0)
+               ++ip;
+       return (c);
+}
+
+/*)Function    VOID    unget(c)
+ *
+ *             int     c               value of last character
+ *                                     read from input text line
+ *
+ *     If (c) is not a NULL character then the global pointer ip
+ *     is updated to point to the preceeding character in the
+ *     input text line.
+ *
+ *     NOTE:   This function does not push the character (c)
+ *             back into the input text line, only
+ *             the pointer ip is changed.
+ *
+ *     local variables:
+ *             int     c               last character read
+ *                                     from input text line
+ *
+ *     global variables:
+ *             char *  ip              position into the current
+ *                                     input text line
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             ip decremented by 1 character position
+ */
+
+VOID
+unget(c)
+{
+       if (c != 0)
+               --ip;
+}
+
+/*)Function    int     getmap(d)
+ *
+ *             int     d               value to compare with the
+ *                                     input text line character
+ *
+ *     The function getmap() converts the 'C' style characters \b, \f,
+ *     \n, \r, and \t to their equivalent ascii values and also
+ *     converts 'C' style octal constants '\123' to their equivalent
+ *     numeric values.  If the first character is equivalent to (d) then
+ *     a (-1) is returned, if the end of the line is detected then
+ *     a 'q' error terminates the parse for this line, or if the first
+ *     character is not a \ then the character value is returned.
+ *
+ *     local variables:
+ *             int     c               value of character
+ *                                     from input text line
+ *             int     n               looping counter
+ *             int     v               current value of numeric conversion
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of get() updates the global pointer ip the position
+ *             in the current input text line
+ */
+
+int
+getmap(d)
+{
+       register int c, n, v;
+
+       if ((c = get()) == '\0')
+               return (-1);
+       if (c == d)
+               return (-1);
+       if (c == '\\') {
+               c = get();
+               switch (c) {
+
+               case 'b':
+                       c = '\b';
+                       break;
+
+               case 'f':
+                       c = '\f';
+                       break;
+
+               case 'n':
+                       c = '\n';
+                       break;
+
+               case 'r':
+                       c = '\r';
+                       break;
+
+               case 't':
+                       c = '\t';
+                       break;
+
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+                       n = 0;
+                       v = 0;
+                       while (++n<=3 && c>='0' && c<='7') {
+                               v = (v<<3) + c - '0';
+                               c = get();
+                       }
+                       unget(c);
+                       c = v;
+                       break;
+               }
+       }
+       return (c);
+}
+
+/*)Function    int     as_getline()
+ *
+ *     The function as_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
+ *     or a (0) if all files have been read.
+ *     This function also opens each input .lst file and output
+ *     .rst file as each .rel file is processed.
+ *
+ *     local variables:
+ *             int     i               string length
+ *             int     ftype           file type
+ *             char *  fid             file name
+ *
+ *     global variables:
+ *             lfile   *cfp            The pointer *cfp points to the
+ *                                     current lfile structure
+ *             lfile   *filep          The pointer *filep points to the
+ *                                     beginning of a linked list of
+ *                                     lfile structures.
+ *             int     gline           get a line from the LST file
+ *                                     to translate for the RST file
+ *             char    ib[NINPUT]      REL file text line
+ *             int     pass            linker pass number
+ *             int     pflag           print linker command file flag
+ *             FILE    *rfp            The file handle to the current
+ *                                     output RST file
+ *             FILE    *sfp            The file handle sfp points to the
+ *                                     currently open file
+ *             FILE *  stdin           c_library
+ *             FILE *  stdout          c_library
+ *             FILE    *tfp            The file handle to the current
+ *                                     LST file being scanned
+ *             int     uflag           update listing flag
+ *
+ *     called functions:
+ *             FILE *  afile()         lkmain.c
+ *             int     fclose()        c_library
+ *             char *  fgets()         c_library
+ *             int     fprintf()       c_library
+ *             VOID    lkulist()       lklist.c
+ *             VOID    lkexit()        lkmain.c
+ *             int     strlen()        c_library
+ *
+ *     side effects:
+ *             The input stream is scanned.  The .rel files will be
+ *             opened and closed sequentially scanning each in turn.
+ */
+
+int
+as_getline()
+{
+       register int ftype;
+       register char *fid;
+
+loop:  if (pflag && cfp && cfp->f_type == F_STD)
+               fprintf(stdout, "ASlink >> ");
+
+       if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) {
+               if (sfp) {
+                       fclose(sfp);
+                       sfp = NULL;
+                       lkulist(0);
+               }
+               if (cfp == NULL) {
+                       cfp = filep;
+               } else {
+                       cfp = cfp->f_flp;
+               }
+               if (cfp) {
+                       ftype = cfp->f_type;
+                       fid = cfp->f_idp;
+                       if (ftype == F_STD) {
+                               sfp = stdin;
+                       } else
+                       if (ftype == F_LNK) {
+                               sfp = afile(fid, "lnk", 0);
+                       } else
+                       if (ftype == F_REL) {
+                               sfp = afile(fid, "rel", 0);
+                               /* if a .cdb file exists then copy it over */
+                               if (dflag && sfp && dfp && pass == 0) {
+                                   FILE *xfp = afile(fid,"adb",0); //JCF: Nov 30, 2002
+                                   if (xfp) {
+                                       copyfile(dfp,xfp);
+                                       fclose(xfp);
+                                   }
+                               }
+                               if (uflag && pass != 0) {
+                                SaveLinkedFilePath(fid); //Save the linked path for aomf51
+                                if ((tfp = afile(fid, "lst", 0)) != NULL) {
+                                 if ((rfp = afile(fid, "rst", 1)) == NULL) {
+                                       fclose(tfp);
+                                       tfp = NULL;
+                                 }
+                                }
+                               }
+                               gline = 1;
+                       } else {
+                               fprintf(stderr, "Invalid file type\n");
+                               lkexit(1);
+                       }
+                       if (sfp == NULL) {
+                               lkexit(1);
+                       }
+                       goto loop;
+               } else {
+                       filep = NULL;
+                       return(0);
+               }
+       }
+       chop_crlf(ib);
+       return (1);
+}
+
+/*)Function    int     more()
+ *
+ *     The function more() scans the input text line
+ *     skipping white space (SPACES and TABS) and returns a (0)
+ *     if the end of the line or a comment delimeter (;) is found,
+ *     or a (1) if their are additional characters in the line.
+ *
+ *     local variables:
+ *             int     c               next character from
+ *                                     the input text line
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of getnb() and unget() updates the global pointer ip
+ *             the position in the current input text line
+ */
+
+int
+more()
+{
+       register int c;
+
+       c = getnb();
+       unget(c);
+       return( (c == '\0' || c == ';') ? 0 : 1 );
+}
+
+/*)Function    char    endline()
+ *
+ *     The function endline() scans the input text line
+ *     skipping white space (SPACES and TABS) and returns the next
+ *     character or a (0) if the end of the line is found or a
+ *     comment delimiter (;) is found.
+ *
+ *     local variables:
+ *             int     c               next character from
+ *                                     the input text line
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    getnb()         lklex.c
+ *
+ *     side effects:
+ *             Use of getnb() updates the global pointer ip the
+ *             position in the current input text line.
+ */
+
+char
+endline()
+{
+       register int c;
+
+       c = getnb();
+       return( (c == '\0' || c == ';') ? 0 : c );
+}
+
+/*)Function    VOID    chop_crlf(str)
+ *
+ *             char    *str            string to chop
+ *
+ *     The function chop_crlf() removes trailing LF or CR/LF from
+ *     str, if present.
+ *
+ *     local variables:
+ *             int     i               string length
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+VOID
+chop_crlf(str)
+char *str;
+{
+       register int i;
+
+       i = strlen(str);
+       if (i >= 1 && str[i-1] == '\n') str[i-1] = 0;
+       if (i >= 2 && str[i-2] == '\r') str[i-2] = 0;
+}
diff --git a/as/link/mcs51/lklibr.c b/as/link/mcs51/lklibr.c
new file mode 100644 (file)
index 0000000..e87c9ec
--- /dev/null
@@ -0,0 +1,1301 @@
+/* lklibr.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * With contributions for the
+ * object libraries from
+ * Ken Hornstein
+ * kenh@cmf.nrl.navy.mil
+ *
+ */
+
+#define EQ(A,B) !strcmp((A),(B))
+#define MAXLINE 254 /*when using fgets*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "aslink.h"
+
+/*)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
+ *
+ *  lklibr.c contains the following functions:
+ *      VOID    addpath()
+ *      VOID    addlib()
+ *      VOID    addfile()
+ *      VOID    search()
+ *      VOID    fndsym()
+ *      VOID    library()
+ *      VOID    loadfile()
+ *
+ */
+
+#ifdef INDEXLIB
+typedef struct slibrarysymbol mlibrarysymbol;
+typedef struct slibrarysymbol *pmlibrarysymbol;
+
+struct slibrarysymbol {
+    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*/
+    long offset; //if > 0, the embedded file offset in the library file libspc
+    pmlibrarysymbol symbols;
+    pmlibraryfile next;
+};
+
+/* First entry in the library object symbol cache */
+pmlibraryfile libr=NULL;
+
+int buildlibraryindex();
+void freelibraryindex (void);
+#endif /* INDEXLIB */
+
+/*)Function VOID    addpath()
+ *
+ *  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
+ *
+ *  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
+ *
+ *  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);
+}
+
+/*)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.
+ *
+ *  This function calls the function addfile() to actually
+ *  add the library file to the search list.
+ *
+ *  local variables:
+ *      lbpath  *lbph       pointer to 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
+ *
+ *  side effects:
+ *      The function addfile() may add the file to
+ *      the library search list.
+ */
+
+VOID
+addlib()
+{
+    struct lbpath *lbph;
+    int foundcount=0;
+
+    unget(getnb());
+
+    if (lbphead == NULL)
+    {
+        foundcount=addfile(NULL, ip);
+    }
+    else
+    {
+        for (lbph=lbphead; lbph; lbph=lbph->next)
+        {
+            foundcount+=addfile(lbph->path, ip);
+        }
+    }
+    if(foundcount == 0)
+    {
+        fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip);
+    }
+}
+
+/*)Function int addfile(path,libfil)
+ *
+ *      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 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
+ *
+ *  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
+ *
+ *  side effects:
+ *      An lbname structure may be created.
+ *
+ *  return:
+ *      1: the library was found
+ *      0: the library was not found
+ */
+
+int addfile(char * path, char * libfil)
+{
+    FILE *fp;
+    char *str;
+    struct lbname *lbnh, *lbn;
+#ifdef  OTHERSYSTEM
+    int libfilinc=0;
+#endif
+
+    if (path != NULL)
+    {
+        str = (char *) new (strlen(path) + strlen(libfil) + 6);
+        strcpy(str,path);
+#ifdef  OTHERSYSTEM
+        if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\'))
+        {
+            strcat(str,"/");
+        }
+#endif
+    }
+    else
+    {
+        str = (char *) new (strlen(libfil) + 5);
+    }
+
+#ifdef  OTHERSYSTEM
+    if ((libfil[0] == '/') || (libfil[0] == '\\'))
+    {
+        libfil++;
+        libfilinc=1;
+    }
+#endif
+
+    strcat(str, libfil);
+    if(strchr(libfil, FSEPX) == NULL)
+    {
+        sprintf(&str[strlen(str)], "%clib", FSEPX);
+    }
+
+    fp=fopen(str, "r");
+    if(fp == NULL)
+    {
+        /*Ok, that didn't work.  Try with the 'libfil' name only*/
+#ifdef  OTHERSYSTEM
+        if(libfilinc) libfil--;
+#endif
+        fp=fopen(libfil, "r");
+        if(fp != NULL)
+        {
+            /*Bingo!  'libfil' is the absolute path of the library*/
+           strcpy(str, libfil);
+            path=NULL;/*This way 'libfil' and 'path' will be rebuilt from 'str'*/
+        }
+    }
+
+    if(path==NULL)
+    {
+        /*'path' can not be null since it is needed to find the '.rel' 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) + 1);
+        strcpy(path, str);
+        for(j=strlen(path)-1; j>=0; j--)
+        {
+            if((path[j] == '/') || (path[j] == '\\'))
+            {
+                strcpy(libfil, &path[j+1]);
+                path[j+1]=0;
+                break;
+            }
+        }
+        if(j<=0) path[0]=0;
+    }
+
+    if (fp != NULL)
+    {
+        fclose(fp);
+        lbnh = (struct lbname *) new (sizeof(struct lbname));
+        if (lbnhead == NULL)
+        {
+            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;
+        return 1;
+    }
+    else
+    {
+        free(str);
+        return 0;
+    }
+}
+
+/*)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.
+ *
+ *  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
+ *
+ *  global variables:
+ *      sym     *symhash[]  array of pointers to symbol tables
+ *
+ *   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.
+ */
+
+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; i<NHASH; ++i) {
+            sp = symhash[i];
+            while (sp) {
+                /* If we find an undefined symbol
+                 * (one where S_DEF is not set), then
+                 * try looking for it.  If we find it
+                 * in any of the libraries then
+                 * increment symfnd.  This will force
+                 * another pass of symbol searching and
+                 * make sure that back references work.
+                 */
+                if ((sp->s_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, "<FILE>"))
+                {
+                    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, "<REL>")) state=2;
+            break;
+            case 2:
+                if(EQ(str, "</REL>")) return;
+                ip = str;
+                link_main();
+            break;
+        }
+    }
+}
+
+/*Load an .adb file embedded in a sdcclib file.  If there is
+something between <ADB> and </ADB> returns 1, otherwise returns 0.
+This way the aomf51 will not have uselless empty modules. */
+
+int LoadAdb(FILE * libfp)
+{
+    char str[MAXLINE+1];
+    int state=0;
+    int ToReturn=0;
+
+    while (fgets(str, MAXLINE, libfp) != NULL)
+    {
+        str[NINPUT+1] = '\0';
+        chop_crlf(str);
+        switch(state)
+        {
+            case 0:
+                if(EQ(str, "<ADB>")) state=1;
+            break;
+            case 1:
+                if(EQ(str, "</ADB>")) return ToReturn;
+                fprintf(dfp, "%s\n", str);
+                ToReturn=1;
+            break;
+        }
+    }
+    return ToReturn;
+}
+
+/*Check for a symbol in a SDCC library.  If found, add the embedded .rel and
+.adb files from the library.  The library must be created with the SDCC
+librarian 'sdcclib' since the linking process depends on the correct file offsets
+embedded in the library 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;
+
+    while(!feof(libfp))
+    {
+        FLine[0]=0;
+        fgets(FLine, MAXLINE, libfp);
+        chop_crlf(FLine);
+
+        switch(state)
+        {
+            case 0:
+                if(EQ(FLine, "<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;
+                }
+            break;
+            case 1:
+                if(EQ(FLine, "<MODULE>"))
+                {
+                    /*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;
+                }
+                else if(EQ(FLine, "</INDEX>"))
+                {
+                    /*Reached the end of the index.  The symbol is not in this library.*/
+                    return 0;
+                }
+            break;
+            case 2:
+                if(EQ(FLine, "</MODULE>"))
+                {
+                    /*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)], "%crel", FSEPX);
+
+                        /*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);
+
+                        /* if cdb information required & .adb file present */
+                        if (dflag && dfp)
+                        {
+                            if(LoadAdb(libfp))
+                                SaveLinkedFilePath(DirLib);
+                        }
+                        return 1; /*Found the symbol, so success!*/
+                    }
+                }
+            break;
+
+            default:
+                return 0; /*It should never reach this point, but just in case...*/
+            break;
+        }
+    }
+
+    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.
+ */
+
+#ifdef INDEXLIB
+
+int fndsym( char *name )
+{
+    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;
+    FirstFound = libr; /*So gcc stops whining*/
+    while (ThisLibr)
+    {
+        /* Iterate through all symbols in an object file */
+        ThisSym = ThisLibr->symbols;
+
+        while (ThisSym)
+        {
+            if (!strcmp(ThisSym->name, name))
+            {
+                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)
+                    {
+                        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);
+                    lbfh->offset = ThisLibr->offset;
+                    if(lbfh->offset>0)
+                    { /*For an embedded object file in a library*/
+                        void loadfile_SdccLib(char * libspc, char * module, long offset);
+                        loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
+                    }
+                    else
+                    { /*For a stand alone object file*/
+                        /* if cdb information required & adb file present */
+                        if (dflag && dfp)
+                        {
+                            FILE *xfp = afile(lbfh->filspc, "adb",0);
+                            if (xfp)
+                            {
+                                SaveLinkedFilePath(lbfh->filspc);
+                                copyfile(dfp, xfp);
+                                fclose(xfp);
+                            }
+                        }
+                        loadfile(lbfh->filspc);
+                    }
+                    ThisLibr->loaded=1;
+                }
+
+                if(numfound==0)
+                {
+                    numfound++;
+                    FirstFound=ThisLibr;
+                }
+                else
+                {
+                    char absPath1[PATH_MAX];
+                    char absPath2[PATH_MAX];
+#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
+                    int j;
+
+                    _fullpath(absPath1, FirstFound->libspc, PATH_MAX);
+                    _fullpath(absPath2, ThisLibr->libspc, PATH_MAX);
+                    for(j=0; absPath1[j]!=0; j++) absPath1[j]=tolower((unsigned char)absPath1[j]);
+                    for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower((unsigned char)absPath2[j]);
+#else
+                    realpath(FirstFound->libspc, absPath1);
+                    realpath(ThisLibr->libspc, absPath2);
+#endif
+                    if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) )
+                    {
+                        if(numfound==1)
+                        {
+                            fprintf(stderr, "?Aslink-Warning-Definition of public symbol '%s'"
+                                   " found more than once:\n", name);
+                            fprintf(stderr, "   Library: '%s', Module: '%s'\n",
+                                    FirstFound->libspc, FirstFound->relfil);
+                        }
+                        fprintf(stderr, "   Library: '%s', Module: '%s'\n",
+                                ThisLibr->libspc, ThisLibr->relfil);
+                        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 buff[PATH_MAX];
+    int state=0;
+    long IndexOffset=0, FileOffset;
+    pmlibrarysymbol ThisSym = NULL;
+
+    while(!feof(libfp))
+    {
+        FLine[0]=0;
+        fgets(FLine, MAXLINE, libfp);
+        chop_crlf(FLine);
+
+        switch(state)
+        {
+            case 0:
+                if(EQ(FLine, "<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;
+                }
+            break;
+            case 1:
+                if(EQ(FLine, "<MODULE>"))
+                {
+                    /*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;
+
+                    /*Create a new libraryfile object for this module*/
+                    if(libr==NULL)
+                    {
+                        libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
+                    }
+                    else
+                    {
+                        This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
+                        This=This->next;
+                    }
+                    This->next = NULL;
+                    This->loaded=-1;
+                    This->offset=FileOffset+IndexOffset;
+                    This->libspc=PathLib;
+
+                    This->relfil=(char *)new(strlen(ModName)+1);
+                    strcpy(This->relfil, ModName);
+
+                    sprintf(buff, "%s%s%crel", DirLib, ModName, FSEPX);
+                    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, "</INDEX>"))
+                {
+                    return This; /*Finish, get out of here*/
+                }
+            break;
+            case 2:
+                if(EQ(FLine, "</MODULE>"))
+                {
+                    This->loaded=0;
+                    /*Create the index for the next module*/
+                    state=1;
+                }
+                else
+                {
+                    /*Add the symbols*/
+                    if(ThisSym==NULL) /*First symbol of the current module*/
+                    {
+                        ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
+                    }
+                    else
+                    {
+                        ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol));
+                        ThisSym=ThisSym->next;
+                    }
+                    ThisSym->next=NULL;
+                    ThisSym->name=(char *)new(strlen(FLine)+1);
+                    strcpy(ThisSym->name, FLine);
+                }
+            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...*/
+}
+
+
+/* buildlibraryindex - build an in-memory cache of the symbols contained in
+ *                     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;
+
+    /*
+     * 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)
+            {
+                strcpy(str, path);
+#ifdef  OTHERSYSTEM
+                if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\'))
+                {
+                    strcat(str,"/");
+                }
+#endif
+            }
+            else
+            {
+                strcpy(str, "");
+            }
+
+            if(strcmp(relfil, "<SDCCLIB>")==0)
+            {
+                /*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] == '\\')
+            {
+                strcat(str,relfil+1);
+            }
+            else
+            {
+                strcat(str,relfil);
+            }
+
+            if(strchr(relfil, FSEPX) == NULL)
+            {
+                sprintf(&str[strlen(str)], "%crel", FSEPX);
+            }
+
+            if ((fp = fopen(str, "r")) != NULL)
+            {
+                /* Opened OK - create a new libraryfile object for it */
+                if(libr==NULL)
+                {
+                    libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
+                }
+                else
+                {
+                    This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
+                    This=This->next;
+                }
+                This->next = NULL;
+                This->loaded=-1;
+                This->offset=-1; /*We have a stand alone .rel file*/
+                This->libspc = lbnh->libspc;
+
+                This->relfil=(char *)new(strlen(relfil)+1);
+                strcpy(This->relfil, relfil);
+
+                This->filename=(char *)new(strlen(str)+1);
+                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';
+
+                    /*
+                     * 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 it's an actual symbol, record it */
+                    if (c == 'D')
+                    {
+                        if(ThisSym==NULL)
+                        {
+                            ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
+                        }
+                        else
+                        {
+                            ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
+                            ThisSym=ThisSym->next;
+                        }
+                        This->loaded=0;
+                        ThisSym->next=NULL;
+                        ThisSym->name=(char *)new(strlen(symname)+1);
+                        strcpy(ThisSym->name, symname);
+                    }
+                } /* 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;
+
+    ThisLibr = libr;
+
+    while (ThisLibr)
+    {
+        ThisSym = ThisLibr->symbols;
+
+        while (ThisSym)
+        {
+            free(ThisSym->name);
+            ThisSym2Free=ThisSym;
+            ThisSym=ThisSym->next;
+            free(ThisSym2Free);
+        }
+        free(ThisLibr->filename);
+        free(ThisLibr->relfil);
+        ThisLibr2Free=ThisLibr;
+        ThisLibr=ThisLibr->next;
+        free(ThisLibr2Free);
+    }
+
+    libr=NULL;
+}
+
+#else /* INDEXLIB */
+
+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".
+     */
+
+    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] != '\\'))
+                {
+                    strcat(str,"/");
+                }
+#endif
+            }
+            else
+            {
+                str = (char *) new (strlen(relfil) + 5);
+            }
+
+            if(strcmp(relfil, "<SDCCLIB>")==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] == '\\')
+            {
+                strcat(str,relfil+1);
+            }
+            else
+            {
+                strcat(str,relfil);
+            }
+
+            if(strchr(relfil, FSEPX) == NULL)
+            {
+                sprintf(&str[strlen(str)], "%crel", FSEPX);
+            }
+
+            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);
+
+                        /* if cdb information required & adb file present */
+                        if (dflag && dfp)
+                        {
+                            FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002
+                            if (xfp)
+                            {
+                                SaveLinkedFilePath(str);
+                                copyfile(dfp,xfp);
+                                fclose(xfp);
+                            }
+                        }
+                        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;
+
+    if ((fp = fopen(libspc,"r")) != NULL)
+    {
+        fseek(fp, offset, SEEK_SET);
+        LoadRel(libspc, fp, module);
+        fclose(fp);
+    }
+}
+
+/*)Function VOID    library()
+ *
+ *  The function library() links all the library object files
+ *  contained in the lbfile structures.
+ *
+ *  local variables:
+ *      lbfile  *lbfh       pointer to lbfile structure
+ *
+ *  global variables:
+ *      lbfile  *lbfhead    pointer to first lbfile structure
+ *
+ *   functions called:
+ *      VOID    loadfile    lklibr.c
+ *
+ *  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);
+        }
+    }
+#ifdef INDEXLIB
+    freelibraryindex();
+#endif
+}
+
+/*)Function VOID    loadfile(filspc)
+ *
+ *      char    *filspc     library object file specification
+ *
+ *  The function loadfile() links the library object module.
+ *
+ *  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
+ *
+ *   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.
+ */
+
+VOID
+loadfile(filspc)
+char *filspc;
+{
+    FILE *fp;
+    char str[NINPUT+2];
+
+    if ((fp = fopen(filspc,"r")) != NULL) {
+        while (fgets(str, NINPUT, fp) != NULL) {
+            str[NINPUT+1] = '\0';
+            chop_crlf(str);
+            ip = str;
+            link_main();
+        }
+        fclose(fp);
+    }
+}
diff --git a/as/link/mcs51/lklist.c b/as/link/mcs51/lklist.c
new file mode 100644 (file)
index 0000000..5325ec8
--- /dev/null
@@ -0,0 +1,1099 @@
+/* lklist.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * 28-Oct-97 JLH: 
+ *           - lstarea: show s_id as string rather than array [NCPS]
+ *           - lstarea: show a_id as string rather than array [NCPS]
+ * 31-Oct-97 JLH: add NoICE output file genration in lstarea
+ * 02-Apr-98 JLH: add XDATA, DATA, BIT flags to area output
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "aslink.h"
+
+/*)Module      lklist.c
+ *
+ *     The module lklist.c contains the functions which
+ *     output the linker .map file and produce a relocated
+ *     listing .rst file.
+ *
+ *     lklist.c contains the following functions:
+ *             int     dgt()
+ *             VOID    lstarea()
+ *             VOID    lkulist()
+ *             VOID    lkalist()
+ *             VOID    lkglist()
+ *             VOID    newpag()
+ *             VOID    slew()
+ *
+ *     lklist.c contains no local variables.
+ */
+
+/*)Function    VOID    slew(fp)
+ *
+ *             FILE *  fp              output file handle
+ *
+ *     The function slew() increments the page line counter.
+ *     If the number of lines exceeds the maximum number of
+ *     lines per page then a page skip and a page header are
+ *     output.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *
+ *     global variables:
+ *             int     lop             current line number on page
+ *             int     xflag           Map file radix type flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    newpag()        lklist.c
+ *
+ *     side effects:
+ *             The page line and the page count may be updated.
+ */
+
+VOID
+slew(fp)
+FILE *fp;
+{
+       register int i;
+
+       if (lop++ >= NLPP) {
+               newpag(fp);
+               if (xflag == 0) {
+                       fprintf(fp, "Hexadecimal\n\n");
+               } else
+               if (xflag == 1) {
+                       fprintf(fp, "Octal\n\n");
+               } else
+               if (xflag == 2) {
+                       fprintf(fp, "Decimal\n\n");
+               }
+               fprintf(fp, "Area       Addr   Size");
+               fprintf(fp, "   Decimal Bytes (Attributes)\n");
+               for(i=0;i<4;++i)
+                       fprintf(fp, "      Value--Global");
+               fprintf(fp, "\n\n");
+               lop += 6;
+       }
+}
+
+/*)Function    VOID    newpag()
+ *
+ *     The function newpag() outputs a page skip, writes the
+ *     first page header line, sets the line count to 1, and
+ *     increments the page counter.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             int     lop             current line number on page
+ *             int     page            current page number
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *
+ *     side effects:
+ *             The page and line counters are updated.
+ */
+
+VOID
+newpag(fp)
+FILE *fp;
+{
+       fprintf(fp, "\fASxxxx Linker %s,  page %u.\n", VERSION, ++page);
+       lop = 1;
+}
+
+/* Used for qsort call in lstsym */
+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);    
+}
+
+
+#if    NCPS-8
+
+/* NCPS != 8 */
+/*)Function    VOID    lstarea(xp)
+ *
+ *             area *  xp              pointer to an area structure
+ *
+ *     The function lstarea() creates the linker map output for
+ *     the area specified by pointer xp.  The generated output
+ *     area header includes the area name, starting address,
+ *     size of area, number of words (in decimal), and the
+ *     area attributes.  The symbols defined in this area are
+ *     sorted by ascending address and output one per line
+ *     in the selected radix.
+ *
+ *     local variables:
+ *             areax * oxp             pointer to an area extension structure
+ *             int     c               character value
+ *             int     i               loop counter
+ *             int     j               bubble sort update status
+ *             char *  ptr             pointer to an id string
+ *             int     nmsym           number of symbols in area
+ *             Addr_T  a0              temporary
+ *             Addr_T  ai              temporary
+ *             Addr_T  aj              temporary
+ *             sym *   sp              pointer to a symbol structure
+ *             sym **  p               pointer to an array of
+ *                                     pointers to symbol structures
+ *
+ *     global variables:
+ *             FILE    *mfp            Map output file handle
+ *             sym *symhash[NHASH]     array of pointers to NHASH
+ *                                     linked symbol lists
+ *             int     xflag           Map file radix type flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    free()          c_library
+ *             char *  malloc()        c_library
+ *             char    putc()          c_library
+ *             VOID    slew()          lklist.c
+ *
+ *     side effects:
+ *             Map output generated.
+ */
+
+VOID
+lstarea(xp)
+struct area *xp;
+{
+       register struct areax *oxp;
+       register int i;
+       /* int j; */
+       register char *ptr;
+       int nmsym;
+       /* Addr_T a0; */
+       Addr_T     ai, aj;
+       struct sym *sp;
+       struct sym **p;
+       int memPage;
+
+       putc('\n', mfp);
+       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 %s (Attributes)\n",
+               (xp->a_flag & A_BIT)?"Bits ":"Bytes");/* JCF: For BIT print bits...*/
+       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. %s ", aj,
+               (xp->a_flag & A_BIT)?"bits ":"bytes"); /* JCF: For BIT print bits...*/
+       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");
+       }
+
+       memPage = 0x00;
+       if (xp->a_flag & A_CODE) {
+               fprintf(mfp, ",CODE");
+               memPage = 0x0C;
+       }
+       if (xp->a_flag & A_XDATA) {
+               fprintf(mfp, ",XDATA");
+               memPage = 0x0D;
+       }
+       if (xp->a_flag & A_BIT) {
+               fprintf(mfp, ",BIT");
+               memPage = 0x0B;
+       }
+       fprintf(mfp, ")");
+       if (xp->a_flag & A_PAG) {
+               ai = (ai & 0xFF);
+               aj = (aj > 256);
+               if (ai || aj) { fprintf(mfp, "  "); }
+               if (ai)      { fprintf(mfp, " Boundary"); }
+               if (ai & aj)  { fprintf(mfp, " /"); }
+               if (aj)      { fprintf(mfp, " Length"); }
+               if (ai || aj) { fprintf(mfp, " Error"); }
+       }
+
+       /*
+        * Find number of symbols in area
+        */
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp)
+                                       ++nmsym;
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+       if (nmsym == 0) {
+               putc('\n', mfp);
+               return;
+       }
+
+       /*
+        * Allocate space for an array of pointers to symbols
+        * and load array.
+        */
+       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
+               == NULL) {
+               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
+               return;
+       }
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp) {
+                                       p[nmsym++] = sp;
+                               }
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+
+#if 0
+       /*
+        * Bubble Sort of Addresses in Symbol Table Array
+        */
+       j = 1;
+       while (j) {
+               j = 0;
+               sp = p[0];
+               a0 = sp->s_addr + sp->s_axp->a_addr;
+               for (i=1; i<nmsym; ++i) {
+                       sp = p[i];
+                       ai = sp->s_addr + sp->s_axp->a_addr;
+                       if (a0 > ai) {
+                               j = 1;
+                               p[i] = p[i-1];
+                               p[i-1] = sp;
+                       }
+                       a0 = ai;
+               }
+       }
+#else
+       qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr);
+#endif 
+
+       /*
+        * Symbol Table Output
+        */
+
+       i = 0;
+       fprintf(mfp, "\n\n");
+       fprintf(mfp, "      Value  Global\n");
+       fprintf(mfp, "   --------  --------------------------------");
+       while (i < nmsym) {
+               fprintf(mfp, "\n");
+               if (memPage != 0) 
+                       fprintf(mfp, "  %02X:", memPage);
+               else
+                       fprintf(mfp, "     ");
+
+               sp = p[i];
+               aj = sp->s_addr + sp->s_axp->a_addr;
+               if (xflag == 0) {
+                       fprintf(mfp, "%04X    ", aj);
+               } else
+               if (xflag == 1) {
+                       fprintf(mfp, "%06o  ", aj);
+               } else
+               if (xflag == 2) {
+                       fprintf(mfp, "%05u   ", aj);
+               }
+               ptr = &sp->s_id[0];
+               fprintf(mfp, "%s", ptr );
+               
+               /* if cdb flag set the output cdb Information 
+                  and the symbol has a '$' sign in it then */
+               if (dflag &&
+                   strchr(ptr,'$'))
+                   fprintf(dfp,"L:%s:%X\n",ptr,aj);
+
+               /* NoICE output of symbol */
+               if (jflag) DefineNoICE( ptr, aj, memPage );
+
+               i++;
+       }
+       putc('\n', mfp);
+       free(p);
+}
+
+#else
+
+/* NCPS == 8 */
+/*)Function    VOID    lstarea(xp)
+ *
+ *             area *  xp              pointer to an area structure
+ *
+ *     The function lstarea() creates the linker map output for
+ *     the area specified by pointer xp.  The generated output
+ *     area header includes the area name, starting address,
+ *     size of area, number of words (in decimal), and the
+ *     area attributes.  The symbols defined in this area are
+ *     sorted by ascending address and output four per line
+ *     in the selected radix.
+ *
+ *     local variables:
+ *             areax * oxp             pointer to an area extension structure
+ *             int     c               character value
+ *             int     i               loop counter
+ *             int     j               bubble sort update status
+ *             char *  ptr             pointer to an id string
+ *             int     nmsym           number of symbols in area
+ *             Addr_T  a0              temporary
+ *             Addr_T  ai              temporary
+ *             Addr_T  aj              temporary
+ *             sym *   sp              pointer to a symbol structure
+ *             sym **  p               pointer to an array of
+ *                                     pointers to symbol structures
+ *
+ *     global variables:
+ *             FILE    *mfp            Map output file handle
+ *             sym *symhash[NHASH]     array of pointers to NHASH
+ *                                     linked symbol lists
+ *             int     xflag           Map file radix type flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    free()          c_library
+ *             char *  malloc()        c_library
+ *             char    putc()          c_library
+ *             VOID    slew()          lklist.c
+ *
+ *     side effects:
+ *             Map output generated.
+ */
+
+VOID
+lstarea(xp)
+struct area *xp;
+{
+       register struct areax *oxp;
+       register c, i, j;
+       register char *ptr;
+       int nmsym;
+       Addr_T a0, ai, aj;
+       struct sym *sp;
+       struct sym **p;
+        int page;
+
+       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");
+       }
+
+       page = 0x00;
+       if (xp->a_flag & A_CODE) {
+               fprintf(mfp, ",CODE");
+               memPage = 0x0C;
+       }
+       if (xp->a_flag & A_XDATA) {
+               fprintf(mfp, ",XDATA");
+               memPage = 0x0D;
+       }
+       if (xp->a_flag & A_BIT) {
+               fprintf(mfp, ",BIT");
+               memPage = 0x0B;
+       }
+       fprintf(mfp, ")");
+       if (xp->a_flag & A_PAG) {
+               ai = (ai & 0xFF);
+               aj = (aj > 256);
+               if (ai || aj) { fprintf(mfp, "  "); }
+               if (ai)      { fprintf(mfp, " Boundary"); }
+               if (ai & aj)  { fprintf(mfp, " /"); }
+               if (aj)      { fprintf(mfp, " Length"); }
+               if (ai || aj) { fprintf(mfp, " Error"); }
+       }
+
+       /*
+        * Find number of symbols in area
+        */
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp)
+                                       ++nmsym;
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+       if (nmsym == 0) {
+               putc('\n', mfp);
+               slew(mfp);
+               return;
+       }
+
+       /*
+        * Allocate space for an array of pointers to symbols
+        * and load array.
+        */
+       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
+               == NULL) {
+               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
+               slew(mfp);
+               return;
+       }
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp) {
+                                       p[nmsym++] = sp;
+                               }
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+
+#if 0
+       /*
+        * Bubble Sort of Addresses in Symbol Table Array
+        */
+       j = 1;
+       while (j) {
+               j = 0;
+               sp = p[0];
+               a0 = sp->s_addr + sp->s_axp->a_addr;
+               for (i=1; i<nmsym; ++i) {
+                       sp = p[i];
+                       ai = sp->s_addr + sp->s_axp->a_addr;
+                       if (a0 > ai) {
+                               j = 1;
+                               p[i] = p[i-1];
+                               p[i-1] = sp;
+                       }
+                       a0 = ai;
+               }
+       }
+#else
+       qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr);
+#endif 
+
+       /*
+        * Symbol Table Output
+        */
+       i = 0;
+       while (i < nmsym) {
+               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", ptr );
+
+               /* NoICE output of symbol */
+               if (jflag) DefineNoICE( ptr, aj, memPage );
+       }
+       putc('\n', mfp);
+       free(p);
+       slew(mfp);
+}
+#endif
+
+/*)Function    VOID    lkulist(i)
+ *
+ *             int     i       i # 0   process LST to RST file
+ *                             i = 0   copy remainder of LST file
+ *                                     to RST file and close files
+ *
+ *     The function lkulist() creates a relocated listing (.rst)
+ *     output file from the ASxxxx assembler listing (.lst)
+ *     files.  The .lst file's program address and code bytes
+ *     are changed to reflect the changes made by ASlink as
+ *     the .rel files are combined into a single relocated
+ *     output file.
+ *
+ *     local variables:
+ *             Addr_T  pc              current program counter address
+ *
+ *     global variables:
+ *             int     hilo            byte order
+ *             int     gline           get a line from the LST file
+ *                                     to translate for the RST file
+ *             char    rb[]            read listing file text line
+ *             FILE    *rfp            The file handle to the current
+ *                                     output RST file
+ *             int     rtcnt           count of data words
+ *             int     rtflg[]         output the data flag
+ *             Addr_T  rtval[]         relocated data
+ *             FILE    *tfp            The file handle to the current
+ *                                     LST file being scanned
+ *
+ *     functions called:
+ *             int     fclose()        c_library
+ *             int     fgets()         c_library
+ *             int     fprintf()       c_library
+ *             VOID    lkalist()       lklist.c
+ *             VOID    lkglist()       lklist.c
+ *
+ *     side effects:
+ *             A .rst file is created for each available .lst
+ *             file associated with a .rel file.
+ */
+
+VOID
+lkulist(i)
+int i;
+{
+       Addr_T pc;
+
+       /*
+        * Exit if listing file is not open
+        */
+       if (tfp == NULL)
+               return;
+
+       /*
+        * Normal processing of LST to RST
+        */
+       if (i) {
+               /*
+                * Evaluate current code address
+                */
+               if (hilo == 0) {
+                       pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF);
+               } else {
+                       pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF);
+               }
+
+               /*
+                * Line with only address
+                */
+               if (rtcnt == 2) {
+                       lkalist(pc);
+
+               /*
+                * Line with address and code
+                */
+               } else {
+                       for (i=2; i < rtcnt; i++) {
+                               if (rtflg[i]) {
+                                       lkglist(pc++, rtval[i] & 0xFF);
+                               }
+                       }
+               }
+
+       /*
+        * Copy remainder of LST to RST
+        */
+       } else {
+               if (gline == 0)
+                       fprintf(rfp, "%s", rb);
+
+               while (fgets(rb, sizeof(rb), tfp) != 0) {
+                       fprintf(rfp, "%s", rb);
+               }
+               fclose(tfp);
+               tfp = NULL;
+               fclose(rfp);
+               rfp = NULL;
+       }
+}
+
+/*)Function    VOID    lkalist(pc)
+ *
+ *             int     pc              current program counter value
+ *
+ *     The function lkalist() performs the following functions:
+ *
+ *     (1)     if the value of gline = 0 then the current listing
+ *             file line is copied to the relocated listing file output.
+ *
+ *     (2)     the listing file is read line by line and copied to
+ *             the relocated listing file until a valid source
+ *             line number and a program counter value of the correct
+ *             radix is found.  The new relocated pc value is substituted
+ *             and the line is written to the RST file.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *             char    str[]           temporary string
+ *
+ *     global variables:
+ *             int     gcntr           data byte counter
+ *             int     gline           get a line from the LST file
+ *                                     to translate for the RST file
+ *             char    rb[]            read listing file text line
+ *             char    *rp             pointer to listing file text line
+ *             FILE    *rfp            The file handle to the current
+ *                                     output RST file
+ *             FILE    *tfp            The file handle to the current
+ *                                     LST file being scanned
+ *
+ *     functions called:
+ *             int     dgt()           lklist.c
+ *             int     fclose()        c_library
+ *             int     fgets()         c_library
+ *             int     fprintf()       c_library
+ *             int     sprintf()       c_library
+ *             char *  strncpy()       c_library
+ *
+ *     side effects:
+ *             Lines of the LST file are copied to the RST file,
+ *             the last line copied has the code address
+ *             updated to reflect the program relocation.
+ */
+
+VOID
+lkalist(pc)
+Addr_T pc;
+{
+       char str[8];
+       int i;
+
+       /*
+        * Exit if listing file is not open
+        */
+loop:  if (tfp == NULL)
+               return;
+
+       /*
+        * Copy current LST to RST
+        */
+       if (gline == 0) {
+               fprintf(rfp, "%s", rb);
+               gline = 1;
+       }
+
+       /*
+        * Clear text line buffer
+        */
+       for (i=0,rp=rb; i<sizeof(rb); i++) {
+               *rp++ = 0;
+       }
+
+       /*
+        * Get next LST text line
+        */
+       if (fgets(rb, sizeof(rb), tfp) == NULL) {
+               fclose(tfp);
+               tfp = NULL;
+               fclose(rfp);
+               rfp = NULL;
+               return;
+       }
+
+       /*
+        * Must have an ASxxxx Listing line number
+        */
+       if (!dgt(RAD10, &rb[30], 1)) {
+               fprintf(rfp, "%s", rb);
+               goto loop;
+       }
+
+       /*
+        * Must have an address in the expected radix
+        */
+       if (radix == 16) {
+               if (!dgt(RAD16, &rb[3], 4)) {
+                       fprintf(rfp, "%s", rb);
+                       goto loop;
+               }
+               sprintf(str, "%04X", pc);
+               strncpy(&rb[3], str, 4);
+       } else
+       if (radix == 10) {
+               if (!dgt(RAD10, &rb[3], 5)) {
+                       fprintf(rfp, "%s", rb);
+                       goto loop;
+               }
+               sprintf(str, "%05d", pc);
+               strncpy(&rb[3], str, 5);
+       } else
+       if (radix == 8) {
+               if (!dgt(RAD8, &rb[3], 6)) {
+                       fprintf(rfp, "%s", rb);
+                       goto loop;
+               }
+               sprintf(str, "%06o", pc);
+               strncpy(&rb[3], str, 6);
+       }
+
+       /*
+        * Copy updated LST text line to RST
+        */
+       fprintf(rfp, "%s", rb);
+       gcntr = 0;
+}
+
+/*)Function    VOID    lkglist(pc,v)
+ *
+ *             int     pc              current program counter value
+ *             int     v               value of byte at this address
+ *
+ *     The function lkglist() performs the following functions:
+ *
+ *     (1)     if the value of gline = 1 then the listing file
+ *             is read line by line and copied to the
+ *             relocated listing file until a valid source
+ *             line number and a program counter value of the correct
+ *             radix is found.
+ *
+ *     (2)     The new relocated values and code address are
+ *             substituted and the line may be written to the RST file.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *             char    str[]           temporary string
+ *
+ *     global variables:
+ *             int     gcntr           data byte counter
+ *                                     set to -1 for a continuation line
+ *             int     gline           get a line from the LST file
+ *                                     to translate for the RST file
+ *             char    rb[]            read listing file text line
+ *             char    *rp             pointer to listing file text line
+ *             FILE    *rfp            The file handle to the current
+ *                                     output RST file
+ *             FILE    *tfp            The file handle to the current
+ *                                     LST file being scanned
+ *
+ *     functions called:
+ *             int     dgt()           lklist.c
+ *             int     fclose()        c_library
+ *             int     fgets()         c_library
+ *             int     fprintf()       c_library
+ *             int     sprintf()       c_library
+ *             char *  strncpy()       c_library
+ *
+ *     side effects:
+ *             Lines of the LST file are copied to the RST file
+ *             with updated data values and code addresses.
+ */
+
+VOID
+lkglist(pc,v)
+Addr_T pc;
+int v;
+{
+       char str[8];
+       int i;
+
+       /*
+        * Exit if listing file is not open
+        */
+loop:  if (tfp == NULL)
+               return;
+
+       /*
+        * Get next LST text line
+        */
+       if (gline) {
+               /*
+                * Clear text line buffer
+                */
+               for (i=0,rp=rb; i<sizeof(rb); i++) {
+                       *rp++ = 0;
+               }
+
+               /*
+                * Get next LST text line
+                */
+               if (fgets(rb, sizeof(rb), tfp) == NULL) {
+                       fclose(tfp);
+                       tfp = NULL;
+                       fclose(rfp);
+                       rfp = NULL;
+                       return;
+               }
+
+               /*
+                * Check for a listing line number if required
+                */
+               if (gcntr != -1) {
+                       if (!dgt(RAD10, &rb[30], 1)) {
+                               fprintf(rfp, "%s", rb);
+                               goto loop;
+                       }
+                       gcntr = 0;
+               }
+               gline = 0;
+       }
+
+       /*
+        * Hex Listing
+        */
+       if (radix == 16) {
+               /*
+                * Data Byte Pointer
+                */
+               if (gcntr == -1) {
+                       rp = &rb[8];
+               } else {
+                       rp = &rb[8 + (3 * gcntr)];
+               }
+               /*
+                * Number must be of proper radix
+                */
+               if (!dgt(RAD16, rp, 2)) {
+                       fprintf(rfp, "%s", rb);
+                       gline = 1;
+                       goto loop;
+               }
+               /*
+                * Output new data value, overwrite relocation codes
+                */
+               sprintf(str, " %02X", v);
+               strncpy(rp-1, str, 3);
+               if (gcntr == -1) {
+                       gcntr = 0;
+               }
+               /*
+                * Output relocated code address
+                */
+               if (gcntr == 0) {
+                       if (dgt(RAD16, &rb[3], 4)) {
+                               sprintf(str, "%04X", pc);
+                               strncpy(&rb[3], str, 4);
+                       }
+               }
+               /*
+                * Output text line when updates finished
+                */
+               if (++gcntr == 6) {
+                       fprintf(rfp, "%s", rb);
+                       gline = 1;
+                       gcntr = -1;
+               }
+       } else
+       /*
+        * Decimal Listing
+        */
+       if (radix == 10) {
+               /*
+                * Data Byte Pointer
+                */
+               if (gcntr == -1) {
+                       rp = &rb[9];
+               } else {
+                       rp = &rb[9 + (3 * gcntr)];
+               }
+               /*
+                * Number must be of proper radix
+                */
+               if (!dgt(RAD10, rp, 3)) {
+                       fprintf(rfp, "%s", rb);
+                       gline = 1;
+                       goto loop;
+               }
+               /*
+                * Output new data value, overwrite relocation codes
+                */
+               sprintf(str, " %03d", v);
+               strncpy(rp-1, str, 4);
+               if (gcntr == -1) {
+                       gcntr = 0;
+               }
+               /*
+                * Output relocated code address
+                */
+               if (gcntr == 0) {
+                       if (dgt(RAD10, &rb[3], 5)) {
+                               sprintf(str, "%05d", pc);
+                               strncpy(&rb[3], str, 5);
+                       }
+               }
+               /*
+                * Output text line when updates finished
+                */
+               if (++gcntr == 4) {
+                       fprintf(rfp, "%s", rb);
+                       gline = 1;
+                       gcntr = -1;
+               }
+       } else
+       /*
+        * Octal Listing
+        */
+       if (radix == 8) {
+               /*
+                * Data Byte Pointer
+                */
+               if (gcntr == -1) {
+                       rp = &rb[10];
+               } else {
+                       rp = &rb[10 + (3 * gcntr)];
+               }
+               /*
+                * Number must be of proper radix
+                */
+               if (!dgt(RAD8, rp, 3)) {
+                       fprintf(rfp, "%s", rb);
+                       gline = 1;
+                       goto loop;
+               }
+               /*
+                * Output new data value, overwrite relocation codes
+                */
+               sprintf(str, " %03o", v);
+               strncpy(rp-1, str, 4);
+               if (gcntr == -1) {
+                       gcntr = 0;
+               }
+               /*
+                * Output relocated code address
+                */
+               if (gcntr == 0) {
+                       if (dgt(RAD8, &rb[3], 6)) {
+                               sprintf(str, "%06o", pc);
+                               strncpy(&rb[3], str, 6);
+                       }
+               }
+               /*
+                * Output text line when updates finished
+                */
+               if (++gcntr == 4) {
+                       fprintf(rfp, "%s", rb);
+                       gline = 1;
+                       gcntr = -1;
+               }
+       }
+}
+
+/*)Function    int     dgt(rdx,str,n)
+ *
+ *             int     rdx             radix bit code
+ *             char    *str            pointer to the test string
+ *             int     n               number of characters to check
+ *
+ *     The function dgt() verifies that the string under test
+ *     is of the specified radix.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *
+ *     global variables:
+ *             ctype[]                 array of character types
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+int
+dgt(rdx, str, n)
+int rdx, n;
+char *str;
+{
+       int i;
+
+       for (i=0; i<n; i++) {
+               if ((ctype[(int)*str++] & rdx) == 0)
+                       return(0);
+       }
+       return(1);
+}
diff --git a/as/link/mcs51/lkmain.c b/as/link/mcs51/lkmain.c
new file mode 100644 (file)
index 0000000..43392b8
--- /dev/null
@@ -0,0 +1,1444 @@
+/* lkmain.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * 31-Oct-97 JLH:
+ *           - add jflag and jfp to control NoICE output file genration
+ *  3-Nov-97 JLH:
+ *           - use a_type == 0 as "virgin area" flag: set == 1 if -b
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+#ifdef WIN32T
+#include <time.h>
+
+void Timer(int action, char * message)
+{
+    static double start, end, total=0.0;
+    static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC;
+
+    if(action==0) start=clock()*secs_per_tick;
+    else if(action==1)
+    {
+        end=clock() * secs_per_tick;
+        printf("%s \t%f seconds.\n", message, (end-start));
+        total+=end-start;
+    }
+    else
+    {
+        printf("Total time: \t%f seconds.\n", total);
+        total=0.0;
+    }
+}
+#endif
+
+/*)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
+ *
+ */
+
+/*JCF:  Creates some of the default areas so they are allocated in the right order.*/
+void Areas51 (void)
+{
+    char * rel[]={
+        "XH",
+        "H 7 areas 0 global symbols",
+        "A _CODE size 0 flags 0",       /*Each .rel has one, so...*/
+        "A REG_BANK_0 size 0 flags 4",  /*Register banks are overlayable*/
+        "A REG_BANK_1 size 0 flags 4",
+        "A REG_BANK_2 size 0 flags 4",
+        "A REG_BANK_3 size 0 flags 4",
+        "A BSEG size 0 flags 80",       /*BSEG must be just before BITS*/
+        "A BSEG_BYTES size 0 flags 0",  /*Size will be obtained from BSEG in lnkarea()*/
+        ""
+    };
+
+    char * rel2[]={
+        "XH",
+        "H C areas 0 global symbols",
+        "A _CODE size 0 flags 0",       /*Each .rel has one, so...*/
+        "A REG_BANK_0 size 0 flags 4",  /*Register banks are overlayable*/
+        "A REG_BANK_1 size 0 flags 4",
+        "A REG_BANK_2 size 0 flags 4",
+        "A REG_BANK_3 size 0 flags 4",
+        "A BSEG size 0 flags 80",       /*BSEG must be just before BITS*/
+        "A BSEG_BYTES size 0 flags 0",  /*Size will be obtained from BSEG in lnkarea()*/
+        "A BIT_BANK size 0 flags 4",    /*Bit register bank is overlayable*/
+        "A DSEG size 0 flags 0",
+        "A OSEG size 0 flags 4",
+        "A ISEG size 0 flags 0",
+        "A SSEG size 0 flags 4",
+        ""
+    };
+    int j;
+    struct sym * sp;
+
+    if(packflag)
+    {
+        for (j=0; rel2[j][0]!=0; j++)
+        {
+            ip=rel2[j];
+            link_main();
+        }
+    }
+    else
+    {
+        for (j=0; rel[j][0]!=0; j++)
+        {
+            ip=rel[j];
+            link_main();
+        }
+    }
+
+    /*Set the start address of the default areas:*/
+    for(ap=areap; ap; ap=ap->a_ap)
+    {
+        /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; }
+        else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; }
+        else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; }
+        else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; }
+        else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; }
+        else if (!strcmp(ap->a_id, "SSEG"))
+        {
+            if(stacksize) ap->a_axp->a_size=stacksize;
+        }
+    }
+
+    sp = lkpsym("l_IRAM", 1);
+    sp->s_addr = ((iram_size>0) && (iram_size<=0x100)) ? iram_size : 0x0100;
+    sp->s_axp = NULL;
+    sp->s_type |= S_DEF;
+}
+
+/*)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 as_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     as_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).
+ */
+
+int
+main(int argc, char *argv[])
+{
+    register char *p;
+    register int c, i;
+
+#ifdef WIN32T
+    Timer(0, "");
+#endif
+
+    startp = (struct lfile *) new (sizeof (struct lfile));
+
+    pflag = 1;
+    for (i=1; i<argc; ++i) {
+        p = argv[i];
+        if (*p == '-') {
+            while (ctype[c = *(++p)] & LETTER) {
+                switch(c) {
+
+                case 'c':
+                case 'C':
+                    startp->f_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();
+                }
+            }
+        } else {
+            if (startp->f_type == F_LNK) {
+                startp->f_idp = p;
+            }
+        }
+    }
+    if (startp->f_type == 0)
+        usage();
+    if (startp->f_type == F_LNK && startp->f_idp == NULL)
+        usage();
+
+    cfp = NULL;
+    sfp = NULL;
+    filep = startp;
+    while (1) {
+        ip = ib;
+        if (as_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();
+
+    syminit();
+
+    if (dflag){
+        //dfp = afile("temp", "cdb", 1);
+        SaveLinkedFilePath(linkp->f_idp); //Must be the first one...
+        dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002
+        if (dfp == NULL)
+        lkexit(1);
+    }
+
+    for (pass=0; pass<2; ++pass) {
+        cfp = NULL;
+        sfp = NULL;
+        filep = linkp;
+        hp = NULL;
+        radix = 10;
+
+        Areas51(); /*JCF: Create the default 8051 areas in the right order*/
+
+        while (as_getline()) {
+            ip = ib;
+
+            /* pass any "magic comments" to NoICE output */
+            if ((ip[0] == ';') && (ip[1] == '!') && jfp) {
+                fprintf( jfp, "%s\n", &ip[2] );
+            }
+            link_main();
+        }
+        if (pass == 0) {
+            /*
+             * Search libraries for global symbols
+             */
+            search();
+            /*
+             * Set area base addresses.
+             */
+            setbas();
+            /*
+             * Link all area addresses.
+             */
+            if(!packflag)
+                lnkarea();
+            else
+                lnkarea2();
+            /*
+             * Process global definitions.
+             */
+            setgbl();
+            /*
+             * Check for undefined globals.
+             */
+            symdef(stderr);
+
+            /* Open NoICE output file if requested */
+            if (jflag) {
+                jfp = afile(linkp->f_idp, "NOI", 1);
+                if (jfp == NULL) {
+                    lkexit(1);
+                }
+            }
+
+            /*
+             * Output Link Map if requested,
+             * or if NoICE output requested (since NoICE
+             * file is generated in part by map() processing)
+             */
+            if (mflag || jflag)
+                map();
+
+            if (sflag) /*JCF: memory usage summary output*/
+            {
+                if(!packflag)
+                {
+                    if(summary(areap)) lkexit(1);
+                }
+                else
+                {
+                    if(summary2(areap)) lkexit(1);
+                }
+            }
+
+            if ((iram_size) && (!packflag))
+                iramcheck();
+
+            /*
+             * Open output file
+             */
+            if (oflag == 1) {
+                ofp = afile(linkp->f_idp, "ihx", 1);
+                if (ofp == NULL) {
+                    lkexit(1);
+                }
+                /* include NoICE command to load hex file */
+                if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp );
+
+            } else
+            if (oflag == 2) {
+                ofp = afile(linkp->f_idp, "S19", 1);
+                if (ofp == NULL) {
+                    lkexit(1);
+                }
+                /* include NoICE command to load hex file */
+                if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp );
+            }
+        } else {
+            /*
+             * Link in library files
+             */
+            library();
+            reloc('E');
+        }
+    }
+    //JCF:
+    CreateAOMF51();
+
+#ifdef WIN32T
+    Timer(1, "Linker execution time");
+#endif
+
+    lkexit(lkerr);
+    return 0;
+}
+
+/*)Function VOID    lkexit(i)
+ *
+ *      int     i       exit code
+ *
+ *  The function lkexit() explicitly closes all open
+ *  files and then terminates the program.
+ *
+ *  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
+ *
+ *  functions called:
+ *      int     fclose()    c_library
+ *      VOID    exit()      c_library
+ *
+ *  side effects:
+ *      All files closed. Program terminates.
+ */
+
+VOID
+lkexit(int i)
+{
+    if (mfp != NULL) fclose(mfp);
+    if (jfp != NULL) fclose(jfp);
+    if (ofp != NULL) fclose(ofp);
+    if (rfp != NULL) fclose(rfp);
+    if (sfp != NULL) fclose(sfp);
+    if (tfp != NULL) fclose(tfp);
+    if (dfp != NULL) fclose(dfp);
+    /*if (dfp != NULL)
+        FILE *xfp = afile(linkp->f_idp,"cdb",1);
+        dfp = freopen("temp.cdb","r",dfp);
+        copyfile(xfp,dfp);
+        fclose(xfp);
+        fclose(dfp);
+        remove("temp.cdb");
+    }*/
+    exit(i);
+}
+
+/*)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_main()
+{
+    register char 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)
+                {
+                    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)
+        {
+            strcpy(curr_module, &ip[1]);
+            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;
+        }
+    }
+}
+
+
+/*)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.
+ */
+
+VOID
+map()
+{
+    register int i;
+    register struct head *hdp;
+    register struct lbfile *lbfh;
+
+    /*
+     * Open Map File
+     */
+    mfp = afile(linkp->f_idp, "map", 1);
+    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;
+    filep = linkp;
+    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);
+}
+
+/*)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;
+
+                case 'm':
+                case 'M':
+                    ++mflag;
+                    break;
+
+                case 'y': /*JCF: memory usage summary output*/
+                    ++sflag;
+                    break;
+
+                case 'Y':
+                    unget(getnb());
+                    packflag=1;
+                    break;
+
+                case 'A':
+                    unget(getnb());
+                    if (ip && *ip)
+                    {
+                        stacksize=expr(0);
+                        if(stacksize>256) stacksize=256;
+                        else if(stacksize<0) stacksize=0;
+                    }
+                    return(0);
+
+                case 'j':
+                case 'J':
+                    jflag = 1;
+                    break;
+
+                case 'u':
+                case 'U':
+                    uflag = 1;
+                    break;
+                case 'r':
+                case 'R':
+                    rflag = 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);
+
+                case 'a':
+                    iramsav();
+                    return(0);
+
+                case 'v':
+                case 'V':
+                    xramsav();
+                    return(0);
+
+                case 'w':
+                case 'W':
+                    codesav();
+                    return(0);
+
+                case 'z':
+                case 'Z':
+                        dflag = 1;
+                    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()
+ *
+ *  The function bassav() creates a linked structure containing
+ *  the base address strings input to the linker.
+ *
+ *  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[]
+ *
+ *   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.
+ */
+
+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);
+}
+
+/*)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) {
+                fprintf(stderr,
+                "ASlink-Warning-No definition of area %s\n", id);
+                lkerr++;
+            } else {
+                ap->a_addr = v;
+                ap->a_type = 1; /* JLH: value set */
+            }
+        } else {
+            fprintf(stderr, "ASlink-Warning-No '=' in base expression");
+            lkerr++;
+        }
+        bsp = bsp->b_base;
+    }
+}
+
+/*)Function VOID    gblsav()
+ *
+ *  The function gblsav() creates a linked structure containing
+ *  the global variable strings input to the linker.
+ *
+ *  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
+ *
+ *  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.
+ */
+
+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);
+}
+
+/*)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) {
+                fprintf(stderr,
+                "No definition of symbol %s\n", id);
+                lkerr++;
+            } else {
+                if (sp->s_flag & S_DEF) {
+                    fprintf(stderr,
+                    "Redefinition of symbol %s\n", id);
+                    lkerr++;
+                    sp->s_axp = NULL;
+                }
+                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:
+ *      char    fb[]        constructed file specification string
+ *      FILE *  fp          filehandle for opened file
+ *
+ *  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(char *fn, char *ft, int wf)
+{
+    FILE *fp;
+    char fb[PATH_MAX];
+    char *omode = (wf ? (wf == 2 ? "a" : "w") : "r");
+    int i;
+
+    /*Look backward the name path and get rid of the extension, if any*/
+    i=strlen(fn);
+    for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--);
+    if( (fn[i]=='.') && strcmp(ft, "lnk") )
+    {
+        strncpy(fb, fn, i);
+        fb[i]=0;
+    }
+    else
+    {
+        strcpy(fb, fn);
+    }
+
+    /*Add the extension*/
+    if (fb[i] != '.')
+    {
+        strcat(fb, ".");
+        strcat(fb, strlen(ft)?ft:"rel");
+    }
+
+    fp = fopen(fb, omode);
+    if (fp==NULL)
+    {
+        if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/
+        {
+            fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
+            lkerr++;
+        }
+    }
+    return (fp);
+}
+
+/*)Function VOID    iramsav()
+ *
+ *  The function iramsav() stores the size of the chip's internal RAM.
+ *  This is used after linking to check that variable assignment to this
+ *  dataspace didn't overflow into adjoining segments.  Variables in the
+ *  DSEG, OSEG, and ISEG are assigned to this dataspace.
+ *
+ *  local variables:
+ *      none
+ *
+ *  global variables:
+ *      char    *ip         pointer into the REL file
+ *                          text line in ib[]
+ *      unsigned int        size of chip's internal
+ *          iram_size       RAM segment
+ *
+ *   functions called:
+ *      char    getnb()     lklex.c
+ *      VOID    unget()     lklex.c
+ *      Addr_T  expr()      lkeval.c
+ *
+ *  side effects:
+ *      The iram_size may be modified.
+ */
+
+VOID
+iramsav()
+{
+  unget(getnb());
+  if (ip && *ip)
+    iram_size = expr(0);    /* evaluate size expression */
+  else
+    iram_size = 128;        /* Default is 128 (0x80) bytes */
+  if ((iram_size<=0) || (iram_size>256))
+    iram_size = 128;        /* Default is 128 (0x80) bytes */
+}
+
+/*Similar to iramsav but for xram memory*/
+VOID
+xramsav()
+{
+  unget(getnb());
+  if (ip && *ip)
+    xram_size = expr(0);    /* evaluate size expression */
+  else
+    xram_size = rflag?0x1000000:0x10000;
+}
+
+/*Similar to iramsav but for code memory*/
+VOID
+codesav()
+{
+  unget(getnb());
+  if (ip && *ip)
+    code_size = expr(0);    /* evaluate size expression */
+  else
+    code_size = rflag?0x1000000:0x10000;
+}
+
+
+/*)Function VOID    iramcheck()
+ *
+ *  The function iramcheck() is used at the end of linking to check that
+ *  the internal RAM area wasn't overflowed by too many variable
+ *  assignments.  Variables in the DSEG, ISEG, and OSEG are assigned to
+ *  the chip's internal RAM.
+ *
+ *  local variables:
+ *      none
+ *
+ *  global variables:
+ *      unsigned int        size of chip's internal
+ *          iram_size       RAM segment
+ *      struct area         linked list of memory
+ *          *areap          areas
+ *
+ *   functions called:
+ *
+ *  side effects:
+ */
+
+VOID
+iramcheck()
+{
+  register unsigned int last_addr;
+  register struct area *ap;
+
+  for (ap = areap; ap; ap=ap->a_ap) {
+    if ((ap->a_size != 0) &&
+        (!strcmp(ap->a_id, "DSEG") ||
+         !strcmp(ap->a_id, "OSEG") ||
+         !strcmp(ap->a_id, "ISEG")
+        )
+       )
+    {
+      last_addr = ap->a_addr + ap->a_size - 1;
+      if (last_addr >= iram_size)
+        fprintf(stderr,
+          "\nWARNING! Segment %s extends past the end\n"
+          "         of internal RAM.  Check map file.\n",
+          ap->a_id);
+    }
+  }
+}
+
+char *usetxt[] = {
+    "Startup:",
+    "  -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",
+/*  "Usage: [-Options] file [file ...]", */
+    "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",
+    "Map format:",
+    "  -m   Map output generated as file[MAP]",
+    "  -x   Hexadecimal (default),  -d  Decimal,  -q  Octal",
+    "Output:",
+    "  -i   Intel Hex as file[IHX]",
+    "  -s   Motorola S19 as file[S19]",
+    "  -j   Produce NoICE debug as file[NOI]",
+    "  -z   Produce SDCdb debug as file[cdb]",
+/*  "List:", */
+    "  -u   Update listing file(s) with link data as file(s)[.RST]",
+    "Miscellaneous:\n"
+    "  -a   [iram-size] Check for internal RAM overflow",
+    "  -v   [xram-size] Check for external RAM overflow",
+    "  -w   [code-size] Check for code overflow",
+    "  -y   Generate memory usage summary file[mem]",
+    "  -Y   Pack internal ram",
+    "  -A   [stack-size] Allocate space for stack",
+    "End:",
+    "  -e   or null line terminates input",
+    0
+};
+
+/*)Function VOID    usage()
+ *
+ *  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.
+ *
+ *  global variables:
+ *      FILE *  stderr      c_library
+ *
+ *  functions called:
+ *      int     fprintf()   c_library
+ *
+ *  side effects:
+ *      none
+ */
+
+VOID
+usage()
+{
+    register char   **dp;
+
+    fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION);
+    for (dp = usetxt; *dp; dp++)
+        fprintf(stderr, "%s\n", *dp);
+    lkexit(1);
+}
+
+/*)Function VOID    copyfile()
+ *
+ *      FILE    *dest           destination file
+ *      FILE    *src            source file
+ *
+ *      function will copy source file to destination file
+ *
+ *
+ *  functions called:
+ *      int     fgetc()         c_library
+ *      int     fputc()         c_library
+ *
+ *  side effects:
+ *      none
+ */
+VOID copyfile (dest,src)
+FILE *src,*dest ;
+{
+    int ch;
+    while ((ch = fgetc(src)) != EOF) {
+
+    fputc(ch,dest);
+    }
+}
diff --git a/as/link/mcs51/lkmem.c b/as/link/mcs51/lkmem.c
new file mode 100644 (file)
index 0000000..47fc14d
--- /dev/null
@@ -0,0 +1,613 @@
+/*-------------------------------------------------------------------------
+  lkmem.c - Create a memory summary file with extension .mem
+
+   Written By -  Jesus Calvino-Fraga, jesusc@ieee.org (2002)
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+-------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "aslink.h"
+#include "strcmpi.h"
+
+int summary(struct area * areap)
+{
+    #define EQ(A,B) !as_strcmpi((A),(B))
+    #define MIN_STACK 16
+    #define REPORT_ERROR(A, H) \
+    {\
+        fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
+        fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
+        toreturn=1; \
+    }
+
+    #define REPORT_WARNING(A, H) \
+    { \
+        fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
+        fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
+    }
+
+    char buff[128];
+    int j, toreturn=0;
+    unsigned int Total_Last=0, k;
+
+    struct area * xp;
+    FILE * of;
+
+    /*Artifacts used for printing*/
+    char start[15], end[15], size[15], max[15];
+    char format[]="   %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
+    char line[]="---------------------";
+
+    typedef struct
+    {
+        unsigned long Start;
+        unsigned long Size;
+        unsigned long Max;
+        char Name[NCPS];
+        unsigned long flag;
+    } _Mem;
+
+    unsigned int dram[0x100];
+    _Mem Ram[]={
+        {0,     8,  8,   "REG_BANK_0", 0x0001},
+        {0x8,   8,  8,   "REG_BANK_1", 0x0002},
+        {0x10,  8,  8,   "REG_BANK_2", 0x0004},
+        {0x18,  8,  8,   "REG_BANK_3", 0x0008},
+        {0x20,  0,  16,  "BSEG_BYTES", 0x0010},
+        {0,     0,  128, "UNUSED",     0x0000},
+        {0x7f,  0,  128, "DATA",       0x0020},
+        {0,     0,  128, "TOTAL:",     0x0000}
+    };
+
+    _Mem IRam= {0xff,   0,   128, "INDIRECT RAM",       0x0080};
+    _Mem Stack={0xff,   0,     1, "STACK",              0x0000};
+    _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM",       0x0100};
+    _Mem Rom=  {0xffff, 0, 65536, "ROM/EPROM/FLASH",    0x0200};
+
+    if(stacksize==0) stacksize=MIN_STACK;
+
+    if(rflag) /*For the DS390*/
+    {
+        XRam.Max=0x1000000; /*24 bits*/
+        XRam.Start=0xffffff;
+        Rom.Max=0x1000000;
+        Rom.Start=0xffffff;
+    }
+
+    if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
+    {
+        Ram[5].Max=0x80;
+        Ram[6].Max=0x80;
+        Ram[7].Max=0x80;
+        IRam.Max=0x80;
+        iram_size=0x100;
+    }
+    else if(iram_size<0x80)
+    {
+        Ram[5].Max=iram_size;
+        Ram[6].Max=iram_size;
+        Ram[7].Max=iram_size;
+        IRam.Max=0;
+    }
+    else
+    {
+        Ram[5].Max=0x80;
+        Ram[6].Max=0x80;
+        Ram[7].Max=0x80;
+        IRam.Max=iram_size-0x80;
+    }
+
+    for(j=0; j<(int)iram_size; j++) dram[j]=0;
+    for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
+
+    /* Open Memory Summary File*/
+    of = afile(linkp->f_idp, "mem", 1);
+    if (of == NULL)
+    {
+        lkexit(1);
+    }
+
+    xp=areap;
+    while (xp)
+    {
+        /**/ if (EQ(xp->a_id, "REG_BANK_0"))
+        {
+            Ram[0].Size=xp->a_size;
+        }
+        else if (EQ(xp->a_id, "REG_BANK_1"))
+        {
+            Ram[1].Size=xp->a_size;
+        }
+        else if (EQ(xp->a_id, "REG_BANK_2"))
+        {
+            Ram[2].Size=xp->a_size;
+        }
+        else if (EQ(xp->a_id, "REG_BANK_3"))
+        {
+            Ram[3].Size=xp->a_size;
+        }
+        else if (EQ(xp->a_id, "BSEG_BYTES"))
+        {
+            Ram[4].Size+=xp->a_size;
+        }
+        else if (EQ(xp->a_id, "BIT_BANK"))
+        {
+            Ram[4].Size+=xp->a_size;
+        }
+
+        else if(xp->a_flag & A_CODE)
+        {
+            if(xp->a_size>0)
+            {
+                Rom.Size+=xp->a_size;
+                if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
+            }
+        }
+
+        else if (EQ(xp->a_id, "SSEG"))
+        {
+            Stack.Size+=xp->a_size;
+            if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
+        }
+
+        else if(xp->a_flag & A_XDATA)
+        {
+            if(xp->a_size>0)
+            {
+                XRam.Size+=xp->a_size;
+                if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
+            }
+        }
+
+        else if (EQ(xp->a_id, "ISEG"))
+        {
+            IRam.Size+=xp->a_size;
+            if(xp->a_addr<IRam.Start) IRam.Start=xp->a_addr;
+        }
+
+        /*If is not a register bank, bit, stack, or idata, then it should be data*/
+        else if((xp->a_flag & (A_CODE|A_BIT|A_XDATA))==0)
+        {
+            if(xp->a_size)
+            {
+                Ram[6].Size+=xp->a_size;
+                if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
+            }
+        }
+
+        xp=xp->a_ap;
+    }
+
+    for(j=0; j<7; j++)
+        for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
+            dram[k]|=Ram[j].flag; /*Mark as used*/
+
+    for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
+        dram[k]|=IRam.flag; /*Mark as used*/
+
+    /*Compute the amount of unused memory in direct data Ram.  This is the
+    gap between the last register bank or bit segment and the data segment.*/
+    for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
+    Ram[5].Start=k+1;
+    Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
+
+    /*Compute the data Ram totals*/
+    for(j=0; j<7; j++)
+    {
+        if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
+        Ram[7].Size+=Ram[j].Size;
+    }
+    Total_Last=Ram[6].Size+Ram[6].Start-1;
+
+    /*Report the Ram totals*/
+    fprintf(of, "Direct Internal RAM:\n");
+    fprintf(of, format, "Name", "Start", "End", "Size", "Max");
+
+    for(j=0; j<8; j++)
+    {
+        if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
+        if((j!=5) || (Ram[j].Size>0))
+        {
+            sprintf(start, "0x%02lx", Ram[j].Start);
+            if(Ram[j].Size==0)
+                end[0]=0;/*Empty string*/
+            else
+                sprintf(end,  "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
+            sprintf(size, "%5lu", Ram[j].Size);
+            sprintf(max, "%5lu", Ram[j].Max);
+            fprintf(of, format, Ram[j].Name, start, end, size, max);
+        }
+    }
+
+    for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
+    {
+        if(dram[k]!=Ram[6].flag)
+        {
+            sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
+            REPORT_ERROR(buff, 1);
+            break;
+        }
+    }
+
+    if(Ram[4].Size>Ram[4].Max)
+    {
+        k=Ram[4].Size-Ram[4].Max;
+        sprintf(buff, "Insufficient bit addressable memory.  "
+                    "%d byte%s short.\n", k, (k==1)?"":"s");
+        REPORT_ERROR(buff, 1);
+    }
+
+    if(Ram[5].Size!=0)
+    {
+        sprintf(buff, "%ld bytes in data memory wasted.  "
+                    "SDCC link could use: --data-loc 0x%02lx\n",
+                    Ram[5].Size, Ram[6].Start-Ram[5].Size);
+        REPORT_WARNING(buff, 1);
+    }
+
+    if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
+    {
+        k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
+        sprintf(buff, "Insufficient space in data memory.   "
+                    "%d byte%s short.\n", k, (k==1)?"":"s");
+        REPORT_ERROR(buff, 1);
+    }
+
+    /*Report the position of the beginning of the stack*/
+    fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
+        rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
+
+    /*Check that the stack pointer is landing in a safe place:*/
+    if( (dram[Stack.Start] & 0x8000) == 0x8000 )
+    {
+        fprintf(of, ".\n");
+        sprintf(buff, "Stack set to unavailable memory.\n");
+        REPORT_ERROR(buff, 1);
+    }
+    else if(dram[Stack.Start])
+    {
+        fprintf(of, ".\n");
+        sprintf(buff, "Stack overlaps area ");
+        REPORT_ERROR(buff, 1);
+        for(j=0; j<7; j++)
+        {
+                        if(dram[Stack.Start]&Ram[j].flag)
+            {
+                sprintf(buff, "'%s'\n", Ram[j].Name);
+                break;
+            }
+        }
+        if(dram[Stack.Start]&IRam.flag)
+        {
+            sprintf(buff, "'%s'\n", IRam.Name);
+        }
+        REPORT_ERROR(buff, 0);
+    }
+    else
+    {
+        for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
+        fprintf(of, " with %d bytes available\n", k);
+        if ((int)k<stacksize)
+        {
+            sprintf(buff, "Only %d byte%s available for stack.\n",
+                k, (k==1)?"":"s");
+            REPORT_WARNING(buff, 1);
+        }
+    }
+
+    fprintf(of, "\nOther memory:\n");
+    fprintf(of, format, "Name", "Start", "End", "Size", "Max");
+    fprintf(of, format, line, line, line, line, line);
+
+    /*Report IRam totals:*/
+    if(IRam.Size==0)
+    {
+        start[0]=0;/*Empty string*/
+        end[0]=0;/*Empty string*/
+    }
+    else
+    {
+        sprintf(start, "0x%02lx", IRam.Start);
+        sprintf(end,  "0x%02lx", IRam.Size+IRam.Start-1);
+    }
+    sprintf(size, "%5lu", IRam.Size);
+    sprintf(max, "%5lu", IRam.Max);
+    fprintf(of, format, IRam.Name, start, end, size, max);
+
+    /*Report XRam totals:*/
+    if(XRam.Size==0)
+    {
+        start[0]=0;/*Empty string*/
+        end[0]=0;/*Empty string*/
+    }
+    else
+    {
+        sprintf(start, "0x%04lx", XRam.Start);
+        sprintf(end,  "0x%04lx", XRam.Size+XRam.Start-1);
+    }
+    sprintf(size, "%5lu", XRam.Size);
+    sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
+    fprintf(of, format, XRam.Name, start, end, size, max);
+
+    /*Report Rom/Flash totals:*/
+    if(Rom.Size==0)
+    {
+        start[0]=0;/*Empty string*/
+        end[0]=0;/*Empty string*/
+    }
+    else
+    {
+        sprintf(start, "0x%04lx", Rom.Start);
+        sprintf(end,  "0x%04lx", Rom.Size+Rom.Start-1);
+    }
+    sprintf(size, "%5lu", Rom.Size);
+    sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
+    fprintf(of, format, Rom.Name, start, end, size, max);
+
+    /*Report any excess:*/
+    if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
+    {
+        sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
+        REPORT_ERROR(buff, 1);
+    }
+    if( ((XRam.Start+XRam.Size)>XRam.Max) ||
+        (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
+    {
+        sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
+        REPORT_ERROR(buff, 1);
+    }
+    if( ((Rom.Start+Rom.Size)>Rom.Max) ||
+        (((int)Rom.Size>code_size)&&(code_size>=0)) )
+    {
+        sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
+        REPORT_ERROR(buff, 1);
+    }
+
+    fclose(of);
+    return toreturn;
+}
+
+extern char idatamap[]; //0:not used, 1:used
+
+
+int summary2(struct area * areap)
+{
+    #define EQ(A,B) !as_strcmpi((A),(B))
+
+    char buff[128];
+    int toreturn = 0;
+    unsigned int j;
+    unsigned long int Stack_Start=0, Stack_Size;
+
+    struct area * xp;
+    struct area * xstack_xp = NULL;
+    FILE * of;
+
+    /*Artifacts used for printing*/
+    char start[15], end[15], size[15], max[15];
+    char format[]="   %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
+    char line[]="---------------------";
+
+    typedef struct
+    {
+        unsigned long Start;
+        unsigned long End;
+        unsigned long Size;
+        unsigned long Max;
+        char Name[NCPS];
+        unsigned long flag;
+    } _Mem;
+
+    _Mem Stack={0xff,   0, 0,     1, "STACK",           0x0000};
+    _Mem Paged={0xff,   0, 0,   256, "PAGED EXT. RAM",  A_PAG};
+    _Mem XRam= {0xffff, 0, 0, 65536, "EXTERNAL RAM",    0x0100};
+    _Mem Rom=  {0xffff, 0, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
+
+    if(rflag) /*For the DS390*/
+    {
+        XRam.Max=0x1000000; /*24 bits*/
+        XRam.Start=0xffffff;
+        Rom.Max=0x1000000;
+        Rom.Start=0xffffff;
+    }
+
+    /* Open Memory Summary File*/
+    of = afile(linkp->f_idp, "mem", 1);
+    if (of == NULL)
+    {
+        lkexit(1);
+    }
+
+    xp=areap;
+    while (xp)
+    {
+        if(xp->a_flag & A_CODE)
+        {
+            if(xp->a_size)
+            {
+                Rom.Size += xp->a_size;
+                if(xp->a_addr < Rom.Start)
+                    Rom.Start = xp->a_addr;
+                if(xp->a_addr + xp->a_size > Rom.End)
+                    Rom.End = xp->a_addr + xp->a_size;
+            }
+        }
+
+        else if (EQ(xp->a_id, "SSEG"))
+        {
+            Stack.Size += xp->a_size;
+            if(xp->a_addr < Stack.Start)
+                Stack.Start = xp->a_addr;
+            if(xp->a_addr + xp->a_size > Stack.End)
+                Stack.End = xp->a_addr + xp->a_size;
+        }
+
+        else if (EQ(xp->a_id, "PSEG"))
+        {
+            Paged.Size += xp->a_size;
+            if(xp->a_addr < Paged.Start)
+                Paged.Start = xp->a_addr;
+            if(xp->a_addr + xp->a_size > Paged.End)
+                Paged.End = xp->a_addr + xp->a_size;
+        }
+
+        else if (EQ(xp->a_id, "XSTK"))
+        {
+            xstack_xp = xp;
+            Paged.Size += xp->a_size;
+            if(xp->a_addr < Paged.Start)
+                Paged.Start = xp->a_addr;
+            if(xp->a_addr + xp->a_size > Paged.End)
+                Paged.End = xp->a_addr + xp->a_size;
+        }
+
+        else if(xp->a_flag & A_XDATA)
+        {
+            if(xp->a_size)
+            {
+                XRam.Size += xp->a_size;
+                if(xp->a_addr < XRam.Start)
+                    XRam.Start = xp->a_addr;
+                if(xp->a_addr + xp->a_size > XRam.End)
+                    XRam.End = xp->a_addr + xp->a_size;
+            }
+        }
+
+        xp = xp->a_ap;
+    }
+
+    /*Report the Ram totals*/
+    fprintf(of, "Internal RAM layout:\n");
+    fprintf(of, "      0 1 2 3 4 5 6 7 8 9 A B C D E F");
+    for(j=0; j<256; j++)
+    {
+        if(j%16==0) fprintf(of, "\n0x%02x:|", j);
+        fprintf(of, "%c|", idatamap[j]);
+    }
+       fprintf(of, "\n0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute\n");
+
+    for(j=0; j<256; j++)
+    {
+        if(idatamap[j]=='S')
+        {
+            Stack_Start=j;
+            break;
+        }
+    }
+
+    for(j=Stack_Start, Stack_Size=0; j<((iram_size)?iram_size:256); j++)
+    {
+        if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_Size++;
+        else break;
+    }
+
+    xp=areap;
+    while (xp)
+    {
+        if(xp->a_unaloc>0)
+        {
+            fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
+                        " in internal RAM for area %s.",
+                        xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id);
+            toreturn=1;
+        }
+        xp=xp->a_ap;
+    }
+
+    /*Report the position of the begining of the stack*/
+    if(Stack_Start!=256)
+        fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
+            rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_Size);
+    else
+        fprintf(of, "\nI don't have a clue where the stack ended up! Sorry...");
+
+    /*Report about xstack*/
+    if (xstack_xp)
+    {
+        Stack_Start = xstack_xp->a_addr;
+        Stack_Size = xstack_xp->a_size;
+        fprintf(of, "\nXstack starts at: 0x%04lx with %ld bytes available.",
+            Stack_Start, Stack_Size);
+    }
+
+    fprintf(of, "\n\nOther memory:\n");
+    fprintf(of, format, "Name", "Start", "End", "Size", "Max");
+    fprintf(of, format, line, line, line, line, line);
+
+    /*Report Paged XRam totals:*/
+    if(Paged.Size==0)
+    {
+        start[0]=0;/*Empty string*/
+        end[0]=0;/*Empty string*/
+    }
+    else
+    {
+        sprintf(start, "0x%04lx", Paged.Start);
+        sprintf(end,  "0x%04lx", Paged.End-1);
+    }
+    sprintf(size, "%5lu", Paged.Size);
+    sprintf(max, "%5lu", xram_size<0 ? Paged.Max : xram_size<256 ? xram_size : 256);
+    fprintf(of, format, Paged.Name, start, end, size, max);
+
+    /*Report XRam totals:*/
+    if(XRam.Size==0)
+    {
+        start[0]=0;/*Empty string*/
+        end[0]=0;/*Empty string*/
+    }
+    else
+    {
+        sprintf(start, "0x%04lx", XRam.Start);
+        sprintf(end,  "0x%04lx", XRam.End-1);
+    }
+    sprintf(size, "%5lu", XRam.Size);
+    sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
+    fprintf(of, format, XRam.Name, start, end, size, max);
+
+    /*Report Rom/Flash totals:*/
+    if(Rom.Size==0)
+    {
+        start[0]=0;/*Empty string*/
+        end[0]=0;/*Empty string*/
+    }
+    else
+    {
+        sprintf(start, "0x%04lx", Rom.Start);
+        sprintf(end,  "0x%04lx", Rom.End-1);
+    }
+    sprintf(size, "%5lu", Rom.Size);
+    sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
+    fprintf(of, format, Rom.Name, start, end, size, max);
+
+    /*Report any excess:*/
+    if( ((XRam.End) > XRam.Max) ||
+        (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
+    {
+        sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
+        REPORT_ERROR(buff, 1);
+    }
+    if( ((Rom.End) > Rom.Max) ||
+        (((int)Rom.Size>code_size)&&(code_size>=0)) )
+    {
+        sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
+        REPORT_ERROR(buff, 1);
+    }
+
+    fclose(of);
+    return toreturn;
+}
diff --git a/as/link/mcs51/lknoice.c b/as/link/mcs51/lknoice.c
new file mode 100644 (file)
index 0000000..2cd6a91
--- /dev/null
@@ -0,0 +1,246 @@
+/* lknoice.c */
+
+/*
+ * Extensions to CUG 292 linker ASLINK to produce NoICE debug files
+ *
+ * 31-Oct-1997 by John Hartman
+ * 30-Jan-98 JLH add page to DefineNoICE for 8051
+ *  2-Feb-98 JLH Allow optional .nest on local vars - C scoping rules...
+ */
+
+#include <stdio.h>
+#include <setjmp.h>
+#include <string.h>
+#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 );
+static void DefineFile( char *name, Addr_T value, int page );
+static void DefineFunction( char *name, Addr_T value, int page );
+static void DefineStaticFunction( char *name, Addr_T value, int page );
+static void DefineEndFunction( Addr_T value, int page );
+static void DefineLine( char *lineString, Addr_T value, int page );
+static void PagedAddress( Addr_T value, int page );
+
+/*
+ * Called from lstarea in lklist.c for each symbol.
+ *
+ * Generates appropriate NoICE commands into output file, if any is open
+ *
+ */
+void DefineNoICE( char *name, Addr_T value, int page )
+{
+       char token1[NCPS];                      /* parse for file.function.symbol */
+       char token2[NCPS];
+       char token3[NCPS];
+       //      char token4[NCPS];
+       char sep1, sep2;
+       int  j, level;
+
+       /* no output if file is not open */
+       if (jfp == NULL) return;
+
+        j = sscanf( name, "%[^.]%c%[^.]%c%s",
+                   token1, &sep1, token2, &sep2, token3 );
+        switch (j)
+       {
+               /* file.function.symbol, or file.function..SPECIAL */
+               case 5:
+                       DefineFile( token1, 0, 0 );
+                       if (token3[0] == '.')
+                       {
+                               if (strcmp( token3, ".FN" ) == 0)
+                               {
+                                       /* Global function */
+                                        DefineFunction( token2, value, page );
+                               }
+                               else if (strcmp( token3, ".SFN" ) == 0)
+                               {
+                                       /* Static (file-scope) function */
+                                       DefineStaticFunction( token2, value, page );
+                               }
+                               else if (strcmp( token3, ".EFN" ) == 0)
+                               {
+                                       /* End of function */
+                                        DefineEndFunction( value, page );
+                                }
+                       }
+                       else
+                       {
+                               /* Function-scope var. */
+                               DefineFunction( token2, 0, 0 );
+
+                                /* Look for optional level integer */
+                               j = sscanf( token3, "%[^.]%c%u", token1, &sep1, &level );
+                                if ((j == 3) && (level != 0))
+                                {
+                                       sprintf( &token1[ strlen(token1) ], "_%u", level );
+                               }
+                                       DefineScoped( token1, value, page );
+                        }
+                       break;
+
+               /* file.func. is illegal */
+               case 4:
+                       break;
+
+               /* either file.symbol or file.line# */
+               case 3:
+                       DefineFile( token1, 0, 0 );
+                       if ((token2[0] >= '0') && (token2[0] <= '9'))
+                       {
+                               /* Line number */
+                                DefineLine( token2, value, page );
+                        }
+                       else
+                       {
+                               /* File-scope symbol.  (Kill any function) */
+                               DefineEndFunction( 0, 0 );
+                                DefineScoped( token2, value, page );
+                        }
+                       break;
+
+               /* symbol. is illegal */
+               case 2:
+                       break;
+
+               /* just a symbol */
+               case 1:
+                        DefineGlobal( token1, value, page );
+                        break;
+       }
+}
+
+static char currentFile[NCPS];
+static char currentFunction[NCPS];
+
+/*
+ * static function:
+ * Define "name" as a global symbol
+ */
+void DefineGlobal( char *name, Addr_T value, int page )
+{
+       fprintf( jfp, "DEF %s ", name );
+       PagedAddress( value, page );
+}
+
+/*
+ * static function:
+ * Define "name" as a static (scoped) symbol
+ */
+void DefineScoped( char *name, Addr_T value, int page )
+{
+       fprintf( jfp, "DEFS %s ", name );
+       PagedAddress( value, page );
+}
+
+/*
+ * static function:
+ * Define "name" as the current file
+ */
+void DefineFile( char *name, Addr_T value, int page )
+{
+       if (as_strcmpi( name, currentFile ) != 0)
+       {
+               strcpy( currentFile, name );
+               if (value != 0)
+               {
+                       fprintf( jfp, "FILE %s ", name );
+                       PagedAddress( value, page );
+               }
+               else
+               {
+                       fprintf( jfp, "FILE %s\n", name );
+               }
+       }
+}
+
+/*
+ * static function:
+ * Define "name" as the current function
+ */
+void DefineFunction( char *name, Addr_T value, int page )
+{
+       if (as_strcmpi( name, currentFunction ) != 0)
+       {
+               strcpy( currentFunction, name );
+                if (value != 0)
+                {
+                        fprintf( jfp, "DEF %s ", name );
+                       PagedAddress( value, page );
+                        fprintf( jfp, "FUNC %s ", name );
+                       PagedAddress( value, page );
+                }
+                else
+                {
+                        fprintf( jfp, "FUNC %s\n", name );
+               }
+       }
+}
+
+/*
+ * static function:
+ * Define "name" as the current static (scoped) function
+ */
+void DefineStaticFunction( char *name, Addr_T value, int page )
+{
+       if (as_strcmpi( name, currentFunction ) != 0)
+       {
+               strcpy( currentFunction, name );
+               if (value != 0)
+               {
+                        fprintf( jfp, "DEFS %s ", name );
+                       PagedAddress( value, page );
+                       fprintf( jfp, "SFUNC %s ", name );
+                       PagedAddress( value, page );
+               }
+               else
+               {
+                       fprintf( jfp, "SFUNC %s\n", name );
+               }
+       }
+}
+
+/*
+ * static function:
+ * Define the end of the current function
+ */
+void DefineEndFunction( Addr_T value, int page )
+{
+       if (currentFunction[0] != 0)
+       {
+               if (value != 0)
+               {
+                       fprintf( jfp, "ENDF " );
+                       PagedAddress( value, page );
+               }
+               else
+               {
+                       fprintf( jfp, "ENDF\n" );
+               }
+
+               currentFunction[0] = 0;
+       }
+}
+
+/*
+ * static function:
+ * Define "lineNumber" as a line in the current file
+ */
+void DefineLine( char *lineString, Addr_T value, int page )
+{
+       int indigit, lineNumber = 0;
+
+       while( (indigit=digit( *lineString++, 10 )) >= 0)
+       {
+               lineNumber = 10*lineNumber + indigit;
+       }
+       fprintf( jfp, "LINE %u ", lineNumber );
+        PagedAddress( value, page );
+}
+
+void PagedAddress( Addr_T value, int page )
+{
+       fprintf( jfp, "%X:0x%X\n", page, value );
+}
diff --git a/as/link/mcs51/lkrloc.c b/as/link/mcs51/lkrloc.c
new file mode 100644 (file)
index 0000000..2771ec5
--- /dev/null
@@ -0,0 +1,1523 @@
+/* lkrloc.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * 29-Oct-97 JLH:
+ *       - errdmp: show s_id as string rather than array [NCPS]
+ *       - relr: add support for 11 bit 8051 addressing
+ * 02-Apr-98 JLH: don't output empty hex records
+ */
+
+#include <stdio.h>
+#include <string.h>
+#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[].
+ *
+ */
+
+/* Global which holds the upper 16 bits of the last 32 bit area adress
+ * output. Useful only for iHex mode.
+ */
+int    lastExtendedAddress=-1;
+
+/* Static variable which holds the index of last processed area.
+ * Useful only for iHex mode.
+ */
+static int lastAreaIndex = -1;
+
+/*)Function VOID    reloc(c)
+ *
+ *          char c      process code
+ *
+ *  The function reloc() calls a particular relocation
+ *  function determined by the process code.
+ *
+ *  local variable:
+ *      none
+ *
+ *  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
+ *
+ *  side effects:
+ *      Refer to the called relocation functions.
+ *
+ */
+
+VOID reloc(char c)
+{
+    switch(c) {
+
+    case 'T':
+        relt();
+        break;
+
+    case 'R':
+        relr();
+        break;
+
+    case 'P':
+        relp();
+        break;
+
+    case 'E':
+        rele();
+        break;
+
+    default:
+        fprintf(stderr, "Undefined Relocation Operation\n");
+        lkerr++;
+        break;
+
+    }
+}
+
+
+/*)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.
+ *
+ *      T Line
+ *
+ *      T xx xx nn nn nn nn nn ...
+ *
+ *
+ *      In: "T n0 n1 n2 n3 ... nn"
+ *
+ *      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.
+ *
+ *  local variable:
+ *      none
+ *
+ *  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
+ *
+ *  side effects:
+ *      Linker input T line evaluated.
+ *
+ */
+
+VOID relt(VOID)
+{
+    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.
+ *
+ */
+
+VOID relr(VOID)
+{
+    register int mode;
+    register Addr_T reli, relv;
+    int aindex, rindex, rtp, error;
+    Addr_T r, rtbase, rtofst, paga, pags, 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);
+
+    #if 0
+    printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
+        a[aindex]->a_addr, a[aindex]->a_size, rtbase);
+    #endif
+    /*
+     * Do remaining relocations
+     */
+    while (more()) {
+        error = 0;
+        mode = eval();
+
+        if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
+        {
+            mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
+            /* printf("unescaping rmode\n"); */
+        }
+
+        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_BYT3)
+            {
+                /* This is a three byte address, of which
+                 * we will select one byte.
+                 */
+                if (mode & R_BIT)
+                {
+                    relv = adb_24_bit(reli, rtp);
+                }
+                else if (mode & R_HIB)
+                {
+                    /* printf("24 bit address selecting hi byte.\n"); */
+                    relv = adb_24_hi(reli, rtp);
+                }
+                else if (mode & R_MSB)
+                {
+                    /* Note that in 24 bit mode, R_MSB
+                     * is really the middle byte, not
+                     * the most significant byte.
+                     *
+                     * This is ugly and I can only apologize
+                     * for any confusion.
+                     */
+                    /* printf("24 bit address selecting middle byte.\n"); */
+                    relv = adb_24_mid(reli, rtp);
+                }
+                else
+                {
+                    /* printf("24 bit address selecting lo byte.\n"); */
+                    relv = adb_24_lo(reli, rtp);
+                }
+            }
+            else if (mode & R_BYT2) {
+                /* This is a two byte address, of
+                 * which we will select one byte.
+                 */
+                if (mode & R_BIT) {
+                    relv = adb_bit(reli, rtp);
+                } else if (mode & R_MSB) {
+                    relv = adb_hi(reli, rtp);
+                } else {
+                    relv = adb_lo(reli, rtp);
+                }
+            } else {
+                relv = adb_b(reli, rtp);
+            }
+        } else if (IS_R_J11(mode)) {
+            /* JLH: 11 bit jump destination for 8051.  Forms
+            /  two byte instruction with op-code bits
+            /  in the MIDDLE!
+            /  rtp points at 3 byte locus: first two
+            /  will get the instructiion. third one
+            /  has raw op-code.
+            */
+
+            /* Calculate absolute destination
+            /  relv must be on same 2K page as pc
+            */
+            relv = adw_w(reli, rtp);
+
+            if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) {
+                    error = 2;
+            }
+
+            /* Merge MSB (byte 0) with op-code, ignoring
+            /  top 5 bits of address.  Then hide the op-code
+            */
+            rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
+            rtflg[rtp+2] = 0;
+            rtofst += 1;
+        }
+        else if (IS_R_J19(mode)) {
+            /* 19 bit jump destination for DS80C390.  Forms
+            /  three byte instruction with op-code bits
+            /  in the MIDDLE!
+            /  rtp points at 4 byte locus: first three
+            /  will get the instructiion. fourth one
+            /  has raw op-code.
+             */
+
+            /* Calculate absolute destination
+            /  relv must be on same 512K page as pc
+            */
+            relv = adw_24(reli, rtp);
+
+            if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) {
+                error = 2;
+            }
+
+            /* Merge MSB (byte 0) with op-code, ignoring
+            /  top 5 bits of address.  Then hide the op-code
+            */
+            rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
+            rtflg[rtp+3] = 0;
+            rtofst += 1;
+        }
+        else if (IS_C24(mode))
+        {
+            /* 24 bit address */
+            relv = adw_24(reli, rtp);
+            }
+        else
+        {
+            /* 16 bit address. */
+            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;
+        if ((mode & R_BIT) && (relv & ~0x87FF))
+            error = 5;
+
+        /*
+         * 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);
+    }
+
+    /* JLH: output only if data (beyond two byte address) */
+    if ((oflag == 1) && (rtcnt > 2)) {
+        int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff;
+
+        /* Boy, is this a hack: for ABS sections, the
+         * base address is stored as zero, and the T records
+         * indicate the offset from zero.
+         *
+         * Since T records can only indicate a 16 bit offset, this
+         * obviously creates a problem for ABS segments located
+         * above 64K (this is only meaningful in flat24 mode).
+         *
+         * However, the size of an ABS area is stored as
+         * base address + section size (I suspect this is a bug,
+         * but it's a handy one right now). So the upper 8 bits of
+         * the 24 bit address are stored in the size record.
+         * Thus we add it in.
+         *
+         * This is another reason why we can't have areas greater
+         * than 64K yet, even in flat24 mode.
+         */
+    //  extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
+    //  commented out by jr
+
+        if (lastAreaIndex != aindex) {
+            lastAreaIndex = aindex;
+            newArea();
+        }
+
+        if (extendedAddress != lastExtendedAddress)
+        {
+
+            if (lastExtendedAddress!=-1) {
+              printf("output extended linear address record 0x%x 0x%x\n",
+                 extendedAddress, lastExtendedAddress);
+            }
+
+            if (rflag)
+            {
+                ihxEntendedLinearAddress(extendedAddress);
+            }
+            else if (extendedAddress)
+            {
+                /* Not allowed to generate extended address records,
+                 * but one is called for here...
+                 */
+                fprintf(stderr,
+                    "warning: extended linear address encountered; "
+                    "you probably want the -r flag.\n");
+            }
+            lastExtendedAddress = extendedAddress;
+        }
+        ihx(1);
+    } else
+    if ((oflag == 2) && (rtcnt > 2)) {
+        s19(1);
+    }
+}
+
+char *errmsg[] = {
+    "Unsigned Byte error",
+    "Byte PCR relocation error",
+    "Page0 relocation error",
+    "Page Mode relocation error",
+    "Bit-addressable 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.
+ *
+ */
+
+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");
+}
+
+/*)Function VOID    rele()
+ *
+ *  The function rele() closes all open output files
+ *  at the end of the linking process.
+ *
+ *  local variable:
+ *      none
+ *
+ *  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
+ *
+ *  side effects:
+ *      All open output files are closed.
+ *
+ */
+
+VOID rele(VOID)
+{
+    if (uflag != 0) {
+        lkulist(0);
+    }
+    if (oflag == 1) {
+        ihx(0);
+    } else
+    if (oflag == 2) {
+        s19(0);
+    }
+}
+
+/*)Function Addr_T      evword()
+ *
+ *  The function evword() combines two byte values
+ *  into a single word value.
+ *
+ *  local variable:
+ *      Addr_T  v       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      int eval()      lkeval.c
+ *
+ *  side effects:
+ *      Relocation text line is scanned to combine
+ *      two byte values into a single word value.
+ *
+ */
+
+Addr_T evword(VOID)
+{
+    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)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      none
+ *
+ *  global variables:
+ *      none
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *
+ */
+
+Addr_T adb_b(register Addr_T v, register int i)
+{
+    return(rtval[i] += v);
+}
+
+/*)Function Addr_T      adb_bit(v, i)
+ *
+ *      int v       value to add to byte
+ *      int i       rtval[] index
+ *
+ *  The function adb_bit() converts the single
+ *  byte address value contained in rtval[i] to bit-
+ *  addressable space and adds the value of v to it.
+ *  The new value of rtval[i] is returned.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      none
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *
+ */
+
+Addr_T adb_bit(register Addr_T v, register int i)
+{
+    register Addr_T j;
+
+    j = adb_lo(v, i) & 0xFF;
+    if ((j >= 0x20) && (j <= 0x2F)) {
+        j = (j - 0x20) * 8;
+    } else if ((j < 0x80) || ((j & 0x07) != 0)) {
+        return(0x100);//error
+    }
+
+    if (hilo) {
+        j = rtval[i+1] = j + (rtval[i] & 0x07);
+    } else {
+        j = rtval[i] = j + (rtval[i+1] & 0x07);
+    }
+    return(j);
+}
+
+/*)Function Addr_T      adb_lo(v, i)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  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.
+ *
+ */
+
+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);
+}
+
+/*)Function Addr_T      adb_hi(v, i)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  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.
+ *
+ */
+
+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);
+}
+
+/*)Function Addr_T      adb_24_bit(v, i)
+ *
+ *      int v       value to add to byte
+ *      int i       rtval[] index
+ *
+ *  The function adb_24_bit() converts the single
+ *  byte address value contained in rtval[i] to bit-
+ *  addressable space and adds the value of v to it.
+ *  The new value of rtval[i] is returned.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      none
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *
+ */
+
+Addr_T adb_24_bit(register Addr_T v, register int i)
+{
+    register Addr_T j;
+
+    j = adb_24_lo(v, i) & 0xFF;
+    if ((j >= 0x20) && (j <= 0x2F)) {
+        j = (j - 0x20) * 8;
+    } else if ((j < 0x80) || ((j & 0x07) != 0)) {
+        return(0x100);//error
+    }
+
+    if (hilo) {
+        j = rtval[i+2] = j + (rtval[i+1] & 0x07);
+    } else {
+        j = rtval[i] = j + (rtval[i+1] & 0x07);
+    }
+    return(j);
+}
+
+/*)Function Addr_T      adb_24_hi(v, i)
+ *
+ *      int v       value to add to byte
+ *      int i       rtval[] index
+ *
+ *  The function adb_24_hi() adds the value of v to the
+ *  24 bit value contained in rtval[i] - rtval[i+2].
+ *  The new value of rtval[i] / rtval[i+1] is returned.
+ *  The LSB & middle byte rtflg[] is cleared.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *      The rtflg[] value corresponding to the
+ *      LSB & middle byte of the word value is cleared to
+ *      reflect the fact that the MSB is the selected byte.
+ *
+ */
+
+Addr_T adb_24_hi(Addr_T v, int i)
+{
+    register Addr_T j;
+
+    j = adw_24(v, i);
+
+    /* Remove the lower two bytes. */
+    if (hilo)
+    {
+        rtflg[i+2] = 0;
+    }
+    else
+    {
+        rtflg[i] = 0;
+    }
+    rtflg[i+1] = 0;
+
+    return (j);
+}
+
+/*)Function Addr_T      adb_24_mid(v, i)
+ *
+ *      int v       value to add to byte
+ *      int i       rtval[] index
+ *
+ *  The function adb_24_mid() adds the value of v to the
+ *  24 bit value contained in rtval[i] - rtval[i+2].
+ *  The new value of rtval[i] / rtval[i+1] is returned.
+ *  The LSB & MSB byte rtflg[] is cleared.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *      The rtflg[] value corresponding to the
+ *      LSB & MSB of the 24 bit value is cleared to reflect
+ *      the fact that the middle byte is the selected byte.
+ *
+ */
+
+Addr_T adb_24_mid(Addr_T v, int i)
+{
+    register Addr_T j;
+
+    j = adw_24(v, i);
+
+    /* remove the MSB & LSB. */
+    rtflg[i+2] = 0;
+    rtflg[i] = 0;
+
+    return (j);
+}
+
+/*)Function Addr_T      adb_24_lo(v, i)
+ *
+ *      int v       value to add to byte
+ *      int i       rtval[] index
+ *
+ *  The function adb_24_lo() adds the value of v to the
+ *  24 bit value contained in rtval[i] - rtval[i+2].
+ *  The new value of rtval[i] / rtval[i+1] is returned.
+ *  The MSB & middle byte rtflg[] is cleared.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *      The rtflg[] value corresponding to the
+ *      MSB & middle byte  of the word value is cleared to
+ *      reflect the fact that the LSB is the selected byte.
+ *
+ */
+
+Addr_T adb_24_lo(Addr_T v, int i)
+{
+    register Addr_T j;
+
+    j = adw_24(v, i);
+
+    /* Remove the upper two bytes. */
+    if (hilo)
+    {
+        rtflg[i] = 0;
+    }
+    else
+    {
+        rtflg[i+2] = 0;
+    }
+    rtflg[i+1] = 0;
+
+    return (j);
+}
+
+/*)Function Addr_T      adw_w(v, i)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The word value of rtval[] is changed.
+ *
+ */
+
+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);
+}
+
+/*)Function Addr_T      adw_24(v, i)
+ *
+ *      int v       value to add to word
+ *      int i       rtval[] index
+ *
+ *  The function adw_w() adds the value of v to the
+ *  24 bit value contained in rtval[i] - rtval[i+2].
+ *  The new value of rtval[i] - rtval[i+2] is returned.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The word value of rtval[] is changed.
+ *
+ */
+Addr_T adw_24(Addr_T v, int i)
+{
+    register Addr_T j;
+
+    if (hilo) {
+        j = v + ((rtval[i] & 0xff) << 16)
+              + ((rtval[i+1] & 0xff) << 8)
+              + (rtval[i+2] & 0xff);
+        rtval[i] = (j >> 16) & 0xff;
+        rtval[i+1] = (j >> 8) & 0xff;
+        rtval[i+2] = j & 0xff;
+    } else {
+        j = v + (rtval[i] & 0xff)
+              + ((rtval[i+1] & 0xff) << 8)
+              + ((rtval[i+2] & 0xff) << 16);
+        rtval[i] = j & 0xff;
+        rtval[i+1] = (j >> 8) & 0xff;
+        rtval[i+2] = (j >> 16) & 0xff;
+    }
+    return(j);
+}
+
+/*)Function Addr_T      adw_lo(v, i)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  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.
+ *
+ */
+
+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);
+}
+
+/*)Function Addr_T      adw_hi(v, i)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      Addr_T  j       temporary evaluation variable
+ *
+ *  global variables:
+ *      hilo            byte ordering parameter
+ *
+ *  called functions:
+ *      none
+ *
+ *  side effects:
+ *      The value of rtval[] is changed.
+ *      The MSB and LSB values are interchanged and
+ *      then the MSB cleared.
+ *
+ */
+
+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);
+}
+
+/*)Function VOID    relerr(str)
+ *
+ *      char    *str        error string
+ *
+ *  The function relerr() outputs the error string to
+ *  stderr and to the map file (if it is open).
+ *
+ *  local variable:
+ *      none
+ *
+ *  global variables:
+ *      FILE    *mfp        handle for the map file
+ *
+ *  called functions:
+ *      VOID    errdmp()    lkrloc.c
+ *
+ *  side effects:
+ *      Error message inserted into map file.
+ *
+ */
+
+VOID relerr(char *str)
+{
+    errdmp(stderr, str);
+    if (mfp)
+        errdmp(mfp, str);
+}
+
+/*)Function VOID    errdmp(fptr, str)
+ *
+ *      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.
+ *
+ *  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
+ *
+ *  called functions:
+ *      int fprintf()   c_library
+ *      VOID    prntval()   lkrloc.c
+ *
+ *  side effects:
+ *      Error reported.
+ *
+ */
+
+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",
+            &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)
+ *
+ *      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.
+ *
+ *  local variable:
+ *      none
+ *
+ *  global variables:
+ *      int xflag       current radix
+ *
+ *  called functions:
+ *      int fprintf()   c_library
+ *
+ *  side effects:
+ *      none
+ *
+ */
+
+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);
+    }
+}
+
+/*)Function VOID    relerp(str)
+ *
+ *      char    *str        error string
+ *
+ *  The function relerp() outputs the paging error string to
+ *  stderr and to the map file (if it is open).
+ *
+ *  local variable:
+ *      none
+ *
+ *  global variables:
+ *      FILE    *mfp        handle for the map file
+ *
+ *  called functions:
+ *      VOID    erpdmp()    lkrloc.c
+ *
+ *  side effects:
+ *      Error message inserted into map file.
+ *
+ */
+
+VOID relerp(char *str)
+{
+    erpdmp(stderr, str);
+    if (mfp)
+        erpdmp(mfp, str);
+}
+
+/*)Function VOID    erpdmp(fptr, str)
+ *
+ *      FILE    *fptr       output file handle
+ *      char    *str        error string
+ *
+ *  The function erpdmp() outputs the error string str
+ *  to the device specified by fptr.
+ *
+ *  local variable:
+ *      head    *thp        pointer to head structure
+ *
+ *  global variables:
+ *      int     lkerr       error flag
+ *      sdp     sdp         base page structure
+ *
+ *  called functions:
+ *      int fprintf()       c_library
+ *      VOID    prntval()   lkrloc.c
+ *
+ *  side effects:
+ *      Error reported.
+ *
+ */
+
+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);
+}
diff --git a/as/link/mcs51/lks19.c b/as/link/mcs51/lks19.c
new file mode 100644 (file)
index 0000000..26d8892
--- /dev/null
@@ -0,0 +1,122 @@
+/* lks19.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "aslink.h"
+
+/*)Module      lks19.c
+ *
+ *     The module lks19.c contains the function to
+ *     output the relocated object code in the
+ *     Motorola S19 format.
+ *
+ *     lks19.c contains the following function:
+ *             VOID    s19(i)
+ *
+ *     lks19.c contains no local variables.
+ */
+
+/*)S19 Format
+ *      Record Type Field    -  This  field  signifies  the  start  of a
+ *                              record and  identifies  the  the  record
+ *                              type as follows:  
+ *
+ *                                  Ascii S1 - Data Record 
+ *                                  Ascii S9 - End of File Record 
+ *
+ *      Record Length Field  -  This  field  specifies the record length
+ *                              which includes the  address,  data,  and
+ *                              checksum   fields.   The  8  bit  record
+ *                              length value is converted to  two  ascii
+ *                              characters, high digit first.  
+ *
+ *      Load Address Field   -  This  field  consists  of the four ascii
+ *                              characters which result from  converting
+ *                              the  the  binary value of the address in
+ *                              which to begin loading this record.  The
+ *                              order is as follows:  
+ *
+ *                                  High digit of high byte of address. 
+ *                                  Low digit of high byte of address.  
+ *                                  High digit of low byte of address.  
+ *                                  Low digit of low byte of address.  
+ *
+ *                              In an End of File record this field con-
+ *                              sists of either four ascii zeros or  the
+ *                              program  entry  address.   Currently the
+ *                              entry address option is not supported.  
+ *
+ *      Data Field           -  This  field consists of the actual data,
+ *                              converted to two ascii characters,  high
+ *                              digit first.  There are no data bytes in
+ *                              the End of File record.  
+ *
+ *      Checksum Field       -  The  checksum  field is the 8 bit binary
+ *                              sum of the record length field, the load
+ *                              address field, and the data field.  This
+ *                              sum is then  complemented  (1's  comple-
+ *                              ment)   and   converted   to  two  ascii
+ *                              characters, high digit first.  
+ */
+
+/*)Function    s19(i)
+ *
+ *             int     i               0 - process data
+ *                                     1 - end of data
+ *
+ *     The function s19() outputs the relocated data
+ *     in the standard Motorola S19 format.
+ *
+ *     local variables:
+ *             Addr_T  chksum          byte checksum
+ *
+ *     global variables:
+ *             int     hilo            byte order
+ *             FILE *  ofp             output file handle
+ *             int     rtcnt           count of data words
+ *             int     rtflg[]         output the data flag
+ *             Addr_T  rtval[]         relocated data
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *
+ *     side effects:
+ *             The data is output to the file defined by ofp.
+ */
+
+VOID
+s19(i)
+{
+       register Addr_T chksum;
+
+       if (i) {
+               if (hilo == 0) {
+                       chksum = rtval[0];
+                       rtval[0] = rtval[1];
+                       rtval[1] = chksum;
+               }
+               for (i = 0, chksum = 1; i < rtcnt; i++) {
+                       if (rtflg[i])
+                               chksum++;
+               }
+               fprintf(ofp, "S1%02X", chksum);
+               for (i = 0; i < rtcnt ; i++) {
+                       if (rtflg[i]) {
+                               fprintf(ofp, "%02X", rtval[i]);
+                               chksum += rtval[i];
+                       }
+               }
+               fprintf(ofp, "%02X\n", (0-chksum-1) & 0xff);
+       } else {
+               fprintf(ofp, "S9030000FC\n");
+       }
+}
diff --git a/as/link/mcs51/lkstore.c b/as/link/mcs51/lkstore.c
new file mode 100644 (file)
index 0000000..063e89c
--- /dev/null
@@ -0,0 +1,50 @@
+/* lkstore.c */
+
+/* 
+ * Allocated string storage module.
+ *
+ * 31-Oct-1997 by John Hartman
+ */
+
+#include <stdio.h>
+#include <setjmp.h>
+#include <string.h>
+#include "aslink.h"
+
+/*
+ * Allocate space for "str", copy str into new space
+ * Return a pointer to the allocated name, or NULL if out of memory
+ */
+char *StoreString( char *str )
+{
+   /* To avoid wasting memory headers on small allocations, we
+   /  allocate a big chunk and parcel it out as required.
+   /  These static variables remember our hunk
+   */
+   #define STR_STORE_HUNK 2000
+   static char *pNextFree = NULL;
+   static int  bytesLeft = 0;
+   
+   int  length;
+   char *pStoredString;
+   
+   length = strlen( str ) + 1; /* what we need, including null */
+
+   if (length > bytesLeft)
+   {
+      /* no space.  Allocate a new hunk.  We lose the pointer to any
+      /  old hunk.  We don't care, as the names are never deleted.
+      */
+      pNextFree = (char*)new( STR_STORE_HUNK );
+      bytesLeft = STR_STORE_HUNK;
+   }
+
+   /* Copy the name and terminating null into the name store */
+   pStoredString = pNextFree;
+   memcpy( pStoredString, str, length );
+
+   pNextFree += length;
+   bytesLeft -= length;
+
+   return pStoredString;
+}
diff --git a/as/link/mcs51/lksym.c b/as/link/mcs51/lksym.c
new file mode 100644 (file)
index 0000000..1ebc49c
--- /dev/null
@@ -0,0 +1,488 @@
+/* lksym.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ *
+ * 28-Oct-97 JLH: 
+ *          - lkpsym: Use StoreString for sym construction
+ *          - change symeq() to do length-independent string compare
+ *          - change hash() to do length-independent hash calculation
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if defined(_MSC_VER)
+#include <malloc.h>
+#else
+#include <alloc.h>
+#endif
+#include "aslink.h"
+
+/*)Module      lksym.c
+ *
+ *     The module lksym.c contains the functions that operate
+ *     on the symbol structures.
+ *
+ *     lksym.c contains the following functions:
+ *             int     hash()
+ *             sym *   lkpsym()
+ *             VOID *  new()
+ *             sym *   newsym()
+ *             VOID    symdef()
+ *             int     symeq()
+ *             VOID    syminit()
+ *             VOID    symmod()
+ *             Addr_T  symval()
+ *
+ *     lksym.c contains no local/static variables.
+ */
+
+/*)Function    VOID    syminit()
+ *
+ *     The function syminit() is called to clear the hashtable.
+ *
+ *     local variables:
+ *             int     h               computed hash value
+ *             sym **  spp             pointer to an array of
+ *                                     sym structure pointers
+ *
+ *     global variables:
+ *             sym * symhash[]         array of pointers to NHASH
+ *                                     linked symbol lists
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             (1)     The symbol hash tables are cleared
+ */
+
+VOID
+syminit()
+{
+    // register int h;
+       struct sym **spp;
+
+       spp = &symhash[0];
+       while (spp < &symhash[NHASH])
+               *spp++ = NULL;
+}
+
+/*)Function    sym *   newsym()
+ *
+ *     The function newsym() is called to evaluate the symbol
+ *     definition/reference directive from the .rel file(s).
+ *     If the symbol is not found in the symbol table a new
+ *     symbol structure is created.  Evaluation of the
+ *     directive determines if this is a reference or a definition.
+ *     Multiple definitions of the same variable will be flagged
+ *     as an error if the values are not identical.  A symbol
+ *     definition places the symbol value and area extension
+ *     into the symbols data structure.  And finally, a pointer
+ *     to the symbol structure is placed into the head structure
+ *     symbol list.  Refer to the description of the header, symbol,
+ *     area, and areax structures in lkdata.c for structure and
+ *     linkage details.
+ *
+ *     local variables:
+ *             int     c               character from input text
+ *             int     i               evaluation value
+ *             char    id[]            symbol name
+ *             int     nglob           number of symbols in this header
+ *             sym *   tsp             pointer to symbol structure
+ *             sym **  s               list of pointers to symbol structures
+ *
+ *     global variables:
+ *             areax   *axp            Pointer to the current
+ *                                     areax structure
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             int     lkerr           error flag
+ *
+ *     functions called:
+ *             Addr_T  eval()          lkeval.c
+ *             VOID    exit()          c_library
+ *             int     fprintf()       c_library
+ *             char    getSid()        lklex.c
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             sym *   lkpsym()        lksym.c
+ *
+ *     side effects:
+ *             A symbol structure is created and/or modified.
+ *             If structure space allocation fails linker will abort.
+ *             Several severe errors (these are internal errors
+ *             indicating a corrupted .rel file or corrupted
+ *             assembler or linker) will terminated the linker.
+ */
+
+/*
+ * Find/Create a global symbol entry.
+ *
+ * S xxxxxx Defnnnn
+ *   |      |  |
+ *   |      |  `-- sp->s_addr
+ *   |      `----- sp->s_type
+ *   `------------ sp->s_id
+ *
+ */
+struct sym *
+newsym()
+{
+  register unsigned i ;
+  register unsigned nglob ;
+       register int c ;
+       struct sym *tsp;
+       struct sym **s;
+       char id[NCPS];
+
+       getSid(id);     // old: getid(id, -1);
+       tsp = lkpsym(id, 1);
+       c = getnb();get();get();
+       if (c == 'R') {
+               tsp->s_type |= S_REF;
+               if (eval()) {
+                       fprintf(stderr, "Non zero S_REF\n");
+                       lkerr++;
+               }
+       } else
+       if (c == 'D') {
+               i = eval();
+               if (tsp->s_type & S_DEF && tsp->s_addr != i) {
+                       fprintf(stderr, "Multiple definition of %8s\n", id);
+                       lkerr++;
+               }
+               tsp->s_type |= S_DEF;
+               /*
+                * Set value and area extension link.
+                */
+               tsp->s_addr = i;
+               tsp->s_axp = axp;
+       } else {
+               fprintf(stderr, "Invalid symbol type %c for %8s\n", c, id);
+               lkexit(1);
+       }
+       /*
+        * Place pointer in header symbol list
+        */
+       if (headp == NULL) {
+               fprintf(stderr, "No header defined\n");
+               lkexit(1);
+       }
+       nglob = hp->h_nglob;
+       s = hp->s_list;
+       for (i=0; i < nglob ;++i) {
+               if (s[i] == NULL) {
+                       s[i] = tsp;
+                       return(tsp);
+               }
+       }
+       fprintf(stderr, "Header symbol list overflow\n");
+       lkexit(1);
+       return(0);
+}
+
+/*)Function    sym *   lkpsym(id,f)
+ *
+ *             char *  id              symbol name string
+ *             int     f               f == 0, lookup only
+ *                                     f != 0, create if not found
+ *
+ *     The function lookup() searches the symbol hash tables for
+ *     a symbol name match returning a pointer to the sym structure.
+ *     If the symbol is not found then a sym structure is created,
+ *     initialized, and linked to the appropriate hash table if f != 0.
+ *     A pointer to this new sym structure is returned or a NULL
+ *     pointer is returned if f == 0.
+ *
+ *     local variables:
+ *             int     h               computed hash value
+ *             sym *   sp              pointer to a sym structure
+ *
+ *     global varaibles:
+ *             sym * symhash[]         array of pointers to NHASH
+ *                                     linked symbol lists
+ *
+ *     functions called:
+ *             int     hash()          lksym.c
+ *             VOID *  new()           lksym.c
+ *             int     symeq()         lksym.c
+ *
+ *     side effects:
+ *             If the function new() fails to allocate space
+ *             for the new sym structure the linker terminates.
+ */
+
+struct sym *
+lkpsym(id, f)
+char *id;
+{
+       register struct sym *sp;
+       register int h;
+
+       h = hash(id);
+       sp = symhash[h];
+       while (sp != NULL) {
+               if (symeq(id, sp->s_id))
+                       return (sp);
+               sp = sp->s_sp;
+       }
+       if (f == 0)
+               return (NULL);
+       sp = (struct sym *) new (sizeof(struct sym));
+       sp->s_sp = symhash[h];
+       symhash[h] = sp;
+       sp->s_id = StoreString( id );   /* JLH */
+       return (sp);
+}
+
+/*)Function    Addr_T  symval(tsp)
+ *
+ *             sym *   tsp             pointer to a symbol structure
+ *
+ *     The function symval() returns the value of the
+ *     relocated symbol by adding the variable definition
+ *     value to the areax base address.
+ *
+ *     local variables:
+ *             Addr_T  val             relocated address value
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+Addr_T
+symval(tsp)
+register struct sym *tsp;
+{
+       register Addr_T val;
+
+       val = tsp->s_addr;
+       if (tsp->s_axp) {
+               val += tsp->s_axp->a_addr;
+       }
+       return(val);
+}
+
+/*)Function    VOID    symdef(fp)
+ *
+ *             FILE *  fp              file handle for output
+ *
+ *     The function symdef() scans the hashed symbol table
+ *     searching for variables referenced but not defined.
+ *     Undefined variables are linked to the default
+ *     area "_CODE" and reported as referenced by the
+ *     appropriate module.
+ *
+ *     local variables:
+ *             int     i               hash table index loop variable
+ *             sym *   sp              pointer to linked symbol structure
+ *
+ *     global variables:
+ *             area    *areap          The pointer to the first
+ *                                     area structure of a linked list
+ *             sym *symhash[NHASH]     array of pointers to NHASH
+ *                                     linked symbol lists
+ *
+ *     functions called:
+ *             symmod()                lksym.c
+ *
+ *     side effects:
+ *             Undefined variables have their areas set to "_CODE".
+ */
+
+VOID
+symdef(fp)
+FILE *fp;
+{
+       register struct sym *sp;
+       register int i;
+
+       for (i=0; i<NHASH; ++i) {
+               sp = symhash[i];
+               while (sp) {
+                       if (sp->s_axp == NULL)
+                               sp->s_axp = areap->a_axp;
+                       if ((sp->s_type & S_DEF) == 0)
+                               symmod(fp, sp);
+                       sp = sp->s_sp;
+               }
+       }
+}
+
+/*)Function    VOID    symmod(fp,tsp)
+ *
+ *             FILE *  fp              output file handle
+ *             sym *   tsp             pointer to a symbol structure
+ *
+ *     The function symmod() scans the header structures
+ *     searching for a reference to the symbol structure
+ *     pointer to by tsp.  The function then generates an error
+ *     message whichs names the module having referenced the
+ *     undefined variable.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *             sym **  p               pointer to a list of pointers
+ *                                     to symbol structures
+ *
+ *     global variables:
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             head    *hp             Pointer to the current
+ *                                     head structure
+ *             int     lkerr           error flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *
+ *     side effects:
+ *             Error output generated.
+ */
+
+VOID
+symmod(fp, tsp)
+FILE *fp;
+struct sym *tsp;
+{
+       register int i;
+       struct sym **p;
+
+       if ((hp = headp) != NULL) {
+           while(hp) {
+               p = hp->s_list;
+               for (i=0; i<hp->h_nglob; ++i) {
+                   if (p[i] == tsp) {
+                       fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
+                       fprintf(fp, "referenced by module '%s'\n", hp->m_id);
+                       lkerr++;
+                   }
+               }
+           hp = hp->h_hp;
+           }
+       }
+}
+
+/*)Function    int     symeq(p1, p2)
+ *
+ *             char *  p1              name string
+ *             char *  p2              name string
+ *
+ *     The function symeq() compares the two name strings for a match.
+ *     The return value is 1 for a match and 0 for no match.
+ *
+ *     local variables:
+ *             int     h               loop counter
+ *
+ *     global variables:
+ *             char    ccase[]         an array of characters which
+ *                                     perform the case translation function
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ *
+ */
+
+int
+symeq(p1, p2)
+register char *p1, *p2;
+{
+#if    CASE_SENSITIVE
+               return (strcmp( p1, p2 ) == 0);
+#else
+               return (as_strcmpi( p1, p2 ) == 0);
+#endif
+}
+
+/*)Function    int     hash(p)
+ *
+ *             char *  p               pointer to string to hash
+ *
+ *     The function hash() computes a hash code using the sum
+ *     of all characters mod table size algorithm.
+ *
+ *     local variables:
+ *             int     h               accumulated character sum
+ *             int     n               loop counter
+ *
+ *     global variables:
+ *             char    ccase[]         an array of characters which
+ *                                     perform the case translation function
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ *
+ */
+int
+hash(p)
+register char *p;
+{
+       register int h;
+
+       h = 0;
+       while (*p) {
+
+#if    CASE_SENSITIVE
+               h += *p++;
+#else
+               h += ccase[*p++];
+#endif
+
+       };
+       return (h&HMASK);
+}
+
+/*)Function    VOID *  new(n)
+ *
+ *             unsigned int    n       allocation size in bytes
+ *
+ *     The function new() allocates n bytes of space and returns
+ *     a pointer to this memory.  If no space is available the
+ *     linker is terminated.
+ *
+ *     local variables:
+ *             char *  p               a general pointer
+ *             char *  q               a general pointer
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID *  malloc()        c_library
+ *
+ *     side effects:
+ *             Memory is allocated, if allocation fails
+ *             the linker is terminated.
+ */
+
+VOID *
+new(n)
+unsigned int n;
+{
+       register char *p;
+
+       if ((p = (char *) calloc(n, 1)) == NULL) {
+               fprintf(stderr, "Out of space!\n");
+               lkexit(1);
+       }
+       return (p);
+}
diff --git a/as/link/mcs51/readme.390 b/as/link/mcs51/readme.390
new file mode 100644 (file)
index 0000000..80170bd
--- /dev/null
@@ -0,0 +1,141 @@
+DS80C390 flat mode support
+
+2/4/2000 Kevin Vigor (e-mail: kevin at vigor.nu)
+
+I have hacked the 8051 assembler to support the 24 bit flat address mode of
+the DS80C390 processor. This mode allows the chip to directly address up to
+4 Meg of RAM. Details can be found at Dallas' web site: www.dalsemi.com.
+
+1: Assembler changes.
+
+24 bit mode is entered via a new assembler directive, .flat24. This directive
+takes a mandatory argument, which is either the string "on" or the string
+"off". ".flat24 on" enables 24-bit mode, and ".flat24 off" puts the assembler
+into standard 8051 mode.
+
+Note that any .included files within a ".flat24 on" segment of the code will
+be compiled in 24-bit mode.
+
+In 24-bit mode, 8 instructions have altered behavior. Of these, 5 modify
+the instruction encoding, while 3 differ only in behavior. These
+instructions are discussed in the DS80C390 User's Guide, but a summary is
+included here:
+
+ACALL and AJMP now take a 19 bit offset instead of the 8051's 11 bit offset. 
+An extra address byte is added to the encoded instruction.
+
+LCALL and LJMP now take a 24 bit target address instead of the 8051's 16 bit
+address. An extra address byte is added to the encoded instruction.
+
+MOV DPTR, #immed now takes a 24 bit immediate value instead of the 8051's 16
+bit address. An extra data byte is added to the encoded instruction.
+
+INC DPTR now increments the entire 24 bit DPTR. The encoding is not changed.
+
+RET and RETI restore the full 24 bit PC from the stack. The encoding is not
+changed.
+
+2: Linker changes.
+
+The linker supports (through a variety of evil hacks) 19 bit ACALL/AJMP
+relocations and 24 bit LCALL/LJMP/DPTR relocations. These changes should be
+invisible to the user.
+
+The linker can now also generated extended linear address records in the
+Intel hex output format. This is necessary for any areas located above the
+64K mark. This is enabled by the "-r" linker flag, and is disabled by
+default (but the linker will throw a warning if an extended address is
+encountered without the -r flag being enabled).
+
+Note that for various reasons, areas may still not be larger than 64K.
+However, they may be located anywhere in the 4 Meg address space via the
+assembler .org directive (for ABS areas) or the linker "-b" option.
+
+3: Examples
+
+Note that this example uses ABS areas to make the layout obvious. This code
+won't do anything useful at all, but demonstrates the instruction encoding
+in .flat24 mode vs 8051 mode.
+
+; test1.asm
+.area CODE (ABS)
+.org 0
+
+; SFRs not known to the assembler yet...
+$TA = 0x00C7
+$ACON = 0x009D
+
+; Set the chip to 24 bit flat mode via the DS "timed access" procedure.
+mov $TA, #0xAA
+mov $TA, #0x55
+mov $ACON, #0x06               ; 10 bit stack & 24 bit flat addressing.
+
+.flat24 on             ; Enable 24-bit mode. The AM1 bit had better be
+                       ; on...
+
+mov dptr, #myData      ; Valid on the '390: myData is in the FARDATA
+                       ; area at 0x300001.
+                       ; Generates: 90 30 00 01
+acall _junkNear                ; Within 11 bit range, but still must generate
+                       ; 19 bit address for '390 flat mode.
+                       ; Generates: 11 04 00                   
+ajmp _junkFar          ; Within 16 bit range.
+                       ; Generates 01 08 00
+acall _junkReallyFar   ; Within 19 bit range.
+                       ; Generates 91 00 00
+lcall _junkReallyReallyFar     ; Within 24 bit range.
+                       ; Generates 12 08 00 00
+
+; Set the chip to 8051 mode via the DS "timed access" procedure.
+mov $TA, #0x0AA
+mov $TA, #0x055
+mov $ACON, #0x00       ; 8 bit stack & 16 bit flat addressing.
+
+.flat24 off            ; Now we're an 8051 again. The AM1 bit had better be
+                       ; off...
+
+;mov dptr, #myData     ; Can't do that: myData is too far away.
+acall _junkNear                ; Within 11 bit range.
+                       ; Generates 91 00
+ljmp _junkFar          ; Within 16 bit range; can't AJMP, but can LJMP
+                       ; Generates 02 08 00
+ret
+
+.area CODE2 (ABS)
+.org 0x400
+; This is within the 11 bit ACALL/AJMP range of the 8051.
+_junkNear:
+ret
+
+.area CODE3 (ABS)
+.org 0x800
+; This is within the 390's 19 bit ACALL/AJMP range, and inside the stock
+; 8051's 16 bit LCALL range.
+_junkFar:
+ret
+
+.area CODE4 (ABS)
+; This is within the 390's 19 bit ACALL/AJMP range and outside the
+; 8051's LCALL range.
+; Note that to link an image with an area beyond 64K (like this one),
+; the '-r' flag must be provided to the linker, and Intel Hex output format
+; must be used.
+.org 0x40000
+_junkReallyFar:
+ret
+
+.area CODE5 (ABS)
+; This is outside anybody's ACALL/AJMP range.
+.org 0x80000
+_junkReallyReallyFar:
+ret
+
+.area FARDATA (ABS)
+.org 0x300000
+; This is way, way up there.
+.byte 0x01
+myData:
+.byte 0x02
+
+; test1.asm ends.
+
diff --git a/as/link/mcs51/strcmpi.c b/as/link/mcs51/strcmpi.c
new file mode 100644 (file)
index 0000000..434529c
--- /dev/null
@@ -0,0 +1,35 @@
+/* strcmpi.c */
+
+/*
+ * Compare two strings ignoring case.
+ *
+ * Taken from GLIBC 2.2.5. Original code is copyrighted "Free
+ * Software Foundation" and published under the GNU Lesser General
+ * Public License.
+ * 
+ */
+
+#include <ctype.h>
+#include "strcmpi.h"
+
+int as_strcmpi (const char *s1, const char *s2)
+{
+  const unsigned char *p1 = (const unsigned char *) s1;
+  const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2)
+    return 0;
+
+  do
+    {
+      c1 = tolower (*p1++);
+      c2 = tolower (*p2++);
+      if (c1 == '\0')
+       break;
+    }
+  while (c1 == c2);
+  
+  return c1 - c2;
+}
+
diff --git a/as/link/mcs51/strcmpi.h b/as/link/mcs51/strcmpi.h
new file mode 100644 (file)
index 0000000..63c35c4
--- /dev/null
@@ -0,0 +1,3 @@
+/* strcmpi.h */
+
+int as_strcmpi (const char *s1, const char *s2);
diff --git a/as/mcs51/Makefile.aslink b/as/mcs51/Makefile.aslink
deleted file mode 100644 (file)
index 0aebe56..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-CC=gcc
-LEX=flex
-YACC=bison
-INCROOT=.
-CFLAGS=-ggdb -O2 -I $(INCROOT)
-TARGETS=$(SDCCDIR)/bin/aslink
-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
-all:: $(TARGETS)
-
-clean::
-       rm -f $(TARGETS) $(ALLOBJECTS)
-
-lkmain.o : lkmain.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkmain.o lkmain.c
-
-lkhead.o : lkhead.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkhead.o lkhead.c
-
-lkarea.o : lkarea.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkarea.o lkarea.c
-
-lkdata.o : lkdata.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkdata.o lkdata.c
-
-lkeval.o : lkeval.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkeval.o lkeval.c
-
-lklex.o  : lklex.c  aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lklex.o lklex.c
-
-lksym.o  : lksym.c  aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lksym.o lksym.c
-
-lkrloc.o : lkrloc.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkrloc.o lkrloc.c
-
-lklibr.o : lklibr.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lklibr.o lklibr.c
-
-lklist.o : lklist.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lklist.o lklist.c
-
-lkihx.o  : lkihx.c  aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkihx.o lkihx.c
-
-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
-
-lknoice.o : lknoice.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lknoice.o lknoice.c
-
-strcmpi.o : strcmpi.c strcmpi.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o strcmpi.o strcmpi.c
-
-lkmem.o : lkmem.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkmem.o lkmem.c
-
-lkaomf51.o : lkaomf51.c aslink.h
-       $(CC) $(CFLAGS) $(LDFLAGS) -c -o lkaomf51.o lkaomf51.c
-
-$(TARGETS): $(ALLOBJECTS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(ALLOBJECTS) 
index 84e61f1f08edfa3d5cef1bd9d3038f888e0e3442..97fc05a640d07e7b8f01549f3335b2266e81296f 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile for Borlad C++
+# Makefile for Borland C++
 
 PRJDIR          = ../..
 
@@ -8,18 +8,9 @@ ASOBJECTS       = asmain.obj aslex.obj assym.obj assubr.obj asnoice.obj \
                   asexpr.obj asdata.obj aslist.obj asout.obj asstore.obj \
                   i51ext.obj i51pst.obj i51mch.obj i51adr.obj strcmpi.obj
 
-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
-
 ASX8051         = $(PRJDIR)/bin/asx8051.exe
-ASLINK          = $(PRJDIR)/bin/aslink.exe
 
-all: $(ASX8051) $(ASLINK)
+all: $(ASX8051)
 
 $(ASX8051): $(ASOBJECTS)
         $(CC) $(CFLAGS) -e$@ $(ASOBJECTS)
-
-$(ASLINK): $(LKOBJECTS)
-        $(CC) $(CFLAGS) -e$@ $(LKOBJECTS)
index 3511edcb45003ae21ede427352fcdcf7adbb32e2..42e5f995e4cdc726fb78ee8fe32ddd64f33fc2b9 100644 (file)
@@ -42,39 +42,27 @@ ASOBJECTS   = asmain.o aslex.o assym.o assubr.o asnoice.o \
                  i51ext.o i51pst.o i51mch.o i51adr.o strcmpi.o
 ASSOURCES      = $(patsubst %.o,%.c,$(ASOBJECTS))
 
-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
-LKSOURCES      = $(patsubst %.o,%.c,$(LKOBJECTS))
-
 ASX8051                = $(top_builddir)bin/asx8051$(EXEEXT)
-ASLINK         = $(top_builddir)bin/aslink$(EXEEXT)
 
 transform       = @program_transform_name@
 
 # Compiling entire program or any subproject
 # ------------------------------------------
-all: checkconf $(ASX8051) $(ASLINK)
+all: checkconf $(ASX8051)
 
 $(ASX8051): $(ASOBJECTS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(ASOBJECTS) 
-
-$(ASLINK): $(LKOBJECTS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LKOBJECTS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(ASOBJECTS)
 
-# Compiling and installing everything and runing test
-# ---------------------------------------------------
+# Compiling and installing everything and running test
+# ----------------------------------------------------
 install: all installdirs
        $(INSTALL) $(ASX8051) `echo $(DESTDIR)$(bindir)/asx8051$(EXEEXT)|sed '$(transform)'`
        $(STRIP) `echo $(DESTDIR)$(bindir)/asx8051$(EXEEXT)|sed '$(transform)'`
-       $(INSTALL) $(ASLINK) `echo $(DESTDIR)$(bindir)/aslink$(EXEEXT)|sed '$(transform)'`
-       $(STRIP) `echo $(DESTDIR)$(bindir)/aslink$(EXEEXT)|sed '$(transform)'`
 
 # Deleting all the installed files
 # --------------------------------
 uninstall:
-       rm -f $(DESTDIR)$(bindir)/asx8051$(EXEEXT) $(DESTDIR)$(bindir)/aslink$(EXEEXT)
+       rm -f $(DESTDIR)$(bindir)/asx8051$(EXEEXT)
 
 
 # Performing self-test
@@ -97,7 +85,7 @@ installdirs:
 # ---------------------
 dep: Makefile.dep
 
-Makefile.dep: $(ASSOURCES) $(LKSOURCES) $(srcdir)/*.h $(top_builddir)*.h $(top_srcdir)/*.h
+Makefile.dep: $(ASSOURCES) $(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/mcs51/aslink.h b/as/mcs51/aslink.h
deleted file mode 100644 (file)
index bcd921d..0000000
+++ /dev/null
@@ -1,788 +0,0 @@
-/* aslink.h */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * 28-Oct-97 JLH:
- *           - add proto for StoreString
- *           - change s_id from [NCPS] to pointer
- *           - change NCPS to 80
- *           - case sensitive
- *           - add R_J11 for 8051 assembler
- * 31-Oct-97 JLH:
- *           - add jflag and jfp for NoICE output
- * 30-Jan-98 JLH:
- *           - add memory space flags to a_flag for 8051
- */
-
-#define VERSION "V01.70 + NoICE + SDCC Feb 1999"
-
-/*
- * 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 <limits.h>
-#ifndef PATH_MAX                /* POSIX, but not required   */
- #if defined(__BORLANDC__) || defined(_MSC_VER)
-  #include <stdlib.h>
-  #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.
- */
-
-#define NCPS    80              /* characters per symbol (JLH: change from 8) */
-#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 */
-
-/*
- *      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 Byte */
-#define R_USGN  0x10            /* Unsigned Byte */
-
-#define R_NOPAG 0x00            /* Page Mode */
-#define R_PAG0  0x20            /* Page '0' */
-#define R_PAG   0x40            /* Page 'nnn' */
-
-#define R_LSB   0x00            /* low byte */
-#define R_MSB   0x80            /* high byte */
-
-#define R_BYT3  0x100           /* if R_BYTE is set, this is a
-                                 * 3 byte address, of which
-                                 * the linker must select one byte.
-                                 */
-#define R_HIB   0x200           /* If R_BYTE & R_BYT3 are set, linker
-                                 * will select byte 3 of the relocated
-                                 * 24 bit address.
-                                 */
-
-#define R_BIT   0x400           /* Linker will convert from byte-addressable
-                                 * space to bit-addressable space.
-                                 */
-
-#define R_J11   (R_WORD|R_BYT2) /* JLH: 11 bit JMP and CALL (8051) */
-#define R_J19   (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */
-#define R_C24   (R_WORD|R_BYT1|R_MSB) /* 24 bit address (DS80C390) */
-#define R_J19_MASK (R_BYTE|R_BYT2|R_MSB)
-
-#define IS_R_J19(x) (((x) & R_J19_MASK) == R_J19)
-#define IS_R_J11(x) (((x) & R_J19_MASK) == R_J11)
-#define IS_C24(x) (((x) & R_J19_MASK) == R_C24)
-
-#define R_ESCAPE_MASK   0xf0    /* Used to escape relocation modes
-                                 * greater than 0xff in the .rel
-                                 * file.
-                                 */
-
-/*
- * Global symbol types.
- */
-#define S_REF   1               /* referenced */
-#define S_DEF   2               /* defined */
-
-/*
- * 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 */
-
-/* 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 */
-
-/*
- * File types
- */
-#define F_STD   1               /* stdin */
-#define F_LNK   2               /* File.lnk */
-#define F_REL   3               /* File.rel */
-
-/*
- *      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 */
-        Addr_T  a_unaloc;       /* Total number of unalocated bytes, for error reporting */
-        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;          /* Name: JLH change from [NCPS] */
-};
-
-/*
- *      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 as_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    *jfp;           /*      NoICE 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  FILE    *dfp;           /*      File handle for debug info output
-                                 */
-extern  int     dflag;          /*      Output debug information flag
-                                 */
-extern  int     oflag;          /*      Output file type flag
-                                 */
-extern  int     mflag;          /*      Map output flag
-                                 */
-extern  int     sflag;          /*      JCF: Memory usage output flag
-                                 */
-extern  int     packflag;       /*      Pack data memory flag
-                                 */
-extern  int     stacksize;      /*      Pack data memory flag
-                                 */
-extern  int     jflag;          /*      NoICE output flag
-                                 */
-extern  int     xflag;          /*      Map file radix type flag
-                                 */
-extern  int     pflag;          /*      print linker command file flag
-                                 */
-extern  int     uflag;          /*      Listing relocation flag
-                                 */
-extern int      rflag;          /*      Extended linear address record 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
-                                 */
-extern  Addr_T iram_size;       /*      internal ram size
-                                 */
-extern  long xram_size;         /*      external ram size
-                                 */
-extern  long code_size;         /*      code size
-                                 */
-
-
-/* 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            iramsav();
-extern  VOID            xramsav();
-extern  VOID            codesav();
-extern  VOID            iramcheck();
-extern  VOID            link_main();
-extern  VOID            lkexit();
-extern  int             main();
-extern  VOID            map();
-extern  int             parse();
-extern  VOID            setbas();
-extern  VOID            setgbl();
-extern  VOID            usage();
-extern  VOID            copyfile();
-
-/* lklex.c */
-extern  char            endline();
-extern  char            get();
-extern  VOID            getfid();
-extern  VOID            getid();
-extern  VOID            getSid();
-extern  int             as_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            lnkarea2();
-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(register Addr_T v, register int i);
-extern  Addr_T          adb_bit(register Addr_T v, register int i);
-extern  Addr_T          adb_hi(Addr_T  v, int i);
-extern  Addr_T          adb_lo(Addr_T  v, int i);
-extern  Addr_T          adb_24_bit(register Addr_T v, register int i);
-extern  Addr_T          adb_24_hi(Addr_T v, int i);
-extern  Addr_T          adb_24_mid(Addr_T v, int i);
-extern  Addr_T          adb_24_lo(Addr_T v, int i);
-extern  Addr_T          adw_w(register Addr_T v, register int i);
-extern  Addr_T          adw_24(Addr_T v, int i);
-extern  Addr_T          adw_hi(Addr_T  v, int i);
-extern  Addr_T          adw_lo(Addr_T  v, int i);
-extern  Addr_T          evword(VOID);
-extern  VOID            rele(VOID);
-extern  VOID            reloc(char c);
-extern  VOID            relt(VOID);
-extern  VOID            relr(VOID);
-extern  VOID            relp(VOID);
-extern  VOID            relerr(char *str);
-extern  char *          errmsg[];
-extern  VOID            errdmp(FILE *fptr, char *str);
-extern  VOID            relerp(char *str);
-extern  VOID            erpdmp(FILE *fptr, char *str);
-extern  VOID            prntval(FILE *fptr, Addr_T v);
-extern  int             lastExtendedAddress;
-
-/* 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();
-extern  VOID            ihxEntendedLinearAddress(Addr_T);
-extern  VOID            newArea();
-
-/* lkstore.c */
-extern char             *StoreString( char *str );
-
-/* lknoice.c */
-extern void             DefineNoICE( char *name, Addr_T value, int page );
-
-/* JCF: lkmem.c */
-extern int summary(struct area * xp);
-extern int summary2(struct area * xp);
-
-/* JCF: lkaomf51.c */
-extern void SaveLinkedFilePath(char * filepath);
-extern void CreateAOMF51(void);
diff --git a/as/mcs51/aslink.mak b/as/mcs51/aslink.mak
deleted file mode 100644 (file)
index 300803d..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-ORIGIN         = Symantec C++
-ORIGIN_VER     = Version 7.00
-VERSION                = RELEASE
-
-!IFDEF SUB_DEBUG
-DEBUG          = $(SUB_DEBUG)
-NDEBUG         = !$(SUB_DEBUG)
-!ELSE
-DEBUG          = 0
-NDEBUG         = 1
-!ENDIF
-
-PROJ           = ASLINK
-APPTYPE                = DOS EXE
-PROJTYPE       = EXE
-
-CC             = SC
-CPP            = SPP
-MAKE           = SMAKE
-RC             = RCC
-HC             = HC31
-ASM            = SC
-DISASM         = OBJ2ASM
-LNK            = LINK
-DLLS           = 
-
-HEADERS                = ..\linksrc\aslink.h 
-
-DEFFILE                = ASLINK.DEF
-
-!IF $(DEBUG)
-OUTPUTDIR      = .
-CREATEOUTPUTDIR        =
-TARGETDIR      = .
-CREATETARGETDIR        =
-
-LIBS           = 
-
-CFLAGS         =  -A -Jm -J -ms -o+time -S -2 -a2 -c 
-LFLAGS         =  /PACKF
-DEFINES                = -D_DEBUG=1
-!ELSE
-OUTPUTDIR      = .
-CREATEOUTPUTDIR        =
-TARGETDIR      = .
-CREATETARGETDIR        =
-
-LIBS           = 
-
-CFLAGS         =  -A -Jm -J -ms -o+time -S -2 -a2 -c 
-LFLAGS         =  /PACKF
-DEFINES                = 
-!ENDIF
-
-HFLAGS         = $(CFLAGS) 
-MFLAGS         = MASTERPROJ=$(PROJ) 
-LIBFLAGS       =  /C 
-RESFLAGS       =  
-DEBUGGERFLAGS  =  -LOADSYMBOLS 
-AFLAGS         = $(CFLAGS) 
-HELPFLAGS      = 
-
-MODEL          = S
-
-PAR            = PROJS BATS OBJS
-
-RCDEFINES      = 
-
-LIBDIRS                = 
-
-INCLUDES       = -Ic:\asxxxx\linksrc
-
-INCLUDEDOBJS   = 
-
-OBJS           =  $(OUTPUTDIR)\lkarea.OBJ  $(OUTPUTDIR)\lkdata.OBJ  $(OUTPUTDIR)\lkeval.OBJ  \
-                $(OUTPUTDIR)\lkhead.OBJ  $(OUTPUTDIR)\lkihx.OBJ  $(OUTPUTDIR)\lklex.OBJ  $(OUTPUTDIR)\lklibr.OBJ  \
-                $(OUTPUTDIR)\lklist.OBJ  $(OUTPUTDIR)\lkmain.OBJ  $(OUTPUTDIR)\lkrloc.OBJ  $(OUTPUTDIR)\lks19.OBJ  \
-                $(OUTPUTDIR)\lksym.OBJ 
-
-RCFILES                = 
-
-RESFILES       = 
-
-SYMS           = 
-
-HELPFILES      = 
-
-BATS           = 
-
-.SUFFIXES: .C .CP .CPP .CXX .CC .H .HPP .HXX .COM .EXE .DLL .LIB .RTF .DLG .ASM .RES .RC .OBJ 
-
-.C.OBJ:
-       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.c
-
-.CPP.OBJ:
-       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cpp
-
-.CXX.OBJ:
-       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cxx
-
-.CC.OBJ:
-       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cc
-
-.CP.OBJ:
-       $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.cp
-
-.H.SYM:
-       $(CC) $(HFLAGS) $(DEFINES) $(INCLUDES) -HF -o$(*B).sym $*.h
-
-.HPP.SYM:
-       $(CC) $(HFLAGS) $(DEFINES) $(INCLUDES) -HF -o$(*B).sym $*.hpp
-
-.HXX.SYM:
-       $(CC) $(HFLAGS) $(DEFINES) $(INCLUDES) -HF -o$(*B).sym $*.hxx
-
-.C.EXP:
-       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES)   $*.c   -o$*.lst
-
-.CPP.EXP:
-       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) $*.cpp -o$*.lst
-
-.CXX.EXP:
-       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) $*.cxx -o$*.lst
-
-.CP.EXP:
-       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES)  $*.cp  -o$*.lst
-
-.CC.EXP:
-       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES)  $*.cc  -o$*.lst
-
-.ASM.EXP:
-       $(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) $*.asm -o$*.lst
-
-.OBJ.COD:
-       $(DISASM) $*.OBJ >$*.cod
-
-.OBJ.EXE:
-       $(LNK) $(LFLAGS) @$(PROJ).LNK
-
-.RTF.HLP:
-       $(HC) $(HELPFLAGS) $*.HPJ
-
-.ASM.OBJ:
-       $(ASM) $(AFLAGS) $(DEFINES) $(INCLUDES) -o$*.obj $*.asm
-
-.RC.RES: 
-       $(RC) $(RCDEFINES) $(RESFLAGS) $(INCLUDES) $*.rc -o$*.res
-
-.DLG.RES:
-       echo ^#include "windows.h" >$$$*.rc
-       echo ^IF EXIST "$*.h" >>$$$*.rc
-       echo ^#include "$*.h" >>$$$*.rc
-       echo ^#include "$*.dlg" >>$$$*.rc
-       $(RC) $(RCDEFINES) $(RESFLAGS) $(INCLUDES) $$$*.rc
-       -del $*.res
-       -ren $$$*.res $*.res
-
-
-
-all:   createdir $(PRECOMPILE) $(SYMS) $(OBJS) $(INCLUDEDOBJS) $(POSTCOMPILE) $(TARGETDIR)\$(PROJ).$(PROJTYPE) $(POSTLINK) _done
-
-createdir:
-       $(CREATEOUTPUTDIR)
-       $(CREATETARGETDIR)
-
-$(TARGETDIR)\$(PROJ).$(PROJTYPE): $(OBJS) $(INCLUDEDOBJS) $(RCFILES) $(RESFILES) $(HELPFILES) 
-                       $(LNK) $(LFLAGS) @$(PROJ).LNK;
-                       -del $(TARGETDIR)\$(PROJ).$(PROJTYPE)
-                       -ren $(TARGETDIR)\$$SCW$$.$(PROJTYPE) $(PROJ).$(PROJTYPE)
-                       -echo $(TARGETDIR)\$(PROJ).$(PROJTYPE) built
-
-_done:
-               -echo $(PROJ).$(PROJTYPE) done
-
-buildall:      clean   all
-
-
-clean:
-               -del $(TARGETDIR)\$$SCW$$.$(PROJTYPE)
-               -del $(TARGETDIR)\$(PROJ).CLE
-               -del $(OUTPUTDIR)\SCPH.SYM
-               -del $(OBJS)
-
-cleanres:
-
-res:           cleanres $(RCFILES) all
-
-
-link:
-               $(LNK) $(LFLAGS) @$(PROJ).LNK;
-               -del $(TARGETDIR)\$(PROJ).$(PROJTYPE)
-               -ren $(TARGETDIR)\$$SCW$$.$(PROJTYPE) $(PROJ).$(PROJTYPE)
-
-
-
-
-!IF EXIST (ASLINK.dpd)
-!INCLUDE ASLINK.dpd
-!ENDIF
-
-
-
-$(OUTPUTDIR)\lkarea.OBJ:       ..\linksrc\lkarea.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkarea.obj ..\linksrc\lkarea.c
-
-
-
-$(OUTPUTDIR)\lkdata.OBJ:       ..\linksrc\lkdata.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkdata.obj ..\linksrc\lkdata.c
-
-
-
-$(OUTPUTDIR)\lkeval.OBJ:       ..\linksrc\lkeval.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkeval.obj ..\linksrc\lkeval.c
-
-
-
-$(OUTPUTDIR)\lkhead.OBJ:       ..\linksrc\lkhead.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkhead.obj ..\linksrc\lkhead.c
-
-
-
-$(OUTPUTDIR)\lkihx.OBJ:        ..\linksrc\lkihx.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkihx.obj ..\linksrc\lkihx.c
-
-
-
-$(OUTPUTDIR)\lklex.OBJ:        ..\linksrc\lklex.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lklex.obj ..\linksrc\lklex.c
-
-
-
-$(OUTPUTDIR)\lklibr.OBJ:       ..\linksrc\lklibr.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lklibr.obj ..\linksrc\lklibr.c
-
-
-
-$(OUTPUTDIR)\lklist.OBJ:       ..\linksrc\lklist.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lklist.obj ..\linksrc\lklist.c
-
-
-
-$(OUTPUTDIR)\lkmain.OBJ:       ..\linksrc\lkmain.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkmain.obj ..\linksrc\lkmain.c
-
-
-
-$(OUTPUTDIR)\lkrloc.OBJ:       ..\linksrc\lkrloc.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lkrloc.obj ..\linksrc\lkrloc.c
-
-
-
-$(OUTPUTDIR)\lks19.OBJ:        ..\linksrc\lks19.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lks19.obj ..\linksrc\lks19.c
-
-
-
-$(OUTPUTDIR)\lksym.OBJ:        ..\linksrc\lksym.c
-               $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o$(OUTPUTDIR)\lksym.obj ..\linksrc\lksym.c
-
-
-
-
index 829d06942953889e3cb7ae41f405f07baeb890fa..90a6b2a9b25b0b15f117250c05a2e32f9cb94c69 100644 (file)
@@ -5,7 +5,7 @@ include $(top_builddir)Makefile.common
 clean:
        rm -f *core *[%~] *.[oa]
        rm -f .[a-z]*~
-       rm -f $(top_builddir)bin/asx8051$(EXEEXT) $(top_builddir)bin/aslink$(EXEEXT) asx8051$(EXEEXT) aslink$(EXEEXT)
+       rm -f $(top_builddir)bin/asx8051$(EXEEXT) asx8051$(EXEEXT)
 
 
 # Deleting all files created by configuring or building the program
diff --git a/as/mcs51/lkaomf51.c b/as/mcs51/lkaomf51.c
deleted file mode 100644 (file)
index 7e65031..0000000
+++ /dev/null
@@ -1,987 +0,0 @@
-/*-------------------------------------------------------------------------
-  lkaomf51.c - Create an absolute object memory format 51 file
-
-   Written By -  Jesus Calvino-Fraga, jesusc@ieee.org (2002)
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
--------------------------------------------------------------------------*/
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "aslink.h"
-
-#define EQ(A,B) !strcmp((A),(B))
-#define MEMSIZE 0x10000
-//#define DODUMP 1
-
-typedef struct
-{
-       char PathName[PATH_MAX];
-       char ModuleName[PATH_MAX];
-} _infn;
-
-int numin=0;
-_infn * infn=NULL;
-
-char ihxFileName[PATH_MAX];
-char aomf51FileName[PATH_MAX];
-
-typedef struct
-{
-   char name[0x100];
-   int FileNameNumber;
-   int Procedure;//If the symbol belongs to a function
-   int Static; //If the symbol is only public on its file
-   int Address;
-   int UsageType;
-} _symbol;
-
-int numsym=0;
-_symbol * symbol=NULL;
-
-typedef struct
-{
-   char name[0x100];
-   int FileNameNumber;
-   int BeginAdd;
-   int EndAdd;
-} _procedure;
-
-int numproc=0;
-_procedure * procedure=NULL;
-
-typedef struct
-{
-   int Number;
-   int Address;
-   int Procedure;
-   int FileNameNumber;
-} _linenum;
-
-int numlinenum=0;
-_linenum * linenum=NULL;
-#if 0
-typedef struct
-{
-       char * name;
-       int usage;
-}
-_UsageType;
-
-_UsageType UsageType[]=
-{
-       {"CSEG",                0},
-       {"GSINIT",              0},
-       {"GSINIT0",             0},
-       {"GSINIT1",             0},
-       {"GSINIT2",             0},
-       {"GSINIT3",             0},
-       {"GSINIT4",             0},
-       {"GSINIT5",             0},
-       {"GSFINAL",             0},
-       {"HOME",                0},
-       {"XINIT",               0},
-       {"XSEG",                1},
-       {"XISEG",               1},
-       {"REG_BANK_0",  2},
-       {"REG_BANK_1",  2},
-       {"REG_BANK_2",  2},
-       {"REG_BANK_3",  2},
-       {"DSEG",                2},
-       {"OSEG",                2},
-       {"SSEG",                2},
-       {"ISEG",                3},
-       {"BSEG",                4},
-       {"",                    5} /*A typeless number?*/
-};
-#endif
-char * UsageTypeName[]={"CODE", "XDATA", "DATA", "IDATA", "BIT", "NUMBER"};
-int AddNumber;
-unsigned char * ihxBuff=NULL;
-FILE * aomf51out;
-int GlobalChkSum=0;
-int HexSize, HexBegin=0x10000;
-
-
-void GetName(char * filepath, char * name)
-{
-       int j, k;
-       for(j=strlen(filepath); j>0; j--)
-               if( (filepath[j-1]=='/')||(filepath[j-1]=='\\') ) break;
-       for(k=0; (filepath[j]!=0)&&(filepath[j]!='.'); j++, k++)
-               name[k]=filepath[j];
-       name[k]=0;
-}
-
-void SaveLinkedFilePath(char * filepath) 
-{
-       int j;
-
-       if((dflag) && (!rflag))
-       {
-               infn=realloc(infn, sizeof(_infn)*(numin+1));
-
-               strcpy(infn[numin].PathName, filepath);
-               j=strlen(infn[numin].PathName);
-               
-               /*If there is an extension remove it*/
-               if(j>=4)
-               {
-                       if(EQ(&infn[numin].PathName[j-4], ".rel"))
-                       {
-                               infn[numin].PathName[j-4]=0;
-                       }
-               }
-
-               /*Get the module name=filename, no drive, no dir, no ext*/
-               GetName(infn[numin].PathName, infn[numin].ModuleName);
-               //printf("%s, %s\n", infn[numin].PathName, infn[numin].ModuleName);
-               
-               /*Check if this filename is already in*/
-               for(j=0; j<numin; j++)
-               {
-                       if(EQ(infn[numin].PathName, infn[j].PathName)) break;
-               }
-               if(j==numin) numin++;
-       }
-}
-
-void FreeAll(void)
-{
-       if(infn!=NULL)
-       {
-               free(infn);
-               numin=0;
-               infn=NULL;
-       }
-
-       if(symbol!=NULL)
-       {
-               free(symbol);
-               numsym=0;
-               symbol=NULL;
-       }
-
-       if(procedure!=NULL)
-       {
-               free(procedure);
-               numproc=0;
-               procedure=NULL;
-
-       }
-       if(linenum!=NULL)
-       {
-               free(linenum);
-               numlinenum=0;
-               linenum=NULL;
-       }
-
-       if(ihxBuff!=NULL)
-       {
-               free(ihxBuff);
-               ihxBuff=NULL;
-       }
-}
-
-void OutputByte(unsigned char value)
-{
-       GlobalChkSum+=value;
-       fwrite( &value, 1, 1, aomf51out );
-}
-
-void OutputWord(int value)
-{
-       OutputByte((unsigned char)(value%0x100));
-       OutputByte((unsigned char)(value/0x100));
-}
-
-void OutputName(char * name)
-{
-       int k;
-       OutputByte((unsigned char)strlen(name));
-       for(k=0; name[k]!=0; k++)
-               OutputByte((unsigned char)toupper(name[k]));
-}
-
-void OutputChkSum(void)
-{
-       OutputByte((unsigned char)(0x100-(GlobalChkSum%0x100)));
-       GlobalChkSum=0;
-}
-
-#ifdef DODUMP
-void DumpForDebug (void)
-{
-       char DumpFileName[PATH_MAX];
-       FILE * DumpFile;
-       int j, k;
-
-       strcpy(DumpFileName, infn[0].PathName);
-       strcat(DumpFileName, ".d51");
-
-       DumpFile=fopen(DumpFileName, "wb");
-       if(DumpFile==NULL)
-       {
-               printf("Couldn't create file %s\n", DumpFileName);
-               return;
-       }
-
-       fprintf(DumpFile,"SYMBOLS:\n");
-
-       for(j=0; j<numsym; j++)
-       {
-               k=symbol[j].UsageType&0xf;
-               fprintf(DumpFile, "%s, %s, %s, 0x%04x, %s\n",
-                       symbol[j].name,
-                       infn[symbol[j].FileNameNumber].PathName,
-                       (symbol[j].Procedure>=0)?procedure[symbol[j].Procedure].name:"GLOBAL",
-                       symbol[j].Address,
-                       k<6?UsageTypeName[k]:"???");
-       }
-       
-       fprintf(DumpFile,"\nPROCEDURES:\n");
-       for(j=0; j<numproc; j++)
-       {
-               fprintf(DumpFile, "%s, %s, 0x%04x-0x%04x\n",
-                       procedure[j].name,
-                       infn[procedure[j].FileNameNumber].PathName,
-                       procedure[j].BeginAdd,
-                       procedure[j].EndAdd);
-       }
-
-       fprintf(DumpFile,"\nLINE NUMBERS:\n");
-       for(j=0; j<numlinenum; j++)
-       {
-               fprintf(DumpFile, "%d:0x%04x, %s -> %s\n",
-                       linenum[j].Number,
-                       linenum[j].Address,
-                       infn[linenum[j].FileNameNumber].PathName,
-                       (linenum[j].Procedure>=0)?procedure[linenum[j].Procedure].name:"I don't know");
-       }
-
-       fclose(DumpFile);
-}
-#endif
-
-void OutputAOEMF51(void)
-{
-       int i, j, k, recsize;
-       char MHRname[0x100], Mname[0x100];
-
-       strcpy(aomf51FileName, infn[0].PathName);
-
-       aomf51out=fopen(aomf51FileName, "wb");
-       if(aomf51out==NULL)
-       {
-               printf("Couldn't create file %s\n", aomf51FileName);
-               return;
-       }
-
-       GetName(infn[0].PathName, MHRname);
-       GlobalChkSum=0;
-       
-       /*Module header record*/
-       OutputByte(0x02);/*REC TYPE*/
-       OutputWord((strlen(MHRname)+1)+3);/*Record Length*/
-       OutputName(MHRname);/*Module Name*/
-       OutputByte(0xff);/*TRN ID: RL51?*/
-       OutputByte(0x00);
-       OutputChkSum();
-
-       for(j=0; j<numin; j++)
-       {
-               GetName(infn[j].PathName, Mname);
-
-               /*Scope Definition record: begin module block*/
-               OutputByte(0x10);/*REC TYPE*/
-               OutputWord((strlen(Mname)+1)+2);/*Record Length*/
-               OutputByte(0x00);/*BLK TYP: module block*/
-               OutputName(Mname);/*Module Name*/
-               OutputChkSum();
-
-               /*Public symbols defined in this module*/
-               recsize=2;
-               for(k=0; k<numsym; k++)/*Compute the record length*/
-                       if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
-                                (symbol[k].Procedure==-1) &&
-                                (symbol[k].Static==-1) ) recsize+=((strlen(symbol[k].name)+1)+5);
-
-               if(recsize>2) /*If there are any symbols*/
-               {
-                       OutputByte(0x12);       /*REC TYPE*/
-                       OutputWord(recsize);/*Record Length*/
-                       OutputByte(0x01);       /*DEF TYPE: Public symbols*/
-                       for(k=0; k<numsym; k++)
-                       {
-                               if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
-                                        (symbol[k].Procedure==-1) &&
-                                        (symbol[k].Static==-1) )
-                               {
-                                       OutputByte(0x00);/*SEG ID*/
-                                       OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
-                                       OutputWord(symbol[k].Address);/*Offset*/
-                                       OutputByte(0x00);
-                                       OutputName(symbol[k].name);/*Symbol name*/
-                               }
-                       }
-                       OutputChkSum();
-               }
-
-               /*Local symbols defined in this module*/
-               recsize=2;
-               for(k=0; k<numsym; k++)/*Compute the record length*/
-                       if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
-                                (symbol[k].Procedure==-1) &&
-                                (symbol[k].Static==j) ) recsize+=((strlen(symbol[k].name)+1)+5);
-
-               if(recsize>2) /*If there are any symbols*/
-               {
-                       OutputByte(0x12);       /*REC TYPE*/
-                       OutputWord(recsize);/*Record Length*/
-                       OutputByte(0x00);       /*DEF TYPE: Local symbols*/
-                       for(k=0; k<numsym; k++)
-                       {
-                               if ( (symbol[k].FileNameNumber==j) && (symbol[k].Address!=-1) &&
-                                        (symbol[k].Procedure==-1) &&
-                                        (symbol[k].Static==j) )
-                               {
-                                       OutputByte(0x00);/*SEG ID*/
-                                       OutputByte((unsigned char)symbol[k].UsageType);/*SYM INFO*/
-                                       OutputWord(symbol[k].Address);/*Offset*/
-                                       OutputByte(0x00);
-                                       OutputName(symbol[k].name);/*Symbol name*/
-                               }
-                       }
-                       OutputChkSum();
-               }
-
-               /*Output the procedures of this module*/
-
-               for(k=0; k<numproc; k++)
-               {
-                       if(procedure[k].FileNameNumber==j)
-                       {
-                               /*Scope Definition record: begin PROCEDURE block*/
-                               OutputByte(0x10);/*REC TYPE*/
-                               OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
-                               OutputByte(0x02);/*BLK TYP: PROCEDURE block*/
-                               OutputName(procedure[k].name);/*Module Name*/
-                               OutputChkSum();
-
-                               /*Content Record*/
-                               OutputByte(0x06);/*REC TYPE*/
-                               if(procedure[k].EndAdd==-1) procedure[k].EndAdd=HexSize;
-                               recsize=procedure[k].EndAdd-procedure[k].BeginAdd+1+4;
-                               OutputWord(recsize);/*Record Length*/
-                               OutputByte(0x00);/*SEG ID*/
-                               OutputWord(procedure[k].BeginAdd); /*Offset*/
-                               for(i=procedure[k].BeginAdd; i<=procedure[k].EndAdd; i++)
-                                       OutputByte(ihxBuff[i]);
-                               OutputChkSum();
-
-                               /*Local Symbols*/
-                               
-                               recsize=2;
-                               for(i=0; i<numsym; i++)/*Get the record length*/
-                                       if(symbol[i].Procedure==k)
-                                               recsize+=((strlen(symbol[i].name)+1)+5);
-
-                               if(recsize>2) /*If there are any symbols*/
-                               {
-                                       OutputByte(0x12);       /*REC TYPE*/
-                                       OutputWord(recsize);/*Record Length*/
-                                       OutputByte(0x00);       /*DEF TYPE: Local symbols*/
-                                       for(i=0; i<numsym; i++)
-                                       {
-                                               if ( (symbol[i].Procedure==k) )
-                                               {
-                                                       OutputByte(0x00);/*SEG ID*/
-                                                       OutputByte((unsigned char)symbol[i].UsageType);/*SYM INFO*/
-                                                       OutputWord(symbol[i].Address);/*Offset*/
-                                                       OutputByte(0x00);
-                                                       OutputName(symbol[i].name);/*Symbol name*/
-                                               }
-                                       }
-                                       OutputChkSum();
-                               }
-
-                               /*Line Numbers*/
-                               recsize=2;
-                               for(i=0; i<numlinenum; i++)/*Get the record length*/
-                                       if(linenum[i].Procedure==k) recsize+=5;
-                               
-                               if(recsize>2) /*If there are any line numbers*/
-                               {
-                                       OutputByte(0x12);       /*REC TYPE*/
-                                       OutputWord(recsize);/*Record Length*/
-                                       OutputByte(0x03);       /*DEF TYPE: Line numbers*/
-                                       for(i=0; i<numlinenum; i++)
-                                       {
-                                               if ( (linenum[i].Procedure==k) )
-                                               {
-                                                       OutputByte(0x00);/*SEG ID*/
-                                                       OutputWord(linenum[i].Address);/*Offset*/
-                                                       OutputWord(linenum[i].Number);/*Line Number*/
-                                               }
-                                       }
-                                       OutputChkSum();
-                               }
-                       
-                               /*Scope Definition record: end PROCEDURE block*/
-                               OutputByte(0x10);/*REC TYPE*/
-                               OutputWord((strlen(procedure[k].name)+1)+2);/*Record Length*/
-                               OutputByte(0x05);/*BLK TYP: PROCEDURE end block*/
-                               OutputName(procedure[k].name);/*Module Name*/
-                               OutputChkSum();
-                       }
-               }
-
-               /*Scope Definition record: end module block*/
-               OutputByte(0x10);/*REC TYPE*/
-               OutputWord((strlen(Mname)+1)+2);/*Record Length*/
-               OutputByte(0x03);/*BLK TYP: module end*/
-               OutputName(Mname);/*Module Name*/
-               OutputChkSum();
-       }
-
-       /*Content records for everything that is not in the above procedures*/
-       strcpy(Mname, "OTHER_SDCC_STUF");
-
-       /*Scope Definition record: begin module block*/
-       OutputByte(0x10);/*REC TYPE*/
-       OutputWord((strlen(Mname)+1)+2);/*Record Length*/
-       OutputByte(0x00);/*BLK TYP: module block*/
-       OutputName(Mname);/*Module Name*/
-       OutputChkSum();
-
-       for(j=-1; j<numproc; j++)
-       {
-               if(numproc)
-               {
-                       if(j==-1)
-                       {
-                               i=HexBegin;
-                               k=procedure[0].BeginAdd;
-                       }
-                       else if(j==(numproc-1))
-                       {
-                               i=procedure[j].EndAdd+1;
-                               k=HexSize;
-                       }
-                       else
-                       {
-                               i=procedure[j].EndAdd+1;
-                               k=procedure[j+1].BeginAdd;
-                       }
-               }
-               else /*What, no procedures??? Ok, here it is the whole hex file*/
-               {
-                       i=HexBegin;
-                       k=HexSize;
-               }
-
-               if(i<k)
-               {
-                       /*Content Record*/
-                       OutputByte(0x06);/*REC TYPE*/
-                       OutputWord(k-i+4);/*Record Length*/
-                       OutputByte(0x00);/*SEG ID*/
-                       OutputWord(i); /*Offset*/
-                       for(; i<k; i++) OutputByte(ihxBuff[i]);
-                       OutputChkSum();
-               }
-       }
-       
-       /*Scope Definition record: end module block*/
-       OutputByte(0x10);/*REC TYPE*/
-       OutputWord((strlen(Mname)+1)+2);/*Record Length*/
-       OutputByte(0x03);/*BLK TYP: module end*/
-       OutputName(Mname);/*Module Name*/
-       OutputChkSum();
-
-       /*Module end record*/
-       OutputByte(0x04);/*REC TYPE*/
-       OutputWord((strlen(MHRname)+1)+5);/*Record Length*/
-       OutputName(MHRname);/*Module Name*/
-       OutputWord(0x00);
-       OutputByte(0x0f);/*REG MSK: All the register banks?*/
-       OutputByte(0x00);
-       OutputChkSum();
-
-       fclose(aomf51out);
-}
-
-void CollectInfoFromCDB(void)
-{
-       int i, j, k, CurrentModule;
-       FILE * CDBin;
-       char buff[0x1000];
-       char SourceName[PATH_MAX];
-
-       //"S:{G|F<filename>|L<functionName>}$<name>$<level>$<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>"
-       char Sfmt[]="%[^$] %c %[^$] %c %[^$] %c %s";
-       char c;
-       char scope[0x100];
-       char name[0x100];
-       char level[0x100];
-       char block[0x100];
-       char Bfmt[]="%[^)] %c %c %c %c %d %c %d";
-       char TypeInfo[0x100];
-       char AddressSpace;
-       int OnStack;
-       int StackOffset;
-       int Address, CLine;
-       
-       if(numin==0) return;
-
-       if (dfp != NULL)
-       {
-               fclose(dfp);
-               dfp=NULL;
-       }
-
-       /*Build the source filename*/
-       strcpy(SourceName, infn[0].PathName);
-       strcat(SourceName, ".cdb");
-       CDBin=fopen(SourceName, "r");
-       if(CDBin==NULL)
-       {
-               printf("Couldn't open file '%s'\n", SourceName);
-               lkexit(1);
-       }
-
-       CurrentModule=0; /*Set the active module as the first one*/
-       while(!feof(CDBin))
-       {
-               fgets(buff, sizeof(buff)-1, CDBin);
-
-               if(!feof(CDBin)) switch(buff[0])
-               {
-                       /*Example: "M:adq"*/
-                       case 'M':
-                               sscanf(&buff[2], "%s", name);
-                               for(j=0; j<numin; j++)
-                                       if(EQ(infn[j].ModuleName, name)) break;
-                               if(j<numin) CurrentModule=j;
-                       break;
-
-                       /* Example:
-                       "S:G$actual$0$0({7}ST__00010000:S),E,0,0"
-                       "S:Lmain$j$1$1({2}SI:S),E,0,0"
-                       "S:G$DS1306_Reset_SPI$0$0({2}DF,SV:S),C,0,0"
-                       "S:G$main$0$0({2}DF,SV:S),C,0,0"
-                       */
-
-                       case 'S':
-                               sscanf(buff, Sfmt,
-                                       scope, &c,
-                                       name, &c,
-                                       level, &c,
-                                       block);
-                               
-                               /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>*/
-                               sscanf(block, Bfmt,
-                                          TypeInfo, &c, &c,
-                                          &AddressSpace, &c,
-                                          &OnStack, &c, 
-                                          &StackOffset);
-
-                               i=-1; k=-1;
-                               switch(scope[2])
-                               {
-                                       case 'G': /*Global symbol*/
-                                       break;
-                                       case 'L': /*Local symbol of a procedure*/
-                                               for(j=0; j<numproc; j++)
-                                               {
-                                                       if(EQ(&scope[3], procedure[j].name)) break;
-                                               }
-                                               if(j<numproc) k=j; /*Local symbol*/
-                                       break;
-                                       case 'F': /*Local symbol to a module*/
-                                               for(j=0; j<numin; j++)
-                                               {
-                                                       if(EQ(&scope[3], infn[j].ModuleName)) break;
-                                               }
-                                               if(j<numin) i=j;
-                                       break;
-                               }
-
-                               /*This symbol may have been already defined*/
-                               for(j=0; j<numsym; j++)
-                               {
-                                       if( EQ(name, symbol[j].name) && 
-                                               (symbol[j].Procedure==k) &&
-                                               (symbol[j].Static==i) ) break;
-                               }
-                               if(j==numsym) /*New symbol*/
-                               {
-                                       symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
-                                       symbol[numsym].FileNameNumber=CurrentModule;
-                                       strcpy(symbol[numsym].name, name);
-                                       symbol[numsym].Procedure=k;
-                                       symbol[numsym].Static=i;
-                                       symbol[numsym].Address=-1;/*Collected later*/
-
-                                       switch(AddressSpace)
-                                       {
-                                               case 'C': /*Code*/ 
-                                               case 'D': /*Code/static segment*/ 
-                                               case 'Z': /*Functions and undefined code space*/ 
-                                                       symbol[numsym].UsageType=0x40;
-                                               break;
-
-                                               case 'F': /*External ram*/ 
-                                               case 'A': /*External stack*/
-                                                       symbol[numsym].UsageType=0x41;
-                                               break;
-
-                                               case 'E': /*Internal ram (lower 128) bytes*/ 
-                                               case 'I': /*SFR space*/ 
-                                               case 'R': /*Register Space*/ 
-                                                       symbol[numsym].UsageType=0x42;
-                                               break;
-
-                                               case 'B': /*Internal stack*/ 
-                                               case 'G': /*Internal ram*/ 
-                                                       symbol[numsym].UsageType=0x43;
-                                               break;
-
-                                               case 'H': /*Bit addressable*/ 
-                                               case 'J': /*SBIT space*/ 
-                                                       symbol[numsym].UsageType=0x44;
-                                               break;
-                                               
-                                               default:
-                                                       printf("Unknown scope information for: %s, AddressSpace:%c\n", symbol[numsym].name, AddressSpace);
-                                               break;
-                                       }
-                                       numsym++;
-                               }
-                       break;
-
-                       /*Examples:
-                       F:G$AsciiToHex$0$0({2}DF,SC:U),C,0,0,0,0,0
-                       F:G$main$0$0({2}DF,SV:S),C,0,0,0,0,0   */
-
-                       case 'F':
-                               sscanf(buff, "%[^$] %c %[^$]", scope, &c, name);
-                               /*The same may have been already defined */
-                               for(j=0; j<numproc; j++)
-                               {
-                                       if(EQ(name, procedure[j].name)) break;
-                               }
-                               if(j==numproc)
-                               {
-                                       procedure=realloc(procedure, sizeof(_procedure)*(numproc+1));
-                                       strcpy(procedure[numproc].name, name);
-                                       procedure[numproc].FileNameNumber=CurrentModule;
-                                       procedure[numproc].BeginAdd=-1;/*To be collected latter*/
-                                       procedure[numproc].EndAdd=-1;/*To be collected latter*/
-                                       numproc++;
-                               }
-                               
-                               /*This function name is also a global symbol*/
-                               for(j=0; j<numsym; j++)/*A global symbol may have been already defined*/
-                               {
-                                       if( EQ(name, symbol[j].name) && (symbol[j].Procedure==-1) ) break;
-                               }
-                               if(j==numsym)
-                               {
-                                       symbol=realloc(symbol, sizeof(_symbol)*(numsym+1));
-                                       symbol[numsym].FileNameNumber=CurrentModule;
-                                       strcpy(symbol[numsym].name, name);
-                                       symbol[numsym].UsageType=0x00;/*A procedure name symbol*/
-                                       symbol[numsym].Procedure=-1; /*Global symbol*/
-                                       symbol[numsym].Address=-1;/*Collected later*/
-                                       symbol[numsym].Static=-1; // o_gloom
-                                       numsym++;
-                               }
-                       break;
-
-                       case 'L':
-                               switch(buff[2])
-                               {
-                                       case 'G': /*Example L:G$P0$0$0:80*/
-                                               sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
-                                                       scope, &c, name, &c, level, &c, &Address);
-
-                                               for(j=0; j<numsym; j++)
-                                               {
-                                                       if(EQ(symbol[j].name, name))
-                                                       {
-                                                               if( (symbol[j].Address==-1) && (symbol[j].Procedure==-1) )
-                                                               {
-                                                                       symbol[j].Address=Address;
-                                                               }
-                                                               
-                                                               /*If the symbol is the name of a procedure, the address is also
-                                                               the begining of such procedure*/
-                                                               if((symbol[j].UsageType&0x0f)==0x00)
-                                                               {
-                                                                       for(k=0; k<numproc; k++)
-                                                                       {
-                                                                               if(EQ(symbol[j].name, procedure[k].name))
-                                                                               {
-                                                                                       if(procedure[k].BeginAdd==-1)
-                                                                                               procedure[k].BeginAdd=Address;
-                                                                                       break;
-                                                                               }
-                                                                       }
-                                                               }
-                                                               
-                                                               break;
-                                                       }
-                                               }
-                                       break;
-                                       
-                                       case 'F': /*Example L:Fadq$_str_2$0$0:57A*/
-                                               sscanf(buff, "%[^$] %c %[^$] %c %[^:] %c %x",
-                                                       scope, &c, name, &c, level, &c, &Address);
-                                               
-                                               for(j=0; j<numsym; j++)
-                                               {
-                                                       if(EQ(symbol[j].name, name))
-                                                       {
-                                                               if( (symbol[j].Address==-1) ) symbol[j].Address=Address;
-                                                               break;
-                                                       }
-                                               }
-                                               
-                                               /*It could be also a static function*/
-                                               for(j=0; j<numproc; j++)
-                                               {
-                                                       if(EQ(procedure[j].name, name))
-                                                       {
-                                                               if( (procedure[j].BeginAdd==-1) ) procedure[j].BeginAdd=Address;
-                                                               break;
-                                                       }
-                                               }
-
-                                       break;
-                                       
-                                       case 'L': /*Example L:Lmain$j$1$1:29*/
-
-                                               /*
-                                               L:LDS1306_Write$Value$1$1:34
-                                               L:LDS1306_Burst_Read$count$1$1:35
-                                               L:LDS1306_Burst_Read$address$1$1:36
-                                               L:LDS1306_Burst_Write$count$1$1:37
-                                               L:LDS1306_Burst_Write$address$1$1:38
-                                               */
-                                               sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
-                                                       scope, &c, name, &c, level, &c, &Address);
-                                               
-                                               for(k=0; k<numproc; k++)
-                                               {
-                                                       if(EQ(procedure[k].name, scope)) break;
-                                               }
-                                               
-                                               if(k<numproc) for(j=0; j<numsym; j++)
-                                               {
-                                                       if( EQ(symbol[j].name, name) && (symbol[j].Procedure==k) )
-                                                       {
-                                                               if(symbol[j].Address==-1) symbol[j].Address=Address;
-                                                               break;
-                                                       }
-                                               }
-                                       break;
-                                       
-                                       /*Line Numbers*/
-                                       case 'C': /*Example L:C$adq.c$38$1$1:3E*/  /*L:C$hwinit.c$29$1$1:7AD*/
-                                               sscanf(&buff[4], "%[^.] %[^$] %c %d %[^:] %c %x",
-                                                       name, level, &c, &CLine, level, &c, &Address);
-
-                                               for(j=0; j<numin; j++)
-                                                       if(EQ(infn[j].ModuleName, name)) break;
-                                               if(j<numin)
-                                               {
-                                                       /*Check if this line is already defined*/
-                                                       for(k=0; k<numlinenum; k++)
-                                                       {
-                                                               if( (linenum[k].Number==CLine) &&
-                                                                       (linenum[k].FileNameNumber==j) )break;
-                                                       }
-                                                       if(k==numlinenum) /*New line number*/
-                                                       {
-                                                               linenum=realloc(linenum, sizeof(_linenum)*(numlinenum+1));
-                                                               linenum[numlinenum].Number=CLine;
-                                                               linenum[numlinenum].FileNameNumber=j;
-                                                               linenum[numlinenum].Procedure=-1;/*To be asigned later*/
-                                                               linenum[numlinenum].Address=Address;
-                                                               numlinenum++;
-                                                       }
-                                               }
-                                       break;
-                                       
-                                       case 'A': /*Example L:A$adq$424:40*/
-                                               /*No use for this one*/
-                                       break;
-                                       
-                                       /*The end of a procedure*/
-                                       case 'X': /*Example L:XG$AsciiToHex$0$0:88*/
-                                               sscanf(&buff[3], "%[^$] %c %[^$] %c %[^:] %c %x",
-                                                       scope, &c, name, &c, level, &c, &Address);
-
-                                               for(k=0; k<numproc; k++)
-                                               {
-                                                       if(EQ(procedure[k].name, name))
-                                                       {
-                                                               if(procedure[k].EndAdd==-1) procedure[k].EndAdd=Address;
-                                                               break;
-                                                       }
-                                               }
-                                       break;
-                               }
-                       break;
-
-                       default:
-                       break;
-               }
-       }
-
-       /*Make sure each procedure has an end*/
-       for(k=0; k<(numproc-1); k++)
-       {
-               if (procedure[k].EndAdd==-1) procedure[k].EndAdd=procedure[k+1].BeginAdd-1;
-       }
-       /*Asign each line number to a procedure*/
-       for(j=0; j<numlinenum; j++)
-       {
-               for(k=0; k<numproc; k++)
-               {
-                       if ( (linenum[j].Address>=procedure[k].BeginAdd) &&
-                                (linenum[j].Address<=procedure[k].EndAdd) &&
-                                (linenum[j].FileNameNumber==procedure[k].FileNameNumber) )
-                       {
-                               linenum[j].Procedure=k;
-                       }
-               }
-       }
-
-       fclose(CDBin);
-}
-
-int hex2dec (unsigned char hex_digit)
-{
-   if (isdigit (hex_digit))
-      return hex_digit-'0';
-   else
-      return toupper (hex_digit)-'A'+10;
-}
-
-unsigned char GetByte(char * buffer)
-{
-       return hex2dec(buffer[0])*0x10+hex2dec(buffer[1]);
-}
-
-unsigned short GetWord(char * buffer)
-{
-       return  hex2dec(buffer[0])*0x1000+
-                       hex2dec(buffer[1])*0x100+
-                       hex2dec(buffer[2])*0x10+
-                       hex2dec(buffer[3]);
-}
-
-int ReadHexFile(int * Begin)
-{
-       char buffer[1024];
-       FILE * filein;
-       int j;
-       unsigned char linesize, recordtype, rchksum, value;
-       unsigned short address;
-       int MaxAddress=0;
-       int chksum;
-
-       /*If the hexfile is already open, close it*/
-       if(ofp!=NULL)
-       {
-               fclose(ofp);
-               ofp=NULL;
-       }
-       
-       strcpy(ihxFileName, infn[0].PathName);
-       strcat(ihxFileName, ".ihx");
-
-       if ( (filein=fopen(ihxFileName, "r")) == NULL )
-       {
-          printf("Error: Can't open file `%s`.\r\n", ihxFileName);
-          return 0;
-       }
-   
-       ihxBuff=calloc(MEMSIZE, sizeof(unsigned char));
-       if(ihxBuff==NULL)
-       {
-               printf("Insufficient memory\n");
-               fclose(filein);
-               return -1;
-       }
-
-       for(j=0; j<MEMSIZE; j++) ihxBuff[j]=0xff;
-
-    while(1)
-    {
-               if(fgets(buffer, sizeof(buffer), filein)==NULL)
-               {
-                       printf("Error reading file '%s'\n", ihxFileName);
-                       break;
-               }
-       if(buffer[0]==':')
-       {
-                       linesize = GetByte(&buffer[1]);
-                       address = GetWord(&buffer[3]);
-                       recordtype = GetByte(&buffer[7]);
-                       rchksum = GetByte(&buffer[9]+(linesize*2));
-                       chksum=linesize+(address/0x100)+(address%0x100)+recordtype+rchksum;
-
-                       if (recordtype==1) break; /*End of record*/
-
-                       for(j=0; j<linesize; j++)
-                       {
-                               value=GetByte(&buffer[9]+(j*2));
-                               chksum+=value;
-                               ihxBuff[address+j]=value;
-                       }
-                       if(MaxAddress<(address+linesize-1)) MaxAddress=(address+linesize-1);
-                       if(address<*Begin) *Begin=address;
-
-                       if((chksum%0x100)!=0)
-                       {
-                               printf("ERROR: Bad checksum in file %s\n", ihxFileName);
-                               fclose(filein);
-                               return -1;
-                       }
-               }
-    }
-    fclose(filein);
-       
-    return MaxAddress;
-}
-
-void CreateAOMF51(void)
-{
-       if((dflag) && (!rflag))
-       {
-               CollectInfoFromCDB();
-               #ifdef DODUMP
-               DumpForDebug();
-               #endif
-               HexSize=ReadHexFile(&HexBegin)+1;
-               OutputAOEMF51();
-               FreeAll();
-       }
-}
diff --git a/as/mcs51/lkarea.c b/as/mcs51/lkarea.c
deleted file mode 100644 (file)
index 96a9130..0000000
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* lkarea.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- *  3-Nov-97 JLH:
- *           - change lkparea to use a_type == 0 as "virgin area" flag
- * 02-Apr-98 JLH: add code to link 8051 data spaces
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*)Module   lkarea.c
- *
- *  The module lkarea.c contains the functions which
- *  create and link together all area definitions read
- *  from the .rel file(s).
- *
- *  lkarea.c contains the following functions:
- *      VOID    lnkarea()
- *      VOID    lnksect()
- *      VOID    lkparea()
- *      VOID    newarea()
- *
- *  lkarea.c contains no global variables.
- */
-
-/*)Function VOID    newarea()
- *
- *  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 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
- *  into the area flag variable.  For each occurence of
- *  an A directive an areax structure is created and
- *  linked to the areax structures associated with this
- *  area.  The size of this area section is placed into
- *  the areax structure.  The flag value for all subsequent
- *  area definitions for the same area are compared and
- *  flagged as an error if they are not identical.
- *  The areax structure created for every occurence of
- *  an A directive is loaded with a pointer to the base
- *  area structure and a pointer to the associated
- *  head structure.  And finally, a pointer to this
- *  areax structure is loaded into the list of areax
- *  structures in the head structure.  Refer to lkdata.c
- *  for details of the structures and their linkage.
- *
- *  local variables:
- *      areax **halp        pointer to an array of pointers
- *      int     i           counter, loop variable, value
- *      char    id[]        id string
- *      int     narea       number of areas in this head structure
- *      areax * taxp        pointer to an areax structure
- *                          to areax structures
- *
- *  global variables:
- *      area    *ap         Pointer to the current
- *                          area structure
- *      areax   *axp        Pointer to the current
- *                          areax structure
- *      head    *hp         Pointer to the current
- *                          head structure
- *      int     lkerr       error flag
- *
- *  functions called:
- *      Addr_T  eval()      lkeval.c
- *      VOID    exit()      c_library
- *      int     fprintf()   c_library
- *      VOID    getid()     lklex.c
- *      VOID    lkparea()   lkarea.c
- *      VOID    skip()      lklex.c
- *
- *  side effects:
- *      The area and areax structures are created and
- *      linked with the appropriate head structures.
- *      Failure to allocate area or areax structure
- *      space will terminate the linker.  Other internal
- *      errors most likely caused by corrupted .rel
- *      files will also terminate the linker.
- */
-
-/*
- * Create an area entry.
- *
- * A xxxxxx size nnnn flags mm
- *   |           |          |
- *   |           |          `--  ap->a_flag
- *   |           `------------- axp->a_size
- *   `-------------------------  ap->a_id
- *
- */
-VOID
-newarea()
-{
-    register int i, narea;
-    struct areax *taxp;
-    struct areax **halp;
-    char id[NCPS];
-
-    /*
-     * Create Area entry
-     */
-    getid(id, -1);
-    lkparea(id);
-    /*
-     * Evaluate area size
-     */
-    skip(-1);
-    axp->a_size = eval();
-    /*
-     * Evaluate flags
-     */
-    skip(-1);
-    i = 0;
-    taxp = ap->a_axp;
-    while (taxp->a_axp) {
-        ++i;
-        taxp = taxp->a_axp;
-    }
-    if (i == 0) {
-        ap->a_flag = eval();
-    } else {
-        i = eval();
-/*      if (i && (ap->a_flag != i)) { */
-/*          fprintf(stderr, "Conflicting flags in area %8s\n", id); */
-/*          lkerr++; */
-/*      } */
-    }
-    /*
-     * Evaluate area address
-     */
-    skip(-1);
-    axp->a_addr = eval();
-    /*
-     * Place pointer in header area list
-     */
-    if (headp == NULL) {
-        fprintf(stderr, "No header defined\n");
-        lkexit(1);
-    }
-    narea = hp->h_narea;
-    halp = hp->a_list;
-    for (i=0; i < narea ;++i) {
-        if (halp[i] == NULL) {
-            halp[i] = taxp;
-            return;
-        }
-    }
-    fprintf(stderr, "Header area list overflow\n");
-    lkexit(1);
-}
-
-/*)Function VOID    lkparea(id)
- *
- *      char *  id      pointer to the area name string
- *
- *  The function lkparea() searches the linked area structures
- *  for a name match.  If the name is not found then an area
- *  structure is created.  An areax structure is created and
- *  appended to the areax structures linked to the area structure.
- *  The associated base area and head structure pointers are
- *  loaded into the areax structure.
- *
- *  local variables:
- *      area *  tap         pointer to an area structure
- *      areax * taxp        pointer to an areax structure
- *
- *  global variables:
- *      area    *ap         Pointer to the current
- *                          area structure
- *      area    *areap      The pointer to the first
- *                          area structure of a linked list
- *      areax   *axp        Pointer to the current
- *                          areax structure
- *
- *  functions called:
- *      VOID *  new()       lksym()
- *      char *  strcpy()    c_library
- *      int     symeq()     lksym.c
- *
- *  side effects:
- *      Area and/or areax structures are created.
- *      Failure to allocate space for created structures
- *      will terminate the linker.
- */
-
-VOID
-lkparea(char *id)
-{
-    register struct area *tap;
-    register struct areax *taxp;
-
-    ap = areap;
-    axp = (struct areax *) new (sizeof(struct areax));
-    axp->a_addr = -1; /* default: no address yet */
-    while (ap) {
-        if (symeq(id, ap->a_id)) {
-            taxp = ap->a_axp;
-            while (taxp->a_axp)
-                taxp = taxp->a_axp;
-            taxp->a_axp = axp;
-            axp->a_bap = ap;
-            axp->a_bhp = hp;
-            return;
-        }
-        ap = ap->a_ap;
-    }
-    ap = (struct area *) new (sizeof(struct area));
-    if (areap == NULL) {
-        areap = ap;
-    } else {
-        tap = areap;
-        while (tap->a_ap)
-            tap = tap->a_ap;
-        tap->a_ap = ap;
-    }
-    ap->a_axp = axp;
-    axp->a_bap = ap;
-    axp->a_bhp = hp;
-    strncpy(ap->a_id, id, NCPS);
-    ap->a_addr = 0;
-}
-
-/*)Function VOID    lnkarea()
- *
- *  The function lnkarea() resolves all area addresses.
- *  The function evaluates each area structure (and all
- *  the associated areax structures) in sequence.  The
- *  linking process supports four (4) possible area types:
- *
- *  ABS/OVR -   All sections (each individual areax
- *          section) starts at the identical base
- *          area address overlaying all other
- *          areax sections for this area.  The
- *          size of the area is largest of the area
- *          sections.
- *
- *  ABS/CON -   All sections (each individual areax
- *          section) are concatenated with the
- *          first section starting at the base
- *          area address.  The size of the area
- *          is the sum of the section sizes.
- *
- *  NOTE:   Multiple absolute (ABS) areas are
- *          never concatenated with each other,
- *          thus absolute area A and absolute area
- *          B will overlay each other if they begin
- *          at the same location (the default is
- *          always address 0 for absolute areas).
- *
- *  REL/OVR -   All sections (each individual areax
- *          section) starts at the identical base
- *          area address overlaying all other
- *          areax sections for this area.  The
- *          size of the area is largest of the area
- *          sections.
- *
- *  REL/CON -   All sections (each individual areax
- *          section) are concatenated with the
- *          first section starting at the base
- *          area address.  The size of the area
- *          is the sum of the section sizes.
- *
- *  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
- *          starting address of area A.  Within a
- *          specific area each areax section may be
- *          overlayed or concatenated with other
- *          areax sections.
- *
- *
- *  If a base address for an area is specified then the
- *  area will start at that address.  Any relocatable
- *  areas defined subsequently will be concatenated to the
- *  previous relocatable area if it does not have a base
- *  address specified.
- *
- *  The names s_<areaname> and l_<areaname> are created to
- *  define the starting address and length of each area.
- *
- *  local variables:
- *      Addr_T  rloc        ;current relocation address
- *      char    temp[]      ;temporary string
- *      struct symbol   *sp ;symbol structure
- *
- *  global variables:
- *      area    *ap         Pointer to the current
- *                          area structure
- *      area    *areap      The pointer to the first
- *                          area structure of a linked list
- *
- *  functions called:
- *      int     fprintf()   c_library
- *      VOID    lnksect()   lkarea.c
- *      symbol *lkpsym()    lksym.c
- *      char *  strncpy()   c_library
- *      int     symeq()     lksym.c
- *
- *  side effects:
- *      All area and areax addresses and sizes are
- *      determined and saved in their respective
- *      structures.
- */
-
-/*
- * Resolve all area addresses.
- */
-VOID
-lnkarea()
-{
-    Addr_T rloc[4];
-    int  locIndex;
-    char temp[NCPS];
-    struct sym *sp;
-    /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
-    struct area *ta[5];
-    int j;
-
-    rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0;
-    ap = areap;
-    while (ap) {
-        if (ap->a_flag&A_ABS) {
-            /*
-             * Absolute sections
-             */
-            lnksect(ap);
-        } else {
-            /* Determine memory space */
-            locIndex = 0;
-            if (ap->a_flag & A_CODE) {
-                locIndex = 1;
-            }
-            if (ap->a_flag & A_XDATA) {
-                locIndex = 2;
-            }
-            if (ap->a_flag & A_BIT) {
-                locIndex = 3;
-            }
-            /*
-             * Relocatable sections
-             */
-            if (ap->a_type == 0) {  /* JLH */
-                ap->a_addr = rloc[ locIndex ];
-                ap->a_type = 1;
-            }
-            lnksect(ap);
-            rloc[ locIndex ] = ap->a_addr + ap->a_size;
-        }
-
-        /*
-         * Create symbols called:
-         *  s_<areaname>    the start address of the area
-         *  l_<areaname>    the length of the area
-         */
-
-        if (! symeq(ap->a_id, _abs_)) {
-            strncpy(temp+2,ap->a_id,NCPS-2);
-            *(temp+1) = '_';
-
-            *temp = 's';
-            sp = lkpsym(temp, 1);
-            sp->s_addr = ap->a_addr ;
-            /* sp->s_axp = ap->a_axp;  JLH: was NULL; */
-            sp->s_type |= S_DEF;
-
-            *temp = 'l';
-            sp = lkpsym(temp, 1);
-            sp->s_addr = ap->a_size;
-            sp->s_axp = NULL;
-            sp->s_type |= S_DEF;
-
-        }
-
-        /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
-        to compute the byte size of BSEG_BYTES: */
-        if (!strcmp(ap->a_id, "BSEG")) {
-            ap->a_ap->a_axp->a_size += ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
-        }
-        else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
-        else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
-        else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
-        else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
-        else if (!strcmp(ap->a_id, "BSEG_BYTES"))
-        {
-            ta[4]=ap;
-            for(j=4; j>1; j--)
-            {
-                /*If upper register banks are not used roll back the relocation counter*/
-                if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
-                {
-                    rloc[0]-=8;
-                }
-                else break;
-            }
-        }
-        ap = ap->a_ap;
-    }
-}
-
-/*)Function VOID    lnksect()
- *
- *      area *  tap         pointer to an area structure
- *
- *  The function lnksect() is the function called by
- *  lnkarea() to resolve the areax addresses.  Refer
- *  to the function lnkarea() for more detail. Pageing
- *  boundary and length errors will be reported by this
- *  function.
- *
- *  local variables:
- *      Addr_T  size        size of area
- *      Addr_T  addr        address of area
- *      areax * taxp        pointer to an areax structure
- *
- *  global variables:
- *      int     lkerr       error flag
- *
- *  functions called:
- *      none
- *
- *  side effects:
- *      All area and areax addresses and sizes area determined
- *      and linked into the structures.
- */
-
-VOID
-lnksect(register struct area *tap)
-{
-    register Addr_T size, addr;
-    register struct areax *taxp;
-
-    size = 0;
-    addr = tap->a_addr;
-#if 0
-    if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
-        fprintf(stderr,
-        "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
-        lkerr++;
-    }
-#endif
-    taxp = tap->a_axp;
-    if (tap->a_flag&A_OVR) {
-        /*
-         * Overlayed sections
-         */
-        while (taxp) {
-            taxp->a_addr = addr;
-            if (taxp->a_size > size)
-                size = taxp->a_size;
-            taxp = taxp->a_axp;
-        }
-    } else {
-        /*
-         * Concatenated sections
-         */
-        while (taxp) {
-            taxp->a_addr = addr;
-            addr += taxp->a_size;
-            size += taxp->a_size;
-            taxp = taxp->a_axp;
-        }
-    }
-    tap->a_size = size;
-    if ((tap->a_flag&A_PAG) && (size > 256)) {
-        fprintf(stderr,
-        "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
-        lkerr++;
-    }
-    if ((tap->a_flag&A_PAG) && (tap->a_size) &&
-        ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
-    {
-        fprintf(stderr,
-        "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
-        lkerr++;
-    }
-}
-
-Addr_T lnksect2 (struct area *tap, int locIndex);
-char idatamap[256];
-unsigned long codemap[524288];
-unsigned long xdatamap[131072];
-
-/*Modified version of the functions for packing variables in internal data memory*/
-VOID lnkarea2 (void)
-{
-    Addr_T rloc[4]={0, 0, 0, 0};
-    Addr_T gs_size = 0;
-    int  locIndex;
-    char temp[NCPS];
-    struct sym *sp;
-    int j;
-    struct area *dseg_ap = NULL;
-    struct area *abs_ap = NULL;
-    struct area *gs0_ap = NULL;
-    struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
-
-    for(j=0; j<256; j++) idatamap[j]=' ';
-    memset(codemap, 0, sizeof(codemap));
-    memset(xdatamap, 0, sizeof(xdatamap));
-
-    /* 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;
-
-    ap = areap;
-    while (ap)
-    {
-        /* Determine memory space */
-             if (ap->a_flag & A_CODE)  locIndex = 1;
-        else if (ap->a_flag & A_XDATA) locIndex = 2;
-        else if (ap->a_flag & A_BIT)   locIndex = 3;
-        else locIndex = 0;
-
-        if (ap->a_flag & A_ABS) /* Absolute sections */
-        {
-            lnksect2(ap, locIndex);
-        }
-        else /* Relocatable sections */
-        {
-            if (ap->a_type == 0)
-            {
-                ap->a_addr = rloc[locIndex];
-                ap->a_type = 1;
-            }
-
-            rloc[locIndex] = lnksect2(ap, locIndex);
-        }
-
-        /*
-         * Create symbols called:
-         *  s_<areaname>    the start address of the area
-         *  l_<areaname>    the length of the area
-         */
-
-        if (! symeq(ap->a_id, _abs_))
-        {
-            strncpy(temp+2,ap->a_id,NCPS-2);
-            *(temp+1) = '_';
-
-            *temp = 's';
-            sp = lkpsym(temp, 1);
-            sp->s_addr = ap->a_addr ;
-            sp->s_type |= S_DEF;
-            if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
-
-            *temp = 'l';
-            sp = lkpsym(temp, 1);
-            sp->s_addr = ap->a_size;
-            sp->s_axp = NULL;
-            sp->s_type |= S_DEF;
-            if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
-        }
-
-        /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
-        to compute the byte size of BSEG_BYTES: */
-        if (!strcmp(ap->a_id, "BSEG"))
-        {
-            ap->a_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
-        }
-        else if (!strcmp(ap->a_id, "DSEG"))
-        {
-            dseg_ap=ap; /*Need it later to set its correct size*/
-        }
-        ap = ap->a_ap;
-    }
-
-    /*Compute the size of DSEG*/
-    if(dseg_ap!=NULL)
-    {
-        dseg_ap->a_addr=0;
-        dseg_ap->a_size=0;
-        for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
-    }
-    if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
-    if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
-}
-
-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;
-}
-
-Addr_T lnksect2 (struct area *tap, int locIndex)
-{
-    register Addr_T size, addr;
-    register struct areax *taxp;
-    int j, k, ramlimit;
-    char fchar=' ', dchar='a';
-    char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
-                  " in internal RAM for area %s.\n";
-
-    tap->a_unaloc=0;
-
-    /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
-    if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
-    {
-        if((iram_size<=0)||(iram_size>0x100))
-            ramlimit=0x100;
-        else
-            ramlimit=iram_size;
-    }
-    else
-    {
-        if((iram_size<=0)||(iram_size>0x80))
-            ramlimit=0x80;
-        else
-            ramlimit=iram_size;
-    }
-
-    size = 0;
-    addr = tap->a_addr;
-#if 0
-    if ((tap->a_flag&A_PAG) && (addr & 0xFF))
-    {
-        fprintf(stderr,
-          "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
-        lkerr++;
-    }
-#endif
-    taxp = tap->a_axp;
-
-    /*Use a letter to identify each area in the internal RAM layout map*/
-    if (locIndex==0)
-    {
-        /**/ if(!strcmp(tap->a_id, "DSEG"))
-            fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/
-        else if(!strcmp(tap->a_id, "ISEG"))
-            fchar='I';
-        else if(!strcmp(tap->a_id, "SSEG"))
-            fchar='S';
-        else if(!strcmp(tap->a_id, "OSEG"))
-            fchar='Q';
-        else if(!strcmp(tap->a_id, "REG_BANK_0"))
-            fchar='0';
-        else if(!strcmp(tap->a_id, "REG_BANK_1"))
-            fchar='1';
-        else if(!strcmp(tap->a_id, "REG_BANK_2"))
-            fchar='2';
-        else if(!strcmp(tap->a_id, "REG_BANK_3"))
-            fchar='3';
-        else if(!strcmp(tap->a_id, "BSEG_BYTES"))
-            fchar='B';
-        else if(!strcmp(tap->a_id, "BIT_BANK"))
-            fchar='T';
-        else
-            fchar=' ';/*???*/
-    }
-    else if (locIndex == 1)
-    {
-        /**/ if(!strcmp(tap->a_id, "GSINIT"))
-            fchar='G';
-    }
-    else if (locIndex == 2)
-    {
-        /**/ if(!strcmp(tap->a_id, "XSTK"))
-            fchar='K';
-    }
-
-    if (tap->a_flag&A_OVR) /* Overlayed sections */
-    {
-        while (taxp)
-        {
-            if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/
-            {
-                addr=(fchar-'0')*8;
-                taxp->a_addr=addr;
-                size=taxp->a_size;
-                for(j=addr; (j<(int)(addr+taxp->a_size)) && (j<ramlimit); j++)
-                    idatamap[j]=fchar;
-            }
-            else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
-            {
-                /*Find the size of the space currently used for this areax overlay*/
-                for(j=0, size=0; j<ramlimit; j++)
-                    if(idatamap[j]==fchar) size++;
-
-                if( (fchar=='S') && (stacksize==0) )
-                {
-                   /*Search for the largest space available and use it for stack*/
-                    for(j=0, k=0, taxp->a_size=0; j<ramlimit; j++)
-                    {
-                        if(idatamap[j]==' ')
-                        {
-                            if((++k)>(int)taxp->a_size) taxp->a_size=k;
-                        }
-                        else
-                        {
-                            k=0;
-                        }
-                    }
-                    stacksize=taxp->a_size;
-                }
-
-                /*If more space required, release the previously allocated areax in
-                internal RAM and search for a bigger one*/
-                if((int)taxp->a_size>size)
-                {
-                    size=(int)taxp->a_size;
-
-                    for(j=0; j<ramlimit; j++)
-                        if(idatamap[j]==fchar) idatamap[j]=' ';
-
-                    /*Search for a space large enough in data memory for this overlay areax*/
-                    for(j=0, k=0; j<ramlimit; j++)
-                    {
-                        if(idatamap[j]==' ')
-                            k++;
-                        else
-                            k=0;
-                        if(k==(int)taxp->a_size) break;
-                    }
-
-                    if(k==(int)taxp->a_size)
-                    {
-                        taxp->a_addr = j-k+1;
-                        if(addr<(unsigned int)ramlimit)
-                        {
-                            for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
-                            if(j>=0) addr=j+1;
-                        }
-                    }
-
-                    /*Mark the memory used for overlay*/
-                    if(k==(int)taxp->a_size)
-                    {
-                        for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
-                            idatamap[j]=fchar;
-
-                        /*Set the new size of the data memory area*/
-                        size=ramlimit-addr;
-                    }
-                    else /*Couldn't find a chunk big enough: report the problem.*/
-                    {
-                        tap->a_unaloc=taxp->a_size;
-                        fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
-                        lkerr++;
-                    }
-                }
-
-                for(j=0; j<ramlimit; j++)
-                {
-                    if (idatamap[j]==fchar)
-                    {
-                        addr=j;
-                        tap->a_addr=addr;
-                        taxp->a_addr=addr;
-                        break;
-                    }
-                }
-            }
-            else if (fchar=='T') /*Bit addressable bytes in internal RAM*/
-            {
-                /*Find the size of the space currently used for this areax overlay*/
-                for(j=0x20, size=0; j<0x30; j++)
-                    if(idatamap[j]==fchar) size++;
-
-                /*If more space required, release the previously allocated areax in
-                internal RAM and search for a bigger one*/
-                if((int)taxp->a_size>size)
-                {
-                    size=(int)taxp->a_size;
-
-                    for(j=0x20; j<0x30; j++)
-                        if(idatamap[j]==fchar) idatamap[j]=' ';
-
-                    /*Search for a space large enough in data memory for this overlay areax*/
-                    for(j=0x20, k=0; j<0x30; j++)
-                    {
-                        if(idatamap[j]==' ')
-                            k++;
-                        else
-                            k=0;
-                        if(k==(int)taxp->a_size) break;
-                    }
-
-                    if(k==(int)taxp->a_size)
-                    {
-                        taxp->a_addr = j-k+1;
-                        if(addr<(unsigned int)0x30)
-                        {
-                            for(j=0x2F; (j>=0x20)&&(idatamap[j]==' '); j--);
-                            if(j>=0x20) addr=j+1;
-                        }
-                    }
-
-                    /*Mark the memory used for overlay*/
-                    if(k==(int)taxp->a_size)
-                    {
-                        for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++)
-                            idatamap[j]=fchar;
-
-                        /*Set the new size of the data memory area*/
-                        size=ramlimit-addr;
-                    }
-                    else /*Couldn't find a chunk big enough: report the problem.*/
-                    {
-                        tap->a_unaloc=taxp->a_size;
-                        fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
-                        lkerr++;
-                    }
-                }
-
-                for(j=0x20; j<0x30; j++)
-                {
-                    if (idatamap[j]==fchar)
-                    {
-                        addr=j;
-                        tap->a_addr=addr;
-                        taxp->a_addr=addr;
-                        break;
-                    }
-                }
-            }
-            else /*Overlay areas not in internal ram*/
-            {
-                taxp->a_addr = addr;
-                if (taxp->a_size > size) size = taxp->a_size;
-            }
-            taxp = taxp->a_axp;
-        }
-    }
-    else if (tap->a_flag & A_ABS) /* Absolute sections */
-    {
-        while (taxp)
-        {
-            if (locIndex == 0)
-            {
-                for (j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
-                    idatamap[j] = 'A';
-            }
-            if (locIndex == 1)
-            {
-                allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap);
-            }
-            if (locIndex == 2)
-            {
-                allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, xdatamap);
-            }
-            taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
-            size += taxp->a_size;
-            taxp = taxp->a_axp;
-        }
-    }
-    else /* Concatenated sections */
-    {
-        if ((locIndex == 1) && tap->a_size)
-        {
-            addr = find_empty_space(addr, tap->a_size, codemap);
-        }
-        if ((locIndex == 2) && tap->a_size)
-        {
-            addr = find_empty_space(addr, tap->a_size, xdatamap);
-        }
-        while (taxp)
-        {
-            if( (fchar=='D') || (fchar=='I') )
-            {
-                if(taxp->a_size)
-                {
-                    /*Search for a space large enough in internal RAM for this areax*/
-                    for(j=0, k=0; j<ramlimit; j++)
-                    {
-                        if(idatamap[j]==' ')
-                            k++;
-                        else
-                            k=0;
-                        if(k==(int)taxp->a_size) break;
-                    }
-
-                    if(k==(int)taxp->a_size)
-                    {
-                        taxp->a_addr = j-k+1;
-                        if(addr<(unsigned int)ramlimit)
-                        {
-                            for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
-                            if(j>=0) addr=j+1;
-                            size=ramlimit-addr;
-                        }
-
-                        for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
-                            idatamap[j]=(fchar=='D')?dchar:fchar;
-                        if((taxp->a_size>0)&&(fchar=='D'))dchar++;
-                        if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
-                    }
-                    else /*We are in trouble, there is not enough memory for an areax chunk*/
-                    {
-                        taxp->a_addr = addr;
-                        addr += taxp->a_size;
-                        size += taxp->a_size;
-                        tap->a_unaloc+=taxp->a_size;
-                        fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
-                        lkerr++;
-                    }
-               }
-               taxp = taxp->a_axp;
-            }
-            else if(fchar=='B')
-            {
-                if(taxp->a_size!=0)
-                {
-                    for(j=addr; j<((int)(addr+taxp->a_size)); j++)
-                        idatamap[j]=fchar;
-                }
-
-                taxp->a_addr = addr;
-                addr += taxp->a_size;
-                size += taxp->a_size;
-                taxp = taxp->a_axp;
-            }
-            else /*For concatenated BIT, CODE, and XRAM areax's*/
-            {
-                if((fchar=='K') && (taxp->a_size == 1))
-                {
-                    taxp->a_size = 256-(addr & 0xFF);
-                }
-                //find next unused address now
-                if ((locIndex == 1) && taxp->a_size)
-                {
-                    addr = find_empty_space(addr, taxp->a_size, codemap);
-                    allocate_space(addr, taxp->a_size, tap->a_id, codemap);
-                }
-                if ((locIndex == 2) && taxp->a_size)
-                {
-                    addr = find_empty_space(addr, taxp->a_size, xdatamap);
-                    allocate_space(addr, taxp->a_size, tap->a_id, xdatamap);
-                }
-                taxp->a_addr = addr;
-                addr += taxp->a_size;
-                size += taxp->a_size;
-                taxp = taxp->a_axp;
-            }
-        }
-    }
-    tap->a_size = size;
-
-    if ((tap->a_flag&A_PAG) && (size > 256))
-    {
-        fprintf(stderr,
-        "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
-        lkerr++;
-    }
-    if ((tap->a_flag&A_PAG) && (tap->a_size) &&
-        ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
-    {
-        fprintf(stderr,
-        "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
-        lkerr++;
-    }
-    return addr;
-}
diff --git a/as/mcs51/lkdata.c b/as/mcs51/lkdata.c
deleted file mode 100644 (file)
index 64af18b..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-/* lkdata.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * 28-Oct-97 JLH:
- *           - change s_id from [NCPS] to pointer (comment)
- * 31-Oct-97 JLH:
- *           - add jflag and jfp for NoICE output
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*)Module       lkdata.c
- *
- *      The module lkdata contains the global variables
- *      and structures used in the linker aslink.
- */
-
-/*
- *      Definitions for all Global Variables
- */
-
-char    *_abs_  = { ".  .ABS." };
-
-int     lkerr;          /*      Linker error flag
-                         */
-char    *ip;            /*      Pointer into the REL file text line in ib[]
-                         */
-char    ib[NINPUT];     /*      REL file text line
-                         */
-char    *rp;            /*      pointer into the LST file
-                         *      text line in rb[]
-                         */
-char    rb[NINPUT];     /*      LST file text line being
-                         *      address relocated
-                         */
-
-char sdccopt[NINPUT]="";
-char sdccopt_module[NINPUT]="";
-char curr_module[NINPUT]="";
-
-int     dflag;          /*      Debug information output flag
-                         */
-int     oflag;          /*      Output file type flag
-                         */
-int     mflag;          /*      Map output flag
-                         */
-int     sflag;          /*      JCF: Memory usage output flag
-                         */
-int     packflag=0;     /*      JCF: Pack internal memory flag
-                         */
-int     stacksize=0;    /*      JCF: Stack size
-                         */
-int     aflag;          /*      Overlapping area warning flag
-                         */
-int     jflag;          /*      NoICE output flag
-                         */
-int     xflag;          /*      Map file radix type flag
-                         */
-int     pflag;          /*      print linker command file flag
-                         */
-int     uflag;          /*      Listing relocation flag
-                         */
-int     rflag;          /*      Extended linear address record flag.
-                         */
-int     radix;          /*      current number conversion radix:
-                         *      2 (binary), 8 (octal), 10 (decimal),
-                         *      16 (hexadecimal)
-                         */
-int     line;           /*      current line number
-                         */
-int     page;           /*      current page number
-                         */
-int     lop;            /*      current line number on page
-                         */
-int     pass;           /*      linker pass number
-                         */
-int     rtcnt;          /*      count of elements in the
-                         *      rtval[] and rtflg[] arrays
-                         */
-Addr_T  rtval[NTXT];    /*      data associated with relocation
-                         */
-int     rtflg[NTXT];    /*      indicates if rtval[] value is
-                         *      to be sent to the output file.
-                         *      (always set in this linker)
-                         */
-int     hilo;           /*      REL file byte ordering
-                         */
-int     gline;          /*      LST file relocation active
-                         *      for current line
-                         */
-int     gcntr;          /*      LST file relocation active
-                         *      counter
-                         */
-Addr_T  iram_size;      /*      internal ram size
-                         */
-long    xram_size=-1;   /*      external ram size
-                         */
-long    code_size=-1;   /*      code size
-                         */
-
-/*
- *      The structure lfile contains a pointer to a
- *      file specification string, the file type, and
- *      a link to the next lfile structure.
- *
- *      struct  lfile
- *      {
- *              struct  lfile   *f_flp;         lfile link
- *              int     f_type;                 File type
- *              char    *f_idp;                 Pointer to file spec
- *      };
- */
-struct  lfile   *filep; /*      The pointers (lfile *) filep,
-                         *      (lfile *) cfp, and (FILE *) sfp
-                         *      are used in conjunction with
-                         *      the routine as_getline() to read
-                         *      asmlnk commands from
-                         *      (1) the standard input or
-                         *      (2) or a command file
-                         *      and to read the REL files
-                         *      sequentially as defined by the
-                         *      asmlnk input commands.
-                         *
-                         *      The pointer *filep points to the
-                         *      beginning of a linked list of
-                         *      lfile structures.
-                         */
-struct  lfile   *cfp;   /*      The pointer *cfp points to the
-                         *      current lfile structure
-                         */
-struct  lfile   *startp;/*      asmlnk startup file structure
-                         */
-struct  lfile   *linkp; /*      pointer to first lfile structure
-                         *      containing an input REL file
-                         *      specification
-                         */
-struct  lfile   *lfp;   /*      pointer to current lfile structure
-                         *      being processed by parse()
-                         */
-FILE    *ofp;           /*      Output file handle
-                         *      for word formats
-                         */
-FILE    *mfp;           /*      Map output file handle
-                         */
-FILE    *jfp;           /*      NoICE output file handle
-                         */
-FILE    *rfp;           /*      File handle for output
-                         *      address relocated ASxxxx
-                         *      listing file
-                         */
-FILE    *sfp;           /*      The file handle sfp points to the
-                         *      currently open file
-                         */
-FILE    *tfp;           /*      File handle for input
-                         *      ASxxxx listing file
-                         */
-FILE    *dfp = NULL ;   /*
-                         *      File handle for debug
-                         *      information output file
-                         */
-/*
- *      The structures of head, area, areax, and sym are created
- *      as the REL files are read during the first pass of the
- *      linker.  The struct head is created upon encountering a
- *      H directive in the REL file.  The structure contains a
- *      link to a link file structure (struct lfile) which describes
- *      the file containing the H directive, the number of data/code
- *      areas contained in this header segment, the number of
- *      symbols referenced/defined in this header segment, a pointer
- *      to an array of pointers to areax structures (struct areax)
- *      created as each A directive is read, and a pointer to an
- *      array of pointers to symbol structures (struct sym) for
- *      all referenced/defined symbols.  As H directives are read
- *      from the REL files a linked list of head structures is
- *      created by placing a link to the new head structure
- *      in the previous head structure.
- *
- *      struct  head
- *      {
- *              struct  head   *h_hp;           Header link
- *              struct  lfile  *h_lfile;        Associated file
- *              int     h_narea;                # of areas
- *              struct  areax **a_list;         Area list
- *              int     h_nglob;                # of global symbols
- *              struct  sym   **s_list;         Global symbol list
- *              char    m_id[NCPS];             Module name
- *      };
- */
-struct  head    *headp; /*      The pointer to the first
-                         *      head structure of a linked list
-                         */
-struct  head    *hp;    /*      Pointer to the current
-                         *      head structure
-                         */
-
-/*
- *      A structure area is created for each 'unique' data/code
- *      area definition found as the REL files are read.  The
- *      struct area contains the name of the area, a flag byte
- *      which contains the area attributes (REL/CON/OVR/ABS),
- *      an area subtype (not used in this assembler), and the
- *      area base address and total size which will be filled
- *      in at the end of the first pass through the REL files.
- *      As A directives are read from the REL files a linked
- *      list of unique area structures is created by placing a
- *      link to the new area structure in the previous area structure.
- *
- *      struct  area
- *      {
- *              struct  area    *a_ap;          Area link
- *              struct  areax   *a_axp;         Area extension link
- *              Addr_T  a_addr;                 Beginning address of area
- *              Addr_T  a_size;                 Total size of the area
- *              char    a_type;                 Area subtype
- *              char    a_flag;                 Flag byte
- *              char    a_id[NCPS];             Name
- *      };
- */
-struct  area    *areap; /*      The pointer to the first
-                         *      area structure of a linked list
-                         */
-struct  area    *ap;    /*      Pointer to the current
-                         *      area structure
-                         */
-
-/*
- *      An areax structure is created for every A directive found
- *      while reading the REL files.  The struct areax contains a
- *      link to the 'unique' area structure referenced by the A
- *      directive and to the head structure this area segment is
- *      a part of.  The size of this area segment as read from the
- *      A directive is placed in the areax structure.  The beginning
- *      address of this segment will be filled in at the end of the
- *      first pass through the REL files.  As A directives are read
- *      from the REL files a linked list of areax structures is
- *      created for each unique area.  The final areax linked
- *      list has at its head the 'unique' area structure linked
- *      to the linked areax structures (one areax structure for
- *      each A directive for this area).
- *
- *      struct  areax
- *      {
- *              struct  areax   *a_axp;         Area extension link
- *              struct  area    *a_bap;         Base area link
- *              struct  head    *a_bhp;         Base header link
- *              Addr_T  a_addr;                 Beginning address of section
- *              Addr_T  a_size;                 Size of the area in section
- *      };
- */
-struct  areax   *axp;   /*      Pointer to the current
-                         *      areax structure
-                         */
-
-/*
- *      A sym structure is created for every unique symbol
- *      referenced/defined while reading the REL files.  The
- *      struct sym contains the symbol's name, a flag value
- *      (not used in this linker), a symbol type denoting
- *      referenced/defined, and an address which is loaded
- *      with the relative address within the area in which
- *      the symbol was defined.  The sym structure also
- *      contains a link to the area where the symbol was defined.
- *      The sym structures are linked into linked lists using
- *      the symbol link element.
- *
- *      struct  sym
- *      {
- *              struct  sym     *s_sp;          Symbol link
- *              struct  areax   *s_axp;         Symbol area link
- *              char    s_type;                 Symbol subtype
- *              char    s_flag;                 Flag byte
- *              Addr_T  s_addr;                 Address
- *              char    *s_id;                  Name (JLH)
- *      };
- */
-struct  sym *symhash[NHASH]; /* array of pointers to NHASH
-                              * linked symbol lists
-                              */
-/*
- *      The struct base contains a pointer to a
- *      base definition string and a link to the next
- *      base structure.
- *
- *      struct  base
- *      {
- *              struct  base  *b_base;          Base link
- *              char          *b_strp;          String pointer
- *      };
- */
-struct  base    *basep; /*      The pointer to the first
-                         *      base structure
-                         */
-struct  base    *bsp;   /*      Pointer to the current
-                         *      base structure
-                         */
-
-/*
- *      The struct globl contains a pointer to a
- *      global definition string and a link to the next
- *      global structure.
- *
- *      struct  globl
- *      {
- *              struct  globl *g_globl;         Global link
- *              char          *g_strp;          String pointer
- *      };
- */
-struct  globl   *globlp;/*      The pointer to the first
-                         *      globl structure
-                         */
-struct  globl   *gsp;   /*      Pointer to the current
-                         *      globl structure
-                         */
-
-/*
- *      A structure sdp is created for each 'unique' paged
- *      area definition found as the REL files are read.
- *      As P directives are read from the REL files a linked
- *      list of unique sdp structures is created by placing a
- *      link to the new sdp structure in the previous area structure.
- *
- *      struct  sdp
- *      {
- *              struct  area  *s_area;  Paged Area link
- *              struct  areax *s_areax; Paged Area Extension Link
- *              Addr_T  s_addr;         Page address offset
- *      };
- */
-struct  sdp     sdp;    /* Base Page Structure */
-
-/*
- *      The structure rerr is loaded with the information
- *      required to report an error during the linking
- *      process.  The structure contains an index value
- *      which selects the areax structure from the header
- *      areax structure list, a mode value which selects
- *      symbol or area relocation, the base address in the
- *      area section, an area/symbol list index value, and
- *      an area/symbol offset value.
- *
- *      struct  rerr
- *      {
- *              int     aindex;         Linking area
- *              int     mode;           Relocation mode
- *              Addr_T  rtbase;         Base address in section
- *              int     rindex;         Area/Symbol reloaction index
- *              Addr_T  rval;           Area/Symbol offset value
- *      };
- */
-struct  rerr    rerr;   /*      Structure containing the
-                         *      linker error information
-                         */
-
-/*
- *      The structure lbpath is created for each library
- *      path specification input by the -k option.  The
- *      lbpath structures are linked into a list using
- *      the next link element.
- *
- *      struct lbpath {
- *              struct  lbpath  *next;
- *              char            *path;
- *      };
- */
-struct  lbpath  *lbphead;       /*      pointer to the first
-                                 *      library path structure
-                                 */
-
-/*
- *      The structure lbname is created for all combinations of the
- *      library path specifications (input by the -k option) and the
- *      library file specifications (input by the -l option) that
- *      lead to an existing file.  The element path points to
- *      the path string, element libfil points to the library
- *      file string, and the element libspc is the concatenation
- *      of the valid path and libfil strings.
- *
- *      The lbpath structures are linked into a list
- *      using the next link element.
- *
- *      Each library file contains a list of object files
- *      that are contained in the particular library. e.g.:
- *
- *              \iolib\termio
- *              \inilib\termio
- *
- *      Only one specification per line is allowed.
- *
- *      struct lbname {
- *              struct  lbname  *next;
- *              char            *path;
- *              char            *libfil;
- *              char            *libspc;
- *      };
- */
-struct  lbname  *lbnhead;       /*      pointer to the first
-                                 *      library name structure
-                                 */
-
-/*
- *      The function fndsym() searches through all combinations of the
- *      library path specifications (input by the -k option) and the
- *      library file specifications (input by the -l option) that
- *      lead to an existing file for a symbol definition.
- *
- *      The structure lbfile is created for the first library
- *      object file which contains the definition for the
- *      specified undefined symbol.
- *
- *      The element libspc points to the library file path specification
- *      and element relfil points to the object file specification string.
- *      The element filspc is the complete path/file specification for
- *      the library file to be imported into the linker.  The
- *      file specicifation may be formed in one of two ways:
- *
- *      (1)     If the library file contained an absolute
- *              path/file specification then this becomes filspc.
- *              (i.e. C:\...)
- *
- *      (2)     If the library file contains a relative path/file
- *              specification then the concatenation of the path
- *              and this file specification becomes filspc.
- *              (i.e. \...)
- *
- *      The lbpath structures are linked into a list
- *      using the next link element.
- *
- *      struct lbfile {
- *              struct  lbfile  *next;
- *              char            *libspc;
- *              char            *relfil;
- *              char            *filspc;
- *      };
- */
-struct  lbfile  *lbfhead;       /*      pointer to the first
-                                 *      library file structure
-                                 */
-
-/*
- *      array of character types, one per
- *      ASCII character
- */
-unsigned char   ctype[128] = {
-/*NUL*/ ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
-/*BS*/  ILL,    SPACE,  ILL,    ILL,    SPACE,  ILL,    ILL,    ILL,
-/*DLE*/ ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
-/*CAN*/ ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
-/*SPC*/ SPACE,  ETC,    ETC,    ETC,    LETTER, BINOP,  BINOP,  ETC,
-/*(*/   ETC,    ETC,    BINOP,  BINOP,  ETC,    BINOP,  LETTER, BINOP,
-/*0*/   DGT2,   DGT2,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,
-/*8*/   DGT10,  DGT10,  ETC,    ETC,    BINOP,  ETC,    BINOP,  ETC,
-/*@*/   ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
-/*H*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*P*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*X*/   LETTER, LETTER, LETTER, BINOP,  ETC,    ETC,    BINOP,  LETTER,
-/*`*/   ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
-/*h*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*p*/   LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*x*/   LETTER, LETTER, LETTER, ETC,    BINOP,  ETC,    ETC,    ETC
-};
-
-/*
- *      an array of characters which
- *      perform the case translation function
- */
-#if     CASE_SENSITIVE
-#else
-char    ccase[128] = {
-/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
-/*BS*/  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
-/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
-/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
-/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
-/*(*/   '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
-/*0*/   '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
-/*8*/   '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
-/*@*/   '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-/*H*/   '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-/*P*/   '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-/*X*/   '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
-/*`*/   '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-/*h*/   '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-/*p*/   '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-/*x*/   '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177'
-};
-#endif
diff --git a/as/mcs51/lkeval.c b/as/mcs51/lkeval.c
deleted file mode 100644 (file)
index 90df003..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/* lkeval.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*)Module      lkeval.c
- *
- *     The module lkeval.c contains the routines to evaluate
- *     arithmetic/numerical expressions.  The functions in
- *     lkeval.c perform a recursive evaluation of the arithmetic
- *     expression read from the input text line.
- *     The expression may include binary/unary operators, brackets,
- *     symbols, labels, and constants in hexadecimal, decimal, octal
- *     and binary.  Arithmetic operations are prioritized and
- *     evaluated by normal arithmetic conventions.
- *
- *     lkeval.c contains the following functions:
- *             int     digit()
- *             Addr_T  eval()
- *             Addr_T  expr()
- *             int     oprio()
- *             Addr_T  term()
- *
- *     lkeval.c contains no local/static variables
- */
-
-/*)Function    Addr_T  eval()
- *
- *     The function eval() evaluates a character string to a
- *     numerical value.
- *
- *     local variables:
- *             int     c               character from input string
- *             int     v               value of character in current radix
- *             Addr_T  n               evaluation value
- *
- *     global variables:
- *             int     radix           current number conversion radix
- *
- *     functions called:
- *             int     digit()         lkeval.c
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             Input test is scanned and evaluated to a
- *             numerical value.
- */
-
-Addr_T
-eval()
-{
-       register int c, v;
-       register Addr_T n;
-
-       c = getnb();
-       n = 0;
-       while ((v = digit(c, radix)) >= 0) {
-               n = n*radix + v;
-               c = get();
-       }
-       unget(c);
-       return(n);
-}
-
-/*)Function    Addr_T  expr(n)
- *
- *             int     n               a firewall priority; all top
- *                                     level calls (from the user)
- *                                     should be made with n set to 0.
- *
- *     The function expr() evaluates an expression and
- *     returns the value.
- *
- *     local variables:
- *             int     c               current input text character
- *             int     p               current operator priority
- *             Addr_T  v               value returned by term()
- *             Addr_T  ve              value returned by a
- *                                     recursive call to expr()
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             int     lkerr           error flag
- *             FILE *  stderr          c_library
- *
- *     functions called:
- *             VOID    expr()          lkeval.c
- *             int     fprintf()       c_library
- *             int     getnb()         lklex.c
- *             int     oprio()         lkeval.c
- *             VOID    term()          lkeval.c
- *             VOID    unget()         lklex.c
- *
- *
- *     side effects:
- *             An expression is evaluated by scanning the input
- *             text string.
- */
-
-Addr_T
-expr (n)
-{
-       register int c, p;
-       register Addr_T v, ve;
-
-       v = term();
-       while (ctype[c = getnb()] & BINOP) {
-               if ((p = oprio(c)) <= n)
-                       break;
-               if ((c == '>' || c == '<') && c != get()) {
-                       fprintf(stderr, "Invalid expression");
-                       lkerr++;
-                       return(v);
-               }
-               ve = expr(p);
-               if (c == '+') {
-                       v += ve;
-               } else
-               if (c == '-') {
-                       v -= ve;
-               } else {
-                       switch (c) {
-
-                       case '*':
-                               v *= ve;
-                               break;
-
-                       case '/':
-                               v /= ve;
-                               break;
-
-                       case '&':
-                               v &= ve;
-                               break;
-
-                       case '|':
-                               v |= ve;
-                               break;
-
-                       case '%':
-                               v %= ve;
-                               break;
-
-                       case '^':
-                               v ^= ve;
-                               break;
-
-                       case '<':
-                               v <<= ve;
-                               break;
-
-                       case '>':
-                               v >>= ve;
-                               break;
-                       }
-               }
-       }
-       unget(c);
-       return(v);
-}
-
-/*)Function    Addr_T  term()
- *
- *     The function term() evaluates a single constant
- *     or symbol value prefaced by any unary operator
- *     ( +, -, ~, ', ", >, or < ).
- *
- *     local variables:
- *             int     c               current character
- *             char    id[]            symbol name
- *             int     n               value of digit in current radix
- *             int     r               current evaluation radix
- *             sym *   sp              pointer to a sym structure
- *             Addr_T  v               evaluation value
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             int     lkerr           error flag
- *
- *     functions called:
- *             int     digit()         lkeval.c
- *             VOID    expr()          lkeval.c
- *             int     fprintf()       c_library
- *             int     get()           lklex.c
- *             VOID    getid()         lklex.c
- *             int     getmap()        lklex.c
- *             int     getnb()         lklex.c
- *             sym *   lkpsym()        lksym.c
- *             Addr_T  symval()        lksym.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             An arithmetic term is evaluated by scanning input text.
- */
-
-Addr_T
-term()
-{
-       register int c, r, n;
-       register Addr_T v;
-       struct sym *sp;
-       char id[NCPS];
-
-       c = getnb();
-       if (c == '#') { c = getnb(); }
-       if (c == '(') {
-               v = expr(0);
-               if (getnb() != ')') {
-                       fprintf(stderr, "Missing delimiter");
-                       lkerr++;
-               }
-               return(v);
-       }
-       if (c == '-') {
-               return(0-expr(100));
-       }
-       if (c == '~') {
-               return(~expr(100));
-       }
-       if (c == '\'') {
-               return(getmap(-1)&0377);
-       }
-       if (c == '\"') {
-               if (hilo) {
-                       v  = (getmap(-1)&0377)<<8;
-                       v |=  getmap(-1)&0377;
-               } else {
-                       v  =  getmap(-1)&0377;
-                       v |= (getmap(-1)&0377)<<8;
-               }
-               return(v);
-       }
-       if (c == '>' || c == '<') {
-               v = expr(100);
-               if (c == '>')
-                       v >>= 8;
-               return(v&0377);
-       }
-       if (ctype[c] & DIGIT) {
-               r = 10;
-               if (c == '0') {
-                       c = get();
-                       switch (c) {
-                       case 'b':
-                       case 'B':
-                               r = 2;
-                               c = get();
-                               break;
-                       case '@':
-                       case 'o':
-                       case 'O':
-                       case 'q':
-                       case 'Q':
-                               r = 8;
-                               c = get();
-                               break;
-                       case 'd':
-                       case 'D':
-                               r = 10;
-                               c = get();
-                               break;
-                       case 'h':
-                       case 'H':
-                       case 'x':
-                       case 'X':
-                               r = 16;
-                               c = get();
-                               break;
-                       default:
-                               break;
-                       }
-               }
-               v = 0;
-               while ((n = digit(c, r)) >= 0) {
-                       v = r*v + n;
-                       c = get();
-               }
-               unget(c);
-               return(v);
-       }
-       if (ctype[c] & LETTER) {
-               getid(id, c);
-               if ((sp = lkpsym(id, 0)) == NULL) {
-                       fprintf(stderr, "Undefined symbol %8s\n", id);
-                       lkerr++;
-                       return(0);
-               } else {
-                       return(symval(sp));
-               }
-       }
-       return(0);
-}
-
-/*)Function    int     digit(c, r)
- *
- *             int     c               digit character
- *             int     r               current radix
- *
- *     The function digit() returns the value of c
- *     in the current radix r.  If the c value is not
- *     a number of the current radix then a -1 is returned.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-
-int
-digit(c, r)
-register int c, r;
-{
-       if (r == 16) {
-               if (ctype[c] & RAD16) {
-                       if (c >= 'A' && c <= 'F')
-                               return (c - 'A' + 10);
-                       if (c >= 'a' && c <= 'f')
-                               return (c - 'a' + 10);
-                       return (c - '0');
-               }
-       } else
-       if (r == 10) {
-               if (ctype[c] & RAD10)
-                       return (c - '0');
-       } else
-       if (r == 8) {
-               if (ctype[c] & RAD8)
-                       return (c - '0');
-       } else
-       if (r == 2) {
-               if (ctype[c] & RAD2)
-                       return (c - '0');
-       }
-       return (-1);
-}
-
-/*)Function    int     oprio(c)
- *
- *             int     c               operator character
- *
- *     The function oprio() returns a relative priority
- *     for all valid unary and binary operators.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             none
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-int
-oprio(c)
-register int c;
-{
-       if (c == '*' || c == '/' || c == '%')
-               return (10);
-       if (c == '+' || c == '-')
-               return (7);
-       if (c == '<' || c == '>')
-               return (5);
-       if (c == '^')
-               return (4);
-       if (c == '&')
-               return (3);
-       if (c == '|')
-               return (1);
-       return (0);
-}
diff --git a/as/mcs51/lkhead.c b/as/mcs51/lkhead.c
deleted file mode 100644 (file)
index 41a5198..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* lkhead.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*Module       lkhead.c
- *
- *     The module lkhead.c contains the function newhead() which
- *     creates a head structure and the function module() which
- *     loads the module name into the current head structure.
- *
- *     lkhead.c contains the following functions:
- *             VOID    newhead()
- *             VOID    module()
- *
- *     lkhead.c contains no local variables.
- */
-
-/*)Function    VOID    newhead()
- *
- *     The function newhead() creates a head structure.  All head
- *     structures are linked to form a linked list of head structures
- *     with the current head structure at the tail of the list.
- *
- *     local variables:
- *             int     i               evaluation value
- *             head *  thp             temporary pointer
- *                                     to a header structure
- *
- *     global variables:
- *             area    *ap             Pointer to the current
- *                                     area structure
- *             lfile   *cfp            The pointer *cfp points to the
- *                                     current lfile structure
- *             head    *headp          The pointer to the first
- *                                     head structure of a linked list
- *             head    *hp             Pointer to the current
- *                                     head structure
- *
- *     functions called:
- *             Addr_T  expr()          lkeval.c
- *             VOID *  new()           lksym.c
- *             VOID    lkparea()       lkarea.c
- *
- *     side effects:
- *             A new head structure is created and linked to any
- *             existing linked head structure.  The head structure
- *             parameters of file handle, number of areas, and number
- *             of global symbols are loaded into the structure.
- *             The default area "_abs_" is created when the first
- *             head structure is created and an areax structure is
- *             created for every head structure called.
- */
-
-/*
- * Create a new header entry.
- *
- * H n areas n global symbols
- *   |       |
- *   |       `---- hp->h_nglob
- *   `------------ hp->h_narea
- *
- */
-VOID
-newhead()
-{
-       register int i;
-       struct head *thp;
-
-       hp = (struct head *) new (sizeof(struct head));
-       if (headp == NULL) {
-               headp = hp;
-       } else {
-               thp = headp;
-               while (thp->h_hp)
-                       thp = thp->h_hp;
-               thp->h_hp = hp;
-       }
-       /*
-        * Set file pointer
-        */
-       hp->h_lfile = cfp;
-       /*
-        * Evaluate and build Area pointer list
-        */
-       i = hp->h_narea = eval();
-       if (i)
-               hp->a_list = (struct areax **) new (i*sizeof(struct areax *));
-       /*
-        * Evaluate and build Global symbol pointer list
-        */
-       skip(-1);
-       i = hp->h_nglob = eval();
-       if (i)
-               hp->s_list = (struct sym **) new (i*sizeof(struct sym *));
-       /*
-        * Setup Absolute DEF linkage.
-        */
-       lkparea(_abs_);
-       ap->a_flag = A_ABS;
-}
-
-/*)Function    VOID    module()
- *
- *     The function module() copies the module name into
- *     the current head structure.
- *
- *     local variables:
- *             char    id[]            module id string
- *
- *     global variables:
- *             head    *headp          The pointer to the first
- *                                     head structure of a linked list
- *             head    *hp             Pointer to the current
- *                                     head structure
- *             int     lkerr           error flag
- *             FILE *  stderr          c_library
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    getid()         lklex.c
- *             char *  strncpy()       c_library
- *
- *     side effects:
- *             The module name is copied into the head structure.
- */
-
-/*
- * Module Name
- */
-VOID
-module()
-{
-       char id[NCPS];
-
-       if (headp) {
-               getid(id, -1);
-               strncpy(hp->m_id, id, NCPS);
-       } else {
-               fprintf(stderr, "No header defined\n");
-               lkerr++;
-       }
-}
diff --git a/as/mcs51/lkihx.c b/as/mcs51/lkihx.c
deleted file mode 100644 (file)
index 8a5aa3e..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/* lkihx.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*)Module      lkihx.c
- *
- *     The module lkihx.c contains the function to
- *     output the relocated object code in the
- *     Intel Hex format.
- *
- *     lkihx.c contains the following functions:
- *             VOID    hexRecord(addr, rtvalIndex)
- *             VOID    ihx(i)
- *             VOID    ihxEntendedLinearAddress(a)
- *
- *     local variables: hexPageOverrun, lastHexAddr
- */
-
-/*Intel Hex Format
- *      Record Mark Field    -  This  field  signifies  the  start  of a
- *                              record, and consists of an  ascii  colon
- *                              (:).  
- *
- *      Record Length Field  -  This   field   consists   of  two  ascii
- *                              characters which indicate the number  of
- *                              data   bytes   in   this   record.   The
- *                              characters are the result of  converting
- *                              the  number  of  bytes  in binary to two
- *                              ascii characters, high digit first.   An
- *                              End  of  File  record contains two ascii
- *                              zeros in this field.  
- *
- *      Load Address Field   -  This  field  consists  of the four ascii
- *                              characters which result from  converting
- *                              the  the  binary value of the address in
- *                              which to begin loading this record.  The
- *                              order is as follows:  
- *
- *                                  High digit of high byte of address. 
- *                                  Low digit of high byte of address.  
- *                                  High digit of low byte of address.  
- *                                  Low digit of low byte of address.  
- *
- *                              In an End of File record this field con-
- *                              sists of either four ascii zeros or  the
- *                              program  entry  address.   Currently the
- *                              entry address option is not supported.  
- *
- *      Record Type Field    -  This  field  identifies the record type,
- *                              which is either 0 for data records or  1
- *                              for  an End of File record.  It consists
- *                              of two ascii characters, with  the  high
- *                              digit of the record type first, followed
- *                              by the low digit of the record type.  
- *
- *      Data Field           -  This  field consists of the actual data,
- *                              converted to two ascii characters,  high
- *                              digit first.  There are no data bytes in
- *                              the End of File record.  
- *
- *      Checksum Field       -  The  checksum  field is the 8 bit binary
- *                              sum of the record length field, the load
- *                              address  field,  the  record type field,
- *                              and the data field.  This  sum  is  then
- *                              negated  (2's  complement) and converted
- *                              to  two  ascii  characters,  high  digit
- *                              first.  
- */
-
-/* Static variable which holds the count of hex page overruns
- * (crossings of the 64kB boundary). Cleared at explicit extended
- * address output.
- */
-static int hexPageOverrun = 0;
-
-/* Global which holds the last (16 bit) address of hex record.
- * Cleared at begin of new area or when the extended address is output.
- */
-unsigned int lastHexAddr = 0;
-
-
-/*)Function    hexRecord(addr, rtvalIndex)
- *
- *             unsigned addr   starting address of hex record
- *             int rtvalIndex  starting index into the rtval[] array
- *
- *     The function hexRecord() outputs the relocated data
- *     in the standard Intel Hex format (with inserting
- *     the extended address record if necessary).
- *
- *     local variables:
- *             Addr_T  chksum          byte checksum
- *             int             i                       index for loops
- *             int             overrun         temporary storage for hexPageOverrun
- *             int             bytes           counter for bytes written
- *
- *     global variables:
- *             FILE *  ofp             output file handle
- *             int     rtcnt           count of data words
- *             int     rtflg[]         output the data flag
- *             Addr_T  rtval[]         relocated data
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             ihxEntendedLinearAddress()      lkihx.c
- *             hexRecord()             lkihx.c         (recursion)
- *
- *     side effects:
- *             hexPageOverrun is eventually incremented,
- *             lastHexAddr is updated
- */
-
-VOID
-hexRecord(unsigned addr, int rtvalIndex)
-{
-       Addr_T chksum;
-       int i, overrun, bytes;
-
-       for (i = rtvalIndex, chksum = 0; i < rtcnt; i++) {
-               if (rtflg[i]) {
-                       if (addr + ++chksum > 0xffff)
-                               break;
-               }
-       }
-       if (chksum == 0)
-               return;                 // nothing to output
-
-       if ( (lastHexAddr > addr) && (rflag) ) {
-               overrun = hexPageOverrun + 1;
-               ihxEntendedLinearAddress(lastExtendedAddress + overrun);
-               hexPageOverrun = overrun;
-               hexRecord(addr, rtvalIndex);
-               return;
-       }
-
-       lastHexAddr = addr;
-       fprintf(ofp, ":%02X%04X00", chksum, addr);
-       chksum += (addr >> 8) + (addr & 0xff);
-       for (i = rtvalIndex, bytes = 0; i < rtcnt; i++) {
-               if (rtflg[i]) {
-                   fprintf(ofp, "%02X", rtval[i]);
-                   chksum += rtval[i];
-                       if (addr + ++bytes > 0xffff) {
-                               if (rflag) {
-                                       fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
-                                       overrun = hexPageOverrun + 1;
-                                       ihxEntendedLinearAddress(lastExtendedAddress + overrun);
-                                       hexPageOverrun = overrun;
-                                       hexRecord(0, i + 1);
-                                       return;
-                               } else {
-                                       fprintf(stderr, 
-                                               "warning: extended linear address encountered; "
-                                               "you probably want the -r flag.\n");
-                               }
-                       }
-               }
-       }
-       fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
-}
-
-/*)Function    ihx(i)
- *
- *             int     i               0 - process data
- *                                     1 - end of data
- *
- *     The function ihx() calls the hexRecord() function for processing data
- *     or writes the End of Data record to the file defined by ofp.
- *
- *     local variables:
- *             Addr_T  n               auxiliary variable
- *
- *     global variables:
- *             int     hilo            byte order
- *             FILE *  ofp             output file handle
- *             Addr_T  rtval[]         relocated data
- *
- *     functions called:
- *             VOID hexRecord()        lkihx.c
- *             int     fprintf()               c_library
- *
- *     side effects:
- *             The sequence of rtval[0], rtval[1] is eventually changed.
- */
-
-VOID
-ihx(i)
-{
-       Addr_T n;
-       if (i) {
-               if (hilo == 0) {
-                       n = rtval[0];
-                       rtval[0] = rtval[1];
-                       rtval[1] = n;
-               }
-               hexRecord((rtval[0]<<8) + rtval[1], 2);
-       } else {
-               fprintf(ofp, ":00000001FF\n");
-       }
-}
-
-/*)Function    newArea(i)
- * The function newArea() is called when processing of new area is started.
- * It resets the value of lastHexAddr.
- */ 
-
-VOID
-newArea()
-{
-       lastHexAddr = 0;
-}
-
-/*)Function    ihxEntendedLinearAddress(i)
- *
- *             Addr_T  i               16 bit extended linear address.
- *
- *     The function ihxEntendedLinearAddress() writes an extended
- *     linear address record (type 04) to the output file.
- *
- *     local variables:
- *             Addr_T  chksum          byte checksum
- *
- *     global variables:
- *             FILE *  ofp             output file handle
- *
- *     functions called:
- *             int     fprintf()       c_library
- *
- *     side effects:
- *             The data is output to the file defined by ofp.
- *             hexPageOverrun and lastHexAddr is cleared
- */
-VOID
-ihxEntendedLinearAddress(Addr_T a)
-{
-    Addr_T     chksum;
-  
-    /* The checksum is the complement of the bytes in the
-     * record: the 2 is record length, 4 is the extended linear
-     * address record type, plus the two address bytes.
-     */ 
-    chksum = 2 + 4 + (a & 0xff) + ((a >> 8) & 0xff);    
-    
-    fprintf(ofp, ":02000004%04X%02X\n", a & 0xffff, (0-chksum) & 0xff);
-       hexPageOverrun = 0;
-       lastHexAddr = 0;
-}
diff --git a/as/mcs51/lklex.c b/as/mcs51/lklex.c
deleted file mode 100644 (file)
index 7c48130..0000000
+++ /dev/null
@@ -1,640 +0,0 @@
-/* lklex.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*)Module      lklex.c
- *
- *     The module lklex.c contains the general lexical analysis
- *     functions used to scan the text lines from the .rel files.
- *
- *     lklex.c contains the fllowing functions:
- *             char    endline()
- *             char    get()
- *             VOID    getfid()
- *             VOID    getid()
- *             VOID    getSid()
- *             int     as_getline()
- *             int     getmap()
- *             char    getnb()
- *             int     more()
- *             VOID    skip()
- *             VOID    unget()
- *
- *     lklex.c contains no local variables.
- */
-
-/*)Function    VOID    getid(id,c)
- *
- *             char *  id              a pointer to a string of
- *                                     maximum length NCPS
- *             int     c               mode flag
- *                                     >=0     this is first character to
- *                                             copy to the string buffer
- *                                     <0      skip white space
- *
- *     The function getid() scans the current input text line
- *     from the current position copying the next LETTER | DIGIT string
- *     into the external string buffer (id).  The string ends when a non
- *     LETTER or DIGIT character is found. The maximum number of
- *     characters copied is NCPS.  If the input string is larger than
- *     NCPS characters then the string is truncated, if the input string
- *     is shorter than NCPS characters then the string is NULL filled.
- *     If the mode argument (c) is >=0 then (c) is the first character
- *     copied to the string buffer, if (c) is <0 then intervening white
- *     space (SPACES and TABS) are skipped.
- *
- *     local variables:
- *             char *  p               pointer to external string buffer
- *             int     c               current character value
- *
- *     global variables:
- *             char    ctype[]         a character array which defines the
- *                                     type of character being processed.
- *                                     This index is the character
- *                                     being processed.
- *
- *     called functions:
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             use of getnb(), get(), and unget() updates the
- *             global pointer ip the position in the current
- *             input text line.
- */
-
-VOID
-getid(id, c)
-register int c;
-char *id;
-{
-       register char *p;
-
-       if (c < 0) {
-               c = getnb();
-       }
-       p = id;
-       do {
-               if (p < &id[NCPS])
-                       *p++ = c;
-       } while (ctype[c=get()] & (LETTER|DIGIT));
-       unget(c);
-       while (p < &id[NCPS])
-               *p++ = 0;
-}
-
-/*)Function    VOID    getSid (char *id)
- *
- *             char *  id              a pointer to a string of
- *                                     maximum length NCPS
- *
- *  getSid is derived from getid. It is called from newsym()
- *  in lksym.c, when an S-record has to be scanned. getSid accepts
- *  much more characters than getid, which is necessary for SDCC.
- * 
- *     The function getSid() scans the current input text line
- *     from the current position copying the next string
- *     into the external string buffer (id).  The string ends when a space
- *  character (space, tab, \0) is found. The maximum number of
- *     characters copied is NCPS.  If the input string is larger than
- *     NCPS characters then the string is truncated, if the input string
- *     is shorter than NCPS characters then the string is NULL filled.
- *     Intervening white space (SPACES and TABS) are skipped.
- *
- *     local variables:
- *             char *  p               pointer to external string buffer
- *             int     c               current character value
- *
- *     global variables:
- *             char    ctype[]         a character array which defines the
- *                                     type of character being processed.
- *                                     This index is the character
- *                                     being processed.
- *
- *     called functions:
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             use of getnb(), get(), and unget() updates the
- *             global pointer ip the position in the current
- *             input text line.
- */
-
-VOID
-getSid (id)
-char *id;
-{
-  register int c;
-       register char *p;
-
-  c = getnb();
-       p = id;
-       do {
-               if (p < &id[NCPS])
-                       *p++ = c;
-               c = get();
-       } while (c != '\0' && c != ' ' && c != '\t');
-       unget(c);
-       while (p < &id[NCPS])
-               *p++ = 0;
-}
-
-/*)Function    VOID    getfid(fid,c)
- *
- *             char *  str             a pointer to a string of
- *                                     maximum length PATH_MAX
- *             int     c               this is first character to
- *                                     copy to the string buffer
- *
- *     The function getfid() scans the current input text line from
- *     the current position copying the next string into the external
- *     string buffer (str).  The string ends when end of line is found.
- *     Trailing spacers are removed. The maximum number of characters
- *     copied is PATH_MAX. If the input string is larger than PATH_MAX
- *     characters then the string is truncated. The string is NULL
- *     terminated.
- *
- *     local variables:
- *             char *  p               pointer to external string buffer
- *             int     c               current character value
- *
- *     global variables:
- *             char    ctype[]         a character array which defines the
- *                                     type of character being processed.
- *                                     This index is the character
- *                                     being processed.
- *
- *     called functions:
- *             char    get()           lklex.c
- *
- *     side effects:
- *             use of get() updates the global pointer ip
- *             the position in the current input text line.
- */
-
-VOID
-getfid(str, c)
-register int c;
-char *str;
-{
-       register char *p;
-
-       p = str;
-       do
-       {
-               if (p < &str[PATH_MAX-1])
-                       *p++ = c;
-               c = get();
-               if (c == ';')
-                       while (c)
-                               c = get();
-       } while (c);
-       /* trim trailing spaces */
-       --p;
-       while (p >= str && ctype[(int)*p] == SPACE)
-               --p;
-       /* terminate the string */
-       *(++p) = '\0';
-}
-
-/*)Function    char    getnb()
- *
- *     The function getnb() scans the current input text
- *     line returning the first character not a SPACE or TAB.
- *
- *     local variables:
- *             int     c               current character from input
- *
- *     global variables:
- *             none
- *
- *     called functions:
- *             char    get()           lklex.c
- *
- *     side effects:
- *             use of get() updates the global pointer ip, the position
- *             in the current input text line
- */
-
-char
-getnb()
-{
-       register int c;
-
-       while ((c=get())==' ' || c=='\t')
-               ;
-       return (c);
-}
-
-/*)Function    VOID    skip()
- *
- *     The function skip() scans the input text skipping all
- *     letters and digits.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             
- *     functions called:
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             Input letters and digits are skipped.
- */
-
-VOID
-skip(c)
-register int c;
-{
-       if (c < 0)
-               c = getnb();
-       while (ctype[c=get()] & (LETTER|DIGIT)) { ; }
-       unget(c);
-}
-
-/*)Function    char    get()
- *
- *     The function get() returns the next character in the
- *     input text line, at the end of the line a
- *     NULL character is returned.
- *
- *     local variables:
- *             int     c               current character from
- *                                     input text line
- *
- *     global variables:
- *             char *  ip              pointer into the current
- *                                     input text line
- *
- *     called functions:
- *             none
- *
- *     side effects:
- *             updates ip to the next character position in the
- *             input text line.  If ip is at the end of the
- *             line, ip is not updated.
- */
-
-char
-get()
-{
-       register int c;
-
-       if ((c = *ip) != 0)
-               ++ip;
-       return (c);
-}
-
-/*)Function    VOID    unget(c)
- *
- *             int     c               value of last character
- *                                     read from input text line
- *
- *     If (c) is not a NULL character then the global pointer ip
- *     is updated to point to the preceeding character in the
- *     input text line.
- *
- *     NOTE:   This function does not push the character (c)
- *             back into the input text line, only
- *             the pointer ip is changed.
- *
- *     local variables:
- *             int     c               last character read
- *                                     from input text line
- *
- *     global variables:
- *             char *  ip              position into the current
- *                                     input text line
- *
- *     called functions:
- *             none
- *
- *     side effects:
- *             ip decremented by 1 character position
- */
-
-VOID
-unget(c)
-{
-       if (c != 0)
-               --ip;
-}
-
-/*)Function    int     getmap(d)
- *
- *             int     d               value to compare with the
- *                                     input text line character
- *
- *     The function getmap() converts the 'C' style characters \b, \f,
- *     \n, \r, and \t to their equivalent ascii values and also
- *     converts 'C' style octal constants '\123' to their equivalent
- *     numeric values.  If the first character is equivalent to (d) then
- *     a (-1) is returned, if the end of the line is detected then
- *     a 'q' error terminates the parse for this line, or if the first
- *     character is not a \ then the character value is returned.
- *
- *     local variables:
- *             int     c               value of character
- *                                     from input text line
- *             int     n               looping counter
- *             int     v               current value of numeric conversion
- *
- *     global variables:
- *             none
- *
- *     called functions:
- *             char    get()           lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             use of get() updates the global pointer ip the position
- *             in the current input text line
- */
-
-int
-getmap(d)
-{
-       register int c, n, v;
-
-       if ((c = get()) == '\0')
-               return (-1);
-       if (c == d)
-               return (-1);
-       if (c == '\\') {
-               c = get();
-               switch (c) {
-
-               case 'b':
-                       c = '\b';
-                       break;
-
-               case 'f':
-                       c = '\f';
-                       break;
-
-               case 'n':
-                       c = '\n';
-                       break;
-
-               case 'r':
-                       c = '\r';
-                       break;
-
-               case 't':
-                       c = '\t';
-                       break;
-
-               case '0':
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-                       n = 0;
-                       v = 0;
-                       while (++n<=3 && c>='0' && c<='7') {
-                               v = (v<<3) + c - '0';
-                               c = get();
-                       }
-                       unget(c);
-                       c = v;
-                       break;
-               }
-       }
-       return (c);
-}
-
-/*)Function    int     as_getline()
- *
- *     The function as_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
- *     or a (0) if all files have been read.
- *     This function also opens each input .lst file and output
- *     .rst file as each .rel file is processed.
- *
- *     local variables:
- *             int     i               string length
- *             int     ftype           file type
- *             char *  fid             file name
- *
- *     global variables:
- *             lfile   *cfp            The pointer *cfp points to the
- *                                     current lfile structure
- *             lfile   *filep          The pointer *filep points to the
- *                                     beginning of a linked list of
- *                                     lfile structures.
- *             int     gline           get a line from the LST file
- *                                     to translate for the RST file
- *             char    ib[NINPUT]      REL file text line
- *             int     pass            linker pass number
- *             int     pflag           print linker command file flag
- *             FILE    *rfp            The file handle to the current
- *                                     output RST file
- *             FILE    *sfp            The file handle sfp points to the
- *                                     currently open file
- *             FILE *  stdin           c_library
- *             FILE *  stdout          c_library
- *             FILE    *tfp            The file handle to the current
- *                                     LST file being scanned
- *             int     uflag           update listing flag
- *
- *     called functions:
- *             FILE *  afile()         lkmain.c
- *             int     fclose()        c_library
- *             char *  fgets()         c_library
- *             int     fprintf()       c_library
- *             VOID    lkulist()       lklist.c
- *             VOID    lkexit()        lkmain.c
- *             int     strlen()        c_library
- *
- *     side effects:
- *             The input stream is scanned.  The .rel files will be
- *             opened and closed sequentially scanning each in turn.
- */
-
-int
-as_getline()
-{
-       register int ftype;
-       register char *fid;
-
-loop:  if (pflag && cfp && cfp->f_type == F_STD)
-               fprintf(stdout, "ASlink >> ");
-
-       if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) {
-               if (sfp) {
-                       fclose(sfp);
-                       sfp = NULL;
-                       lkulist(0);
-               }
-               if (cfp == NULL) {
-                       cfp = filep;
-               } else {
-                       cfp = cfp->f_flp;
-               }
-               if (cfp) {
-                       ftype = cfp->f_type;
-                       fid = cfp->f_idp;
-                       if (ftype == F_STD) {
-                               sfp = stdin;
-                       } else
-                       if (ftype == F_LNK) {
-                               sfp = afile(fid, "lnk", 0);
-                       } else
-                       if (ftype == F_REL) {
-                               sfp = afile(fid, "rel", 0);
-                               /* if a .cdb file exists then copy it over */
-                               if (dflag && sfp && dfp && pass == 0) {
-                                   FILE *xfp = afile(fid,"adb",0); //JCF: Nov 30, 2002
-                                   if (xfp) {
-                                       copyfile(dfp,xfp);
-                                       fclose(xfp);
-                                   }
-                               }
-                               if (uflag && pass != 0) {
-                                SaveLinkedFilePath(fid); //Save the linked path for aomf51
-                                if ((tfp = afile(fid, "lst", 0)) != NULL) {
-                                 if ((rfp = afile(fid, "rst", 1)) == NULL) {
-                                       fclose(tfp);
-                                       tfp = NULL;
-                                 }
-                                }
-                               }
-                               gline = 1;
-                       } else {
-                               fprintf(stderr, "Invalid file type\n");
-                               lkexit(1);
-                       }
-                       if (sfp == NULL) {
-                               lkexit(1);
-                       }
-                       goto loop;
-               } else {
-                       filep = NULL;
-                       return(0);
-               }
-       }
-       chop_crlf(ib);
-       return (1);
-}
-
-/*)Function    int     more()
- *
- *     The function more() scans the input text line
- *     skipping white space (SPACES and TABS) and returns a (0)
- *     if the end of the line or a comment delimeter (;) is found,
- *     or a (1) if their are additional characters in the line.
- *
- *     local variables:
- *             int     c               next character from
- *                                     the input text line
- *
- *     global variables:
- *             none
- *
- *     called functions:
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             use of getnb() and unget() updates the global pointer ip
- *             the position in the current input text line
- */
-
-int
-more()
-{
-       register int c;
-
-       c = getnb();
-       unget(c);
-       return( (c == '\0' || c == ';') ? 0 : 1 );
-}
-
-/*)Function    char    endline()
- *
- *     The function endline() scans the input text line
- *     skipping white space (SPACES and TABS) and returns the next
- *     character or a (0) if the end of the line is found or a
- *     comment delimiter (;) is found.
- *
- *     local variables:
- *             int     c               next character from
- *                                     the input text line
- *
- *     global variables:
- *             none
- *
- *     called functions:
- *             char    getnb()         lklex.c
- *
- *     side effects:
- *             Use of getnb() updates the global pointer ip the
- *             position in the current input text line.
- */
-
-char
-endline()
-{
-       register int c;
-
-       c = getnb();
-       return( (c == '\0' || c == ';') ? 0 : c );
-}
-
-/*)Function    VOID    chop_crlf(str)
- *
- *             char    *str            string to chop
- *
- *     The function chop_crlf() removes trailing LF or CR/LF from
- *     str, if present.
- *
- *     local variables:
- *             int     i               string length
- *
- *     global variables:
- *             none
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-
-VOID
-chop_crlf(str)
-char *str;
-{
-       register int i;
-
-       i = strlen(str);
-       if (i >= 1 && str[i-1] == '\n') str[i-1] = 0;
-       if (i >= 2 && str[i-2] == '\r') str[i-2] = 0;
-}
diff --git a/as/mcs51/lklibr.c b/as/mcs51/lklibr.c
deleted file mode 100644 (file)
index e87c9ec..0000000
+++ /dev/null
@@ -1,1301 +0,0 @@
-/* lklibr.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * With contributions for the
- * object libraries from
- * Ken Hornstein
- * kenh@cmf.nrl.navy.mil
- *
- */
-
-#define EQ(A,B) !strcmp((A),(B))
-#define MAXLINE 254 /*when using fgets*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "aslink.h"
-
-/*)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
- *
- *  lklibr.c contains the following functions:
- *      VOID    addpath()
- *      VOID    addlib()
- *      VOID    addfile()
- *      VOID    search()
- *      VOID    fndsym()
- *      VOID    library()
- *      VOID    loadfile()
- *
- */
-
-#ifdef INDEXLIB
-typedef struct slibrarysymbol mlibrarysymbol;
-typedef struct slibrarysymbol *pmlibrarysymbol;
-
-struct slibrarysymbol {
-    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*/
-    long offset; //if > 0, the embedded file offset in the library file libspc
-    pmlibrarysymbol symbols;
-    pmlibraryfile next;
-};
-
-/* First entry in the library object symbol cache */
-pmlibraryfile libr=NULL;
-
-int buildlibraryindex();
-void freelibraryindex (void);
-#endif /* INDEXLIB */
-
-/*)Function VOID    addpath()
- *
- *  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
- *
- *  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
- *
- *  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);
-}
-
-/*)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.
- *
- *  This function calls the function addfile() to actually
- *  add the library file to the search list.
- *
- *  local variables:
- *      lbpath  *lbph       pointer to 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
- *
- *  side effects:
- *      The function addfile() may add the file to
- *      the library search list.
- */
-
-VOID
-addlib()
-{
-    struct lbpath *lbph;
-    int foundcount=0;
-
-    unget(getnb());
-
-    if (lbphead == NULL)
-    {
-        foundcount=addfile(NULL, ip);
-    }
-    else
-    {
-        for (lbph=lbphead; lbph; lbph=lbph->next)
-        {
-            foundcount+=addfile(lbph->path, ip);
-        }
-    }
-    if(foundcount == 0)
-    {
-        fprintf(stderr, "?ASlink-Warning-Couldn't find library '%s'\n", ip);
-    }
-}
-
-/*)Function int addfile(path,libfil)
- *
- *      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 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
- *
- *  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
- *
- *  side effects:
- *      An lbname structure may be created.
- *
- *  return:
- *      1: the library was found
- *      0: the library was not found
- */
-
-int addfile(char * path, char * libfil)
-{
-    FILE *fp;
-    char *str;
-    struct lbname *lbnh, *lbn;
-#ifdef  OTHERSYSTEM
-    int libfilinc=0;
-#endif
-
-    if (path != NULL)
-    {
-        str = (char *) new (strlen(path) + strlen(libfil) + 6);
-        strcpy(str,path);
-#ifdef  OTHERSYSTEM
-        if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\'))
-        {
-            strcat(str,"/");
-        }
-#endif
-    }
-    else
-    {
-        str = (char *) new (strlen(libfil) + 5);
-    }
-
-#ifdef  OTHERSYSTEM
-    if ((libfil[0] == '/') || (libfil[0] == '\\'))
-    {
-        libfil++;
-        libfilinc=1;
-    }
-#endif
-
-    strcat(str, libfil);
-    if(strchr(libfil, FSEPX) == NULL)
-    {
-        sprintf(&str[strlen(str)], "%clib", FSEPX);
-    }
-
-    fp=fopen(str, "r");
-    if(fp == NULL)
-    {
-        /*Ok, that didn't work.  Try with the 'libfil' name only*/
-#ifdef  OTHERSYSTEM
-        if(libfilinc) libfil--;
-#endif
-        fp=fopen(libfil, "r");
-        if(fp != NULL)
-        {
-            /*Bingo!  'libfil' is the absolute path of the library*/
-           strcpy(str, libfil);
-            path=NULL;/*This way 'libfil' and 'path' will be rebuilt from 'str'*/
-        }
-    }
-
-    if(path==NULL)
-    {
-        /*'path' can not be null since it is needed to find the '.rel' 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) + 1);
-        strcpy(path, str);
-        for(j=strlen(path)-1; j>=0; j--)
-        {
-            if((path[j] == '/') || (path[j] == '\\'))
-            {
-                strcpy(libfil, &path[j+1]);
-                path[j+1]=0;
-                break;
-            }
-        }
-        if(j<=0) path[0]=0;
-    }
-
-    if (fp != NULL)
-    {
-        fclose(fp);
-        lbnh = (struct lbname *) new (sizeof(struct lbname));
-        if (lbnhead == NULL)
-        {
-            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;
-        return 1;
-    }
-    else
-    {
-        free(str);
-        return 0;
-    }
-}
-
-/*)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.
- *
- *  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
- *
- *  global variables:
- *      sym     *symhash[]  array of pointers to symbol tables
- *
- *   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.
- */
-
-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; i<NHASH; ++i) {
-            sp = symhash[i];
-            while (sp) {
-                /* If we find an undefined symbol
-                 * (one where S_DEF is not set), then
-                 * try looking for it.  If we find it
-                 * in any of the libraries then
-                 * increment symfnd.  This will force
-                 * another pass of symbol searching and
-                 * make sure that back references work.
-                 */
-                if ((sp->s_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, "<FILE>"))
-                {
-                    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, "<REL>")) state=2;
-            break;
-            case 2:
-                if(EQ(str, "</REL>")) return;
-                ip = str;
-                link_main();
-            break;
-        }
-    }
-}
-
-/*Load an .adb file embedded in a sdcclib file.  If there is
-something between <ADB> and </ADB> returns 1, otherwise returns 0.
-This way the aomf51 will not have uselless empty modules. */
-
-int LoadAdb(FILE * libfp)
-{
-    char str[MAXLINE+1];
-    int state=0;
-    int ToReturn=0;
-
-    while (fgets(str, MAXLINE, libfp) != NULL)
-    {
-        str[NINPUT+1] = '\0';
-        chop_crlf(str);
-        switch(state)
-        {
-            case 0:
-                if(EQ(str, "<ADB>")) state=1;
-            break;
-            case 1:
-                if(EQ(str, "</ADB>")) return ToReturn;
-                fprintf(dfp, "%s\n", str);
-                ToReturn=1;
-            break;
-        }
-    }
-    return ToReturn;
-}
-
-/*Check for a symbol in a SDCC library.  If found, add the embedded .rel and
-.adb files from the library.  The library must be created with the SDCC
-librarian 'sdcclib' since the linking process depends on the correct file offsets
-embedded in the library 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;
-
-    while(!feof(libfp))
-    {
-        FLine[0]=0;
-        fgets(FLine, MAXLINE, libfp);
-        chop_crlf(FLine);
-
-        switch(state)
-        {
-            case 0:
-                if(EQ(FLine, "<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;
-                }
-            break;
-            case 1:
-                if(EQ(FLine, "<MODULE>"))
-                {
-                    /*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;
-                }
-                else if(EQ(FLine, "</INDEX>"))
-                {
-                    /*Reached the end of the index.  The symbol is not in this library.*/
-                    return 0;
-                }
-            break;
-            case 2:
-                if(EQ(FLine, "</MODULE>"))
-                {
-                    /*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)], "%crel", FSEPX);
-
-                        /*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);
-
-                        /* if cdb information required & .adb file present */
-                        if (dflag && dfp)
-                        {
-                            if(LoadAdb(libfp))
-                                SaveLinkedFilePath(DirLib);
-                        }
-                        return 1; /*Found the symbol, so success!*/
-                    }
-                }
-            break;
-
-            default:
-                return 0; /*It should never reach this point, but just in case...*/
-            break;
-        }
-    }
-
-    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.
- */
-
-#ifdef INDEXLIB
-
-int fndsym( char *name )
-{
-    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;
-    FirstFound = libr; /*So gcc stops whining*/
-    while (ThisLibr)
-    {
-        /* Iterate through all symbols in an object file */
-        ThisSym = ThisLibr->symbols;
-
-        while (ThisSym)
-        {
-            if (!strcmp(ThisSym->name, name))
-            {
-                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)
-                    {
-                        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);
-                    lbfh->offset = ThisLibr->offset;
-                    if(lbfh->offset>0)
-                    { /*For an embedded object file in a library*/
-                        void loadfile_SdccLib(char * libspc, char * module, long offset);
-                        loadfile_SdccLib(lbfh->libspc, lbfh->relfil, lbfh->offset);
-                    }
-                    else
-                    { /*For a stand alone object file*/
-                        /* if cdb information required & adb file present */
-                        if (dflag && dfp)
-                        {
-                            FILE *xfp = afile(lbfh->filspc, "adb",0);
-                            if (xfp)
-                            {
-                                SaveLinkedFilePath(lbfh->filspc);
-                                copyfile(dfp, xfp);
-                                fclose(xfp);
-                            }
-                        }
-                        loadfile(lbfh->filspc);
-                    }
-                    ThisLibr->loaded=1;
-                }
-
-                if(numfound==0)
-                {
-                    numfound++;
-                    FirstFound=ThisLibr;
-                }
-                else
-                {
-                    char absPath1[PATH_MAX];
-                    char absPath2[PATH_MAX];
-#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
-                    int j;
-
-                    _fullpath(absPath1, FirstFound->libspc, PATH_MAX);
-                    _fullpath(absPath2, ThisLibr->libspc, PATH_MAX);
-                    for(j=0; absPath1[j]!=0; j++) absPath1[j]=tolower((unsigned char)absPath1[j]);
-                    for(j=0; absPath2[j]!=0; j++) absPath2[j]=tolower((unsigned char)absPath2[j]);
-#else
-                    realpath(FirstFound->libspc, absPath1);
-                    realpath(ThisLibr->libspc, absPath2);
-#endif
-                    if( !( EQ(absPath1, absPath2) && EQ(FirstFound->relfil, ThisLibr->relfil) ) )
-                    {
-                        if(numfound==1)
-                        {
-                            fprintf(stderr, "?Aslink-Warning-Definition of public symbol '%s'"
-                                   " found more than once:\n", name);
-                            fprintf(stderr, "   Library: '%s', Module: '%s'\n",
-                                    FirstFound->libspc, FirstFound->relfil);
-                        }
-                        fprintf(stderr, "   Library: '%s', Module: '%s'\n",
-                                ThisLibr->libspc, ThisLibr->relfil);
-                        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 buff[PATH_MAX];
-    int state=0;
-    long IndexOffset=0, FileOffset;
-    pmlibrarysymbol ThisSym = NULL;
-
-    while(!feof(libfp))
-    {
-        FLine[0]=0;
-        fgets(FLine, MAXLINE, libfp);
-        chop_crlf(FLine);
-
-        switch(state)
-        {
-            case 0:
-                if(EQ(FLine, "<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;
-                }
-            break;
-            case 1:
-                if(EQ(FLine, "<MODULE>"))
-                {
-                    /*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;
-
-                    /*Create a new libraryfile object for this module*/
-                    if(libr==NULL)
-                    {
-                        libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
-                    }
-                    else
-                    {
-                        This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
-                        This=This->next;
-                    }
-                    This->next = NULL;
-                    This->loaded=-1;
-                    This->offset=FileOffset+IndexOffset;
-                    This->libspc=PathLib;
-
-                    This->relfil=(char *)new(strlen(ModName)+1);
-                    strcpy(This->relfil, ModName);
-
-                    sprintf(buff, "%s%s%crel", DirLib, ModName, FSEPX);
-                    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, "</INDEX>"))
-                {
-                    return This; /*Finish, get out of here*/
-                }
-            break;
-            case 2:
-                if(EQ(FLine, "</MODULE>"))
-                {
-                    This->loaded=0;
-                    /*Create the index for the next module*/
-                    state=1;
-                }
-                else
-                {
-                    /*Add the symbols*/
-                    if(ThisSym==NULL) /*First symbol of the current module*/
-                    {
-                        ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
-                    }
-                    else
-                    {
-                        ThisSym->next = (pmlibrarysymbol)new(sizeof(mlibrarysymbol));
-                        ThisSym=ThisSym->next;
-                    }
-                    ThisSym->next=NULL;
-                    ThisSym->name=(char *)new(strlen(FLine)+1);
-                    strcpy(ThisSym->name, FLine);
-                }
-            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...*/
-}
-
-
-/* buildlibraryindex - build an in-memory cache of the symbols contained in
- *                     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;
-
-    /*
-     * 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)
-            {
-                strcpy(str, path);
-#ifdef  OTHERSYSTEM
-                if (strlen(str) && (str[strlen(str)-1] != '/') && (str[strlen(str)-1] != '\\'))
-                {
-                    strcat(str,"/");
-                }
-#endif
-            }
-            else
-            {
-                strcpy(str, "");
-            }
-
-            if(strcmp(relfil, "<SDCCLIB>")==0)
-            {
-                /*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] == '\\')
-            {
-                strcat(str,relfil+1);
-            }
-            else
-            {
-                strcat(str,relfil);
-            }
-
-            if(strchr(relfil, FSEPX) == NULL)
-            {
-                sprintf(&str[strlen(str)], "%crel", FSEPX);
-            }
-
-            if ((fp = fopen(str, "r")) != NULL)
-            {
-                /* Opened OK - create a new libraryfile object for it */
-                if(libr==NULL)
-                {
-                    libr=This=(pmlibraryfile)new( sizeof( mlibraryfile ));
-                }
-                else
-                {
-                    This->next=(pmlibraryfile)new( sizeof( mlibraryfile ));
-                    This=This->next;
-                }
-                This->next = NULL;
-                This->loaded=-1;
-                This->offset=-1; /*We have a stand alone .rel file*/
-                This->libspc = lbnh->libspc;
-
-                This->relfil=(char *)new(strlen(relfil)+1);
-                strcpy(This->relfil, relfil);
-
-                This->filename=(char *)new(strlen(str)+1);
-                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';
-
-                    /*
-                     * 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 it's an actual symbol, record it */
-                    if (c == 'D')
-                    {
-                        if(ThisSym==NULL)
-                        {
-                            ThisSym=This->symbols=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
-                        }
-                        else
-                        {
-                            ThisSym->next=(pmlibrarysymbol)new(sizeof(mlibrarysymbol));
-                            ThisSym=ThisSym->next;
-                        }
-                        This->loaded=0;
-                        ThisSym->next=NULL;
-                        ThisSym->name=(char *)new(strlen(symname)+1);
-                        strcpy(ThisSym->name, symname);
-                    }
-                } /* 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;
-
-    ThisLibr = libr;
-
-    while (ThisLibr)
-    {
-        ThisSym = ThisLibr->symbols;
-
-        while (ThisSym)
-        {
-            free(ThisSym->name);
-            ThisSym2Free=ThisSym;
-            ThisSym=ThisSym->next;
-            free(ThisSym2Free);
-        }
-        free(ThisLibr->filename);
-        free(ThisLibr->relfil);
-        ThisLibr2Free=ThisLibr;
-        ThisLibr=ThisLibr->next;
-        free(ThisLibr2Free);
-    }
-
-    libr=NULL;
-}
-
-#else /* INDEXLIB */
-
-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".
-     */
-
-    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] != '\\'))
-                {
-                    strcat(str,"/");
-                }
-#endif
-            }
-            else
-            {
-                str = (char *) new (strlen(relfil) + 5);
-            }
-
-            if(strcmp(relfil, "<SDCCLIB>")==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] == '\\')
-            {
-                strcat(str,relfil+1);
-            }
-            else
-            {
-                strcat(str,relfil);
-            }
-
-            if(strchr(relfil, FSEPX) == NULL)
-            {
-                sprintf(&str[strlen(str)], "%crel", FSEPX);
-            }
-
-            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);
-
-                        /* if cdb information required & adb file present */
-                        if (dflag && dfp)
-                        {
-                            FILE *xfp = afile(str,"adb",0); //JCF: Nov 30, 2002
-                            if (xfp)
-                            {
-                                SaveLinkedFilePath(str);
-                                copyfile(dfp,xfp);
-                                fclose(xfp);
-                            }
-                        }
-                        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;
-
-    if ((fp = fopen(libspc,"r")) != NULL)
-    {
-        fseek(fp, offset, SEEK_SET);
-        LoadRel(libspc, fp, module);
-        fclose(fp);
-    }
-}
-
-/*)Function VOID    library()
- *
- *  The function library() links all the library object files
- *  contained in the lbfile structures.
- *
- *  local variables:
- *      lbfile  *lbfh       pointer to lbfile structure
- *
- *  global variables:
- *      lbfile  *lbfhead    pointer to first lbfile structure
- *
- *   functions called:
- *      VOID    loadfile    lklibr.c
- *
- *  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);
-        }
-    }
-#ifdef INDEXLIB
-    freelibraryindex();
-#endif
-}
-
-/*)Function VOID    loadfile(filspc)
- *
- *      char    *filspc     library object file specification
- *
- *  The function loadfile() links the library object module.
- *
- *  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
- *
- *   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.
- */
-
-VOID
-loadfile(filspc)
-char *filspc;
-{
-    FILE *fp;
-    char str[NINPUT+2];
-
-    if ((fp = fopen(filspc,"r")) != NULL) {
-        while (fgets(str, NINPUT, fp) != NULL) {
-            str[NINPUT+1] = '\0';
-            chop_crlf(str);
-            ip = str;
-            link_main();
-        }
-        fclose(fp);
-    }
-}
diff --git a/as/mcs51/lklist.c b/as/mcs51/lklist.c
deleted file mode 100644 (file)
index 5325ec8..0000000
+++ /dev/null
@@ -1,1099 +0,0 @@
-/* lklist.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * 28-Oct-97 JLH: 
- *           - lstarea: show s_id as string rather than array [NCPS]
- *           - lstarea: show a_id as string rather than array [NCPS]
- * 31-Oct-97 JLH: add NoICE output file genration in lstarea
- * 02-Apr-98 JLH: add XDATA, DATA, BIT flags to area output
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "aslink.h"
-
-/*)Module      lklist.c
- *
- *     The module lklist.c contains the functions which
- *     output the linker .map file and produce a relocated
- *     listing .rst file.
- *
- *     lklist.c contains the following functions:
- *             int     dgt()
- *             VOID    lstarea()
- *             VOID    lkulist()
- *             VOID    lkalist()
- *             VOID    lkglist()
- *             VOID    newpag()
- *             VOID    slew()
- *
- *     lklist.c contains no local variables.
- */
-
-/*)Function    VOID    slew(fp)
- *
- *             FILE *  fp              output file handle
- *
- *     The function slew() increments the page line counter.
- *     If the number of lines exceeds the maximum number of
- *     lines per page then a page skip and a page header are
- *     output.
- *
- *     local variables:
- *             int     i               loop counter
- *
- *     global variables:
- *             int     lop             current line number on page
- *             int     xflag           Map file radix type flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    newpag()        lklist.c
- *
- *     side effects:
- *             The page line and the page count may be updated.
- */
-
-VOID
-slew(fp)
-FILE *fp;
-{
-       register int i;
-
-       if (lop++ >= NLPP) {
-               newpag(fp);
-               if (xflag == 0) {
-                       fprintf(fp, "Hexadecimal\n\n");
-               } else
-               if (xflag == 1) {
-                       fprintf(fp, "Octal\n\n");
-               } else
-               if (xflag == 2) {
-                       fprintf(fp, "Decimal\n\n");
-               }
-               fprintf(fp, "Area       Addr   Size");
-               fprintf(fp, "   Decimal Bytes (Attributes)\n");
-               for(i=0;i<4;++i)
-                       fprintf(fp, "      Value--Global");
-               fprintf(fp, "\n\n");
-               lop += 6;
-       }
-}
-
-/*)Function    VOID    newpag()
- *
- *     The function newpag() outputs a page skip, writes the
- *     first page header line, sets the line count to 1, and
- *     increments the page counter.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             int     lop             current line number on page
- *             int     page            current page number
- *
- *     functions called:
- *             int     fprintf()       c_library
- *
- *     side effects:
- *             The page and line counters are updated.
- */
-
-VOID
-newpag(fp)
-FILE *fp;
-{
-       fprintf(fp, "\fASxxxx Linker %s,  page %u.\n", VERSION, ++page);
-       lop = 1;
-}
-
-/* Used for qsort call in lstsym */
-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);    
-}
-
-
-#if    NCPS-8
-
-/* NCPS != 8 */
-/*)Function    VOID    lstarea(xp)
- *
- *             area *  xp              pointer to an area structure
- *
- *     The function lstarea() creates the linker map output for
- *     the area specified by pointer xp.  The generated output
- *     area header includes the area name, starting address,
- *     size of area, number of words (in decimal), and the
- *     area attributes.  The symbols defined in this area are
- *     sorted by ascending address and output one per line
- *     in the selected radix.
- *
- *     local variables:
- *             areax * oxp             pointer to an area extension structure
- *             int     c               character value
- *             int     i               loop counter
- *             int     j               bubble sort update status
- *             char *  ptr             pointer to an id string
- *             int     nmsym           number of symbols in area
- *             Addr_T  a0              temporary
- *             Addr_T  ai              temporary
- *             Addr_T  aj              temporary
- *             sym *   sp              pointer to a symbol structure
- *             sym **  p               pointer to an array of
- *                                     pointers to symbol structures
- *
- *     global variables:
- *             FILE    *mfp            Map output file handle
- *             sym *symhash[NHASH]     array of pointers to NHASH
- *                                     linked symbol lists
- *             int     xflag           Map file radix type flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    free()          c_library
- *             char *  malloc()        c_library
- *             char    putc()          c_library
- *             VOID    slew()          lklist.c
- *
- *     side effects:
- *             Map output generated.
- */
-
-VOID
-lstarea(xp)
-struct area *xp;
-{
-       register struct areax *oxp;
-       register int i;
-       /* int j; */
-       register char *ptr;
-       int nmsym;
-       /* Addr_T a0; */
-       Addr_T     ai, aj;
-       struct sym *sp;
-       struct sym **p;
-       int memPage;
-
-       putc('\n', mfp);
-       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 %s (Attributes)\n",
-               (xp->a_flag & A_BIT)?"Bits ":"Bytes");/* JCF: For BIT print bits...*/
-       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. %s ", aj,
-               (xp->a_flag & A_BIT)?"bits ":"bytes"); /* JCF: For BIT print bits...*/
-       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");
-       }
-
-       memPage = 0x00;
-       if (xp->a_flag & A_CODE) {
-               fprintf(mfp, ",CODE");
-               memPage = 0x0C;
-       }
-       if (xp->a_flag & A_XDATA) {
-               fprintf(mfp, ",XDATA");
-               memPage = 0x0D;
-       }
-       if (xp->a_flag & A_BIT) {
-               fprintf(mfp, ",BIT");
-               memPage = 0x0B;
-       }
-       fprintf(mfp, ")");
-       if (xp->a_flag & A_PAG) {
-               ai = (ai & 0xFF);
-               aj = (aj > 256);
-               if (ai || aj) { fprintf(mfp, "  "); }
-               if (ai)      { fprintf(mfp, " Boundary"); }
-               if (ai & aj)  { fprintf(mfp, " /"); }
-               if (aj)      { fprintf(mfp, " Length"); }
-               if (ai || aj) { fprintf(mfp, " Error"); }
-       }
-
-       /*
-        * Find number of symbols in area
-        */
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp)
-                                       ++nmsym;
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-       if (nmsym == 0) {
-               putc('\n', mfp);
-               return;
-       }
-
-       /*
-        * Allocate space for an array of pointers to symbols
-        * and load array.
-        */
-       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
-               == NULL) {
-               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
-               return;
-       }
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp) {
-                                       p[nmsym++] = sp;
-                               }
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-
-#if 0
-       /*
-        * Bubble Sort of Addresses in Symbol Table Array
-        */
-       j = 1;
-       while (j) {
-               j = 0;
-               sp = p[0];
-               a0 = sp->s_addr + sp->s_axp->a_addr;
-               for (i=1; i<nmsym; ++i) {
-                       sp = p[i];
-                       ai = sp->s_addr + sp->s_axp->a_addr;
-                       if (a0 > ai) {
-                               j = 1;
-                               p[i] = p[i-1];
-                               p[i-1] = sp;
-                       }
-                       a0 = ai;
-               }
-       }
-#else
-       qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr);
-#endif 
-
-       /*
-        * Symbol Table Output
-        */
-
-       i = 0;
-       fprintf(mfp, "\n\n");
-       fprintf(mfp, "      Value  Global\n");
-       fprintf(mfp, "   --------  --------------------------------");
-       while (i < nmsym) {
-               fprintf(mfp, "\n");
-               if (memPage != 0) 
-                       fprintf(mfp, "  %02X:", memPage);
-               else
-                       fprintf(mfp, "     ");
-
-               sp = p[i];
-               aj = sp->s_addr + sp->s_axp->a_addr;
-               if (xflag == 0) {
-                       fprintf(mfp, "%04X    ", aj);
-               } else
-               if (xflag == 1) {
-                       fprintf(mfp, "%06o  ", aj);
-               } else
-               if (xflag == 2) {
-                       fprintf(mfp, "%05u   ", aj);
-               }
-               ptr = &sp->s_id[0];
-               fprintf(mfp, "%s", ptr );
-               
-               /* if cdb flag set the output cdb Information 
-                  and the symbol has a '$' sign in it then */
-               if (dflag &&
-                   strchr(ptr,'$'))
-                   fprintf(dfp,"L:%s:%X\n",ptr,aj);
-
-               /* NoICE output of symbol */
-               if (jflag) DefineNoICE( ptr, aj, memPage );
-
-               i++;
-       }
-       putc('\n', mfp);
-       free(p);
-}
-
-#else
-
-/* NCPS == 8 */
-/*)Function    VOID    lstarea(xp)
- *
- *             area *  xp              pointer to an area structure
- *
- *     The function lstarea() creates the linker map output for
- *     the area specified by pointer xp.  The generated output
- *     area header includes the area name, starting address,
- *     size of area, number of words (in decimal), and the
- *     area attributes.  The symbols defined in this area are
- *     sorted by ascending address and output four per line
- *     in the selected radix.
- *
- *     local variables:
- *             areax * oxp             pointer to an area extension structure
- *             int     c               character value
- *             int     i               loop counter
- *             int     j               bubble sort update status
- *             char *  ptr             pointer to an id string
- *             int     nmsym           number of symbols in area
- *             Addr_T  a0              temporary
- *             Addr_T  ai              temporary
- *             Addr_T  aj              temporary
- *             sym *   sp              pointer to a symbol structure
- *             sym **  p               pointer to an array of
- *                                     pointers to symbol structures
- *
- *     global variables:
- *             FILE    *mfp            Map output file handle
- *             sym *symhash[NHASH]     array of pointers to NHASH
- *                                     linked symbol lists
- *             int     xflag           Map file radix type flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    free()          c_library
- *             char *  malloc()        c_library
- *             char    putc()          c_library
- *             VOID    slew()          lklist.c
- *
- *     side effects:
- *             Map output generated.
- */
-
-VOID
-lstarea(xp)
-struct area *xp;
-{
-       register struct areax *oxp;
-       register c, i, j;
-       register char *ptr;
-       int nmsym;
-       Addr_T a0, ai, aj;
-       struct sym *sp;
-       struct sym **p;
-        int page;
-
-       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");
-       }
-
-       page = 0x00;
-       if (xp->a_flag & A_CODE) {
-               fprintf(mfp, ",CODE");
-               memPage = 0x0C;
-       }
-       if (xp->a_flag & A_XDATA) {
-               fprintf(mfp, ",XDATA");
-               memPage = 0x0D;
-       }
-       if (xp->a_flag & A_BIT) {
-               fprintf(mfp, ",BIT");
-               memPage = 0x0B;
-       }
-       fprintf(mfp, ")");
-       if (xp->a_flag & A_PAG) {
-               ai = (ai & 0xFF);
-               aj = (aj > 256);
-               if (ai || aj) { fprintf(mfp, "  "); }
-               if (ai)      { fprintf(mfp, " Boundary"); }
-               if (ai & aj)  { fprintf(mfp, " /"); }
-               if (aj)      { fprintf(mfp, " Length"); }
-               if (ai || aj) { fprintf(mfp, " Error"); }
-       }
-
-       /*
-        * Find number of symbols in area
-        */
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp)
-                                       ++nmsym;
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-       if (nmsym == 0) {
-               putc('\n', mfp);
-               slew(mfp);
-               return;
-       }
-
-       /*
-        * Allocate space for an array of pointers to symbols
-        * and load array.
-        */
-       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
-               == NULL) {
-               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
-               slew(mfp);
-               return;
-       }
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp) {
-                                       p[nmsym++] = sp;
-                               }
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-
-#if 0
-       /*
-        * Bubble Sort of Addresses in Symbol Table Array
-        */
-       j = 1;
-       while (j) {
-               j = 0;
-               sp = p[0];
-               a0 = sp->s_addr + sp->s_axp->a_addr;
-               for (i=1; i<nmsym; ++i) {
-                       sp = p[i];
-                       ai = sp->s_addr + sp->s_axp->a_addr;
-                       if (a0 > ai) {
-                               j = 1;
-                               p[i] = p[i-1];
-                               p[i-1] = sp;
-                       }
-                       a0 = ai;
-               }
-       }
-#else
-       qsort(p, nmsym, sizeof(struct sym *), _cmpSymByAddr);
-#endif 
-
-       /*
-        * Symbol Table Output
-        */
-       i = 0;
-       while (i < nmsym) {
-               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", ptr );
-
-               /* NoICE output of symbol */
-               if (jflag) DefineNoICE( ptr, aj, memPage );
-       }
-       putc('\n', mfp);
-       free(p);
-       slew(mfp);
-}
-#endif
-
-/*)Function    VOID    lkulist(i)
- *
- *             int     i       i # 0   process LST to RST file
- *                             i = 0   copy remainder of LST file
- *                                     to RST file and close files
- *
- *     The function lkulist() creates a relocated listing (.rst)
- *     output file from the ASxxxx assembler listing (.lst)
- *     files.  The .lst file's program address and code bytes
- *     are changed to reflect the changes made by ASlink as
- *     the .rel files are combined into a single relocated
- *     output file.
- *
- *     local variables:
- *             Addr_T  pc              current program counter address
- *
- *     global variables:
- *             int     hilo            byte order
- *             int     gline           get a line from the LST file
- *                                     to translate for the RST file
- *             char    rb[]            read listing file text line
- *             FILE    *rfp            The file handle to the current
- *                                     output RST file
- *             int     rtcnt           count of data words
- *             int     rtflg[]         output the data flag
- *             Addr_T  rtval[]         relocated data
- *             FILE    *tfp            The file handle to the current
- *                                     LST file being scanned
- *
- *     functions called:
- *             int     fclose()        c_library
- *             int     fgets()         c_library
- *             int     fprintf()       c_library
- *             VOID    lkalist()       lklist.c
- *             VOID    lkglist()       lklist.c
- *
- *     side effects:
- *             A .rst file is created for each available .lst
- *             file associated with a .rel file.
- */
-
-VOID
-lkulist(i)
-int i;
-{
-       Addr_T pc;
-
-       /*
-        * Exit if listing file is not open
-        */
-       if (tfp == NULL)
-               return;
-
-       /*
-        * Normal processing of LST to RST
-        */
-       if (i) {
-               /*
-                * Evaluate current code address
-                */
-               if (hilo == 0) {
-                       pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF);
-               } else {
-                       pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF);
-               }
-
-               /*
-                * Line with only address
-                */
-               if (rtcnt == 2) {
-                       lkalist(pc);
-
-               /*
-                * Line with address and code
-                */
-               } else {
-                       for (i=2; i < rtcnt; i++) {
-                               if (rtflg[i]) {
-                                       lkglist(pc++, rtval[i] & 0xFF);
-                               }
-                       }
-               }
-
-       /*
-        * Copy remainder of LST to RST
-        */
-       } else {
-               if (gline == 0)
-                       fprintf(rfp, "%s", rb);
-
-               while (fgets(rb, sizeof(rb), tfp) != 0) {
-                       fprintf(rfp, "%s", rb);
-               }
-               fclose(tfp);
-               tfp = NULL;
-               fclose(rfp);
-               rfp = NULL;
-       }
-}
-
-/*)Function    VOID    lkalist(pc)
- *
- *             int     pc              current program counter value
- *
- *     The function lkalist() performs the following functions:
- *
- *     (1)     if the value of gline = 0 then the current listing
- *             file line is copied to the relocated listing file output.
- *
- *     (2)     the listing file is read line by line and copied to
- *             the relocated listing file until a valid source
- *             line number and a program counter value of the correct
- *             radix is found.  The new relocated pc value is substituted
- *             and the line is written to the RST file.
- *
- *     local variables:
- *             int     i               loop counter
- *             char    str[]           temporary string
- *
- *     global variables:
- *             int     gcntr           data byte counter
- *             int     gline           get a line from the LST file
- *                                     to translate for the RST file
- *             char    rb[]            read listing file text line
- *             char    *rp             pointer to listing file text line
- *             FILE    *rfp            The file handle to the current
- *                                     output RST file
- *             FILE    *tfp            The file handle to the current
- *                                     LST file being scanned
- *
- *     functions called:
- *             int     dgt()           lklist.c
- *             int     fclose()        c_library
- *             int     fgets()         c_library
- *             int     fprintf()       c_library
- *             int     sprintf()       c_library
- *             char *  strncpy()       c_library
- *
- *     side effects:
- *             Lines of the LST file are copied to the RST file,
- *             the last line copied has the code address
- *             updated to reflect the program relocation.
- */
-
-VOID
-lkalist(pc)
-Addr_T pc;
-{
-       char str[8];
-       int i;
-
-       /*
-        * Exit if listing file is not open
-        */
-loop:  if (tfp == NULL)
-               return;
-
-       /*
-        * Copy current LST to RST
-        */
-       if (gline == 0) {
-               fprintf(rfp, "%s", rb);
-               gline = 1;
-       }
-
-       /*
-        * Clear text line buffer
-        */
-       for (i=0,rp=rb; i<sizeof(rb); i++) {
-               *rp++ = 0;
-       }
-
-       /*
-        * Get next LST text line
-        */
-       if (fgets(rb, sizeof(rb), tfp) == NULL) {
-               fclose(tfp);
-               tfp = NULL;
-               fclose(rfp);
-               rfp = NULL;
-               return;
-       }
-
-       /*
-        * Must have an ASxxxx Listing line number
-        */
-       if (!dgt(RAD10, &rb[30], 1)) {
-               fprintf(rfp, "%s", rb);
-               goto loop;
-       }
-
-       /*
-        * Must have an address in the expected radix
-        */
-       if (radix == 16) {
-               if (!dgt(RAD16, &rb[3], 4)) {
-                       fprintf(rfp, "%s", rb);
-                       goto loop;
-               }
-               sprintf(str, "%04X", pc);
-               strncpy(&rb[3], str, 4);
-       } else
-       if (radix == 10) {
-               if (!dgt(RAD10, &rb[3], 5)) {
-                       fprintf(rfp, "%s", rb);
-                       goto loop;
-               }
-               sprintf(str, "%05d", pc);
-               strncpy(&rb[3], str, 5);
-       } else
-       if (radix == 8) {
-               if (!dgt(RAD8, &rb[3], 6)) {
-                       fprintf(rfp, "%s", rb);
-                       goto loop;
-               }
-               sprintf(str, "%06o", pc);
-               strncpy(&rb[3], str, 6);
-       }
-
-       /*
-        * Copy updated LST text line to RST
-        */
-       fprintf(rfp, "%s", rb);
-       gcntr = 0;
-}
-
-/*)Function    VOID    lkglist(pc,v)
- *
- *             int     pc              current program counter value
- *             int     v               value of byte at this address
- *
- *     The function lkglist() performs the following functions:
- *
- *     (1)     if the value of gline = 1 then the listing file
- *             is read line by line and copied to the
- *             relocated listing file until a valid source
- *             line number and a program counter value of the correct
- *             radix is found.
- *
- *     (2)     The new relocated values and code address are
- *             substituted and the line may be written to the RST file.
- *
- *     local variables:
- *             int     i               loop counter
- *             char    str[]           temporary string
- *
- *     global variables:
- *             int     gcntr           data byte counter
- *                                     set to -1 for a continuation line
- *             int     gline           get a line from the LST file
- *                                     to translate for the RST file
- *             char    rb[]            read listing file text line
- *             char    *rp             pointer to listing file text line
- *             FILE    *rfp            The file handle to the current
- *                                     output RST file
- *             FILE    *tfp            The file handle to the current
- *                                     LST file being scanned
- *
- *     functions called:
- *             int     dgt()           lklist.c
- *             int     fclose()        c_library
- *             int     fgets()         c_library
- *             int     fprintf()       c_library
- *             int     sprintf()       c_library
- *             char *  strncpy()       c_library
- *
- *     side effects:
- *             Lines of the LST file are copied to the RST file
- *             with updated data values and code addresses.
- */
-
-VOID
-lkglist(pc,v)
-Addr_T pc;
-int v;
-{
-       char str[8];
-       int i;
-
-       /*
-        * Exit if listing file is not open
-        */
-loop:  if (tfp == NULL)
-               return;
-
-       /*
-        * Get next LST text line
-        */
-       if (gline) {
-               /*
-                * Clear text line buffer
-                */
-               for (i=0,rp=rb; i<sizeof(rb); i++) {
-                       *rp++ = 0;
-               }
-
-               /*
-                * Get next LST text line
-                */
-               if (fgets(rb, sizeof(rb), tfp) == NULL) {
-                       fclose(tfp);
-                       tfp = NULL;
-                       fclose(rfp);
-                       rfp = NULL;
-                       return;
-               }
-
-               /*
-                * Check for a listing line number if required
-                */
-               if (gcntr != -1) {
-                       if (!dgt(RAD10, &rb[30], 1)) {
-                               fprintf(rfp, "%s", rb);
-                               goto loop;
-                       }
-                       gcntr = 0;
-               }
-               gline = 0;
-       }
-
-       /*
-        * Hex Listing
-        */
-       if (radix == 16) {
-               /*
-                * Data Byte Pointer
-                */
-               if (gcntr == -1) {
-                       rp = &rb[8];
-               } else {
-                       rp = &rb[8 + (3 * gcntr)];
-               }
-               /*
-                * Number must be of proper radix
-                */
-               if (!dgt(RAD16, rp, 2)) {
-                       fprintf(rfp, "%s", rb);
-                       gline = 1;
-                       goto loop;
-               }
-               /*
-                * Output new data value, overwrite relocation codes
-                */
-               sprintf(str, " %02X", v);
-               strncpy(rp-1, str, 3);
-               if (gcntr == -1) {
-                       gcntr = 0;
-               }
-               /*
-                * Output relocated code address
-                */
-               if (gcntr == 0) {
-                       if (dgt(RAD16, &rb[3], 4)) {
-                               sprintf(str, "%04X", pc);
-                               strncpy(&rb[3], str, 4);
-                       }
-               }
-               /*
-                * Output text line when updates finished
-                */
-               if (++gcntr == 6) {
-                       fprintf(rfp, "%s", rb);
-                       gline = 1;
-                       gcntr = -1;
-               }
-       } else
-       /*
-        * Decimal Listing
-        */
-       if (radix == 10) {
-               /*
-                * Data Byte Pointer
-                */
-               if (gcntr == -1) {
-                       rp = &rb[9];
-               } else {
-                       rp = &rb[9 + (3 * gcntr)];
-               }
-               /*
-                * Number must be of proper radix
-                */
-               if (!dgt(RAD10, rp, 3)) {
-                       fprintf(rfp, "%s", rb);
-                       gline = 1;
-                       goto loop;
-               }
-               /*
-                * Output new data value, overwrite relocation codes
-                */
-               sprintf(str, " %03d", v);
-               strncpy(rp-1, str, 4);
-               if (gcntr == -1) {
-                       gcntr = 0;
-               }
-               /*
-                * Output relocated code address
-                */
-               if (gcntr == 0) {
-                       if (dgt(RAD10, &rb[3], 5)) {
-                               sprintf(str, "%05d", pc);
-                               strncpy(&rb[3], str, 5);
-                       }
-               }
-               /*
-                * Output text line when updates finished
-                */
-               if (++gcntr == 4) {
-                       fprintf(rfp, "%s", rb);
-                       gline = 1;
-                       gcntr = -1;
-               }
-       } else
-       /*
-        * Octal Listing
-        */
-       if (radix == 8) {
-               /*
-                * Data Byte Pointer
-                */
-               if (gcntr == -1) {
-                       rp = &rb[10];
-               } else {
-                       rp = &rb[10 + (3 * gcntr)];
-               }
-               /*
-                * Number must be of proper radix
-                */
-               if (!dgt(RAD8, rp, 3)) {
-                       fprintf(rfp, "%s", rb);
-                       gline = 1;
-                       goto loop;
-               }
-               /*
-                * Output new data value, overwrite relocation codes
-                */
-               sprintf(str, " %03o", v);
-               strncpy(rp-1, str, 4);
-               if (gcntr == -1) {
-                       gcntr = 0;
-               }
-               /*
-                * Output relocated code address
-                */
-               if (gcntr == 0) {
-                       if (dgt(RAD8, &rb[3], 6)) {
-                               sprintf(str, "%06o", pc);
-                               strncpy(&rb[3], str, 6);
-                       }
-               }
-               /*
-                * Output text line when updates finished
-                */
-               if (++gcntr == 4) {
-                       fprintf(rfp, "%s", rb);
-                       gline = 1;
-                       gcntr = -1;
-               }
-       }
-}
-
-/*)Function    int     dgt(rdx,str,n)
- *
- *             int     rdx             radix bit code
- *             char    *str            pointer to the test string
- *             int     n               number of characters to check
- *
- *     The function dgt() verifies that the string under test
- *     is of the specified radix.
- *
- *     local variables:
- *             int     i               loop counter
- *
- *     global variables:
- *             ctype[]                 array of character types
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-
-int
-dgt(rdx, str, n)
-int rdx, n;
-char *str;
-{
-       int i;
-
-       for (i=0; i<n; i++) {
-               if ((ctype[(int)*str++] & rdx) == 0)
-                       return(0);
-       }
-       return(1);
-}
diff --git a/as/mcs51/lkmain.c b/as/mcs51/lkmain.c
deleted file mode 100644 (file)
index 43392b8..0000000
+++ /dev/null
@@ -1,1444 +0,0 @@
-/* lkmain.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * 31-Oct-97 JLH:
- *           - add jflag and jfp to control NoICE output file genration
- *  3-Nov-97 JLH:
- *           - use a_type == 0 as "virgin area" flag: set == 1 if -b
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-#ifdef WIN32T
-#include <time.h>
-
-void Timer(int action, char * message)
-{
-    static double start, end, total=0.0;
-    static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC;
-
-    if(action==0) start=clock()*secs_per_tick;
-    else if(action==1)
-    {
-        end=clock() * secs_per_tick;
-        printf("%s \t%f seconds.\n", message, (end-start));
-        total+=end-start;
-    }
-    else
-    {
-        printf("Total time: \t%f seconds.\n", total);
-        total=0.0;
-    }
-}
-#endif
-
-/*)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
- *
- */
-
-/*JCF:  Creates some of the default areas so they are allocated in the right order.*/
-void Areas51 (void)
-{
-    char * rel[]={
-        "XH",
-        "H 7 areas 0 global symbols",
-        "A _CODE size 0 flags 0",       /*Each .rel has one, so...*/
-        "A REG_BANK_0 size 0 flags 4",  /*Register banks are overlayable*/
-        "A REG_BANK_1 size 0 flags 4",
-        "A REG_BANK_2 size 0 flags 4",
-        "A REG_BANK_3 size 0 flags 4",
-        "A BSEG size 0 flags 80",       /*BSEG must be just before BITS*/
-        "A BSEG_BYTES size 0 flags 0",  /*Size will be obtained from BSEG in lnkarea()*/
-        ""
-    };
-
-    char * rel2[]={
-        "XH",
-        "H C areas 0 global symbols",
-        "A _CODE size 0 flags 0",       /*Each .rel has one, so...*/
-        "A REG_BANK_0 size 0 flags 4",  /*Register banks are overlayable*/
-        "A REG_BANK_1 size 0 flags 4",
-        "A REG_BANK_2 size 0 flags 4",
-        "A REG_BANK_3 size 0 flags 4",
-        "A BSEG size 0 flags 80",       /*BSEG must be just before BITS*/
-        "A BSEG_BYTES size 0 flags 0",  /*Size will be obtained from BSEG in lnkarea()*/
-        "A BIT_BANK size 0 flags 4",    /*Bit register bank is overlayable*/
-        "A DSEG size 0 flags 0",
-        "A OSEG size 0 flags 4",
-        "A ISEG size 0 flags 0",
-        "A SSEG size 0 flags 4",
-        ""
-    };
-    int j;
-    struct sym * sp;
-
-    if(packflag)
-    {
-        for (j=0; rel2[j][0]!=0; j++)
-        {
-            ip=rel2[j];
-            link_main();
-        }
-    }
-    else
-    {
-        for (j=0; rel[j][0]!=0; j++)
-        {
-            ip=rel[j];
-            link_main();
-        }
-    }
-
-    /*Set the start address of the default areas:*/
-    for(ap=areap; ap; ap=ap->a_ap)
-    {
-        /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; }
-        else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; }
-        else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; }
-        else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; }
-        else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; }
-        else if (!strcmp(ap->a_id, "SSEG"))
-        {
-            if(stacksize) ap->a_axp->a_size=stacksize;
-        }
-    }
-
-    sp = lkpsym("l_IRAM", 1);
-    sp->s_addr = ((iram_size>0) && (iram_size<=0x100)) ? iram_size : 0x0100;
-    sp->s_axp = NULL;
-    sp->s_type |= S_DEF;
-}
-
-/*)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 as_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     as_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).
- */
-
-int
-main(int argc, char *argv[])
-{
-    register char *p;
-    register int c, i;
-
-#ifdef WIN32T
-    Timer(0, "");
-#endif
-
-    startp = (struct lfile *) new (sizeof (struct lfile));
-
-    pflag = 1;
-    for (i=1; i<argc; ++i) {
-        p = argv[i];
-        if (*p == '-') {
-            while (ctype[c = *(++p)] & LETTER) {
-                switch(c) {
-
-                case 'c':
-                case 'C':
-                    startp->f_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();
-                }
-            }
-        } else {
-            if (startp->f_type == F_LNK) {
-                startp->f_idp = p;
-            }
-        }
-    }
-    if (startp->f_type == 0)
-        usage();
-    if (startp->f_type == F_LNK && startp->f_idp == NULL)
-        usage();
-
-    cfp = NULL;
-    sfp = NULL;
-    filep = startp;
-    while (1) {
-        ip = ib;
-        if (as_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();
-
-    syminit();
-
-    if (dflag){
-        //dfp = afile("temp", "cdb", 1);
-        SaveLinkedFilePath(linkp->f_idp); //Must be the first one...
-        dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002
-        if (dfp == NULL)
-        lkexit(1);
-    }
-
-    for (pass=0; pass<2; ++pass) {
-        cfp = NULL;
-        sfp = NULL;
-        filep = linkp;
-        hp = NULL;
-        radix = 10;
-
-        Areas51(); /*JCF: Create the default 8051 areas in the right order*/
-
-        while (as_getline()) {
-            ip = ib;
-
-            /* pass any "magic comments" to NoICE output */
-            if ((ip[0] == ';') && (ip[1] == '!') && jfp) {
-                fprintf( jfp, "%s\n", &ip[2] );
-            }
-            link_main();
-        }
-        if (pass == 0) {
-            /*
-             * Search libraries for global symbols
-             */
-            search();
-            /*
-             * Set area base addresses.
-             */
-            setbas();
-            /*
-             * Link all area addresses.
-             */
-            if(!packflag)
-                lnkarea();
-            else
-                lnkarea2();
-            /*
-             * Process global definitions.
-             */
-            setgbl();
-            /*
-             * Check for undefined globals.
-             */
-            symdef(stderr);
-
-            /* Open NoICE output file if requested */
-            if (jflag) {
-                jfp = afile(linkp->f_idp, "NOI", 1);
-                if (jfp == NULL) {
-                    lkexit(1);
-                }
-            }
-
-            /*
-             * Output Link Map if requested,
-             * or if NoICE output requested (since NoICE
-             * file is generated in part by map() processing)
-             */
-            if (mflag || jflag)
-                map();
-
-            if (sflag) /*JCF: memory usage summary output*/
-            {
-                if(!packflag)
-                {
-                    if(summary(areap)) lkexit(1);
-                }
-                else
-                {
-                    if(summary2(areap)) lkexit(1);
-                }
-            }
-
-            if ((iram_size) && (!packflag))
-                iramcheck();
-
-            /*
-             * Open output file
-             */
-            if (oflag == 1) {
-                ofp = afile(linkp->f_idp, "ihx", 1);
-                if (ofp == NULL) {
-                    lkexit(1);
-                }
-                /* include NoICE command to load hex file */
-                if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp );
-
-            } else
-            if (oflag == 2) {
-                ofp = afile(linkp->f_idp, "S19", 1);
-                if (ofp == NULL) {
-                    lkexit(1);
-                }
-                /* include NoICE command to load hex file */
-                if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp );
-            }
-        } else {
-            /*
-             * Link in library files
-             */
-            library();
-            reloc('E');
-        }
-    }
-    //JCF:
-    CreateAOMF51();
-
-#ifdef WIN32T
-    Timer(1, "Linker execution time");
-#endif
-
-    lkexit(lkerr);
-    return 0;
-}
-
-/*)Function VOID    lkexit(i)
- *
- *      int     i       exit code
- *
- *  The function lkexit() explicitly closes all open
- *  files and then terminates the program.
- *
- *  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
- *
- *  functions called:
- *      int     fclose()    c_library
- *      VOID    exit()      c_library
- *
- *  side effects:
- *      All files closed. Program terminates.
- */
-
-VOID
-lkexit(int i)
-{
-    if (mfp != NULL) fclose(mfp);
-    if (jfp != NULL) fclose(jfp);
-    if (ofp != NULL) fclose(ofp);
-    if (rfp != NULL) fclose(rfp);
-    if (sfp != NULL) fclose(sfp);
-    if (tfp != NULL) fclose(tfp);
-    if (dfp != NULL) fclose(dfp);
-    /*if (dfp != NULL)
-        FILE *xfp = afile(linkp->f_idp,"cdb",1);
-        dfp = freopen("temp.cdb","r",dfp);
-        copyfile(xfp,dfp);
-        fclose(xfp);
-        fclose(dfp);
-        remove("temp.cdb");
-    }*/
-    exit(i);
-}
-
-/*)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_main()
-{
-    register char 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)
-                {
-                    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)
-        {
-            strcpy(curr_module, &ip[1]);
-            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;
-        }
-    }
-}
-
-
-/*)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.
- */
-
-VOID
-map()
-{
-    register int i;
-    register struct head *hdp;
-    register struct lbfile *lbfh;
-
-    /*
-     * Open Map File
-     */
-    mfp = afile(linkp->f_idp, "map", 1);
-    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;
-    filep = linkp;
-    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);
-}
-
-/*)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;
-
-                case 'm':
-                case 'M':
-                    ++mflag;
-                    break;
-
-                case 'y': /*JCF: memory usage summary output*/
-                    ++sflag;
-                    break;
-
-                case 'Y':
-                    unget(getnb());
-                    packflag=1;
-                    break;
-
-                case 'A':
-                    unget(getnb());
-                    if (ip && *ip)
-                    {
-                        stacksize=expr(0);
-                        if(stacksize>256) stacksize=256;
-                        else if(stacksize<0) stacksize=0;
-                    }
-                    return(0);
-
-                case 'j':
-                case 'J':
-                    jflag = 1;
-                    break;
-
-                case 'u':
-                case 'U':
-                    uflag = 1;
-                    break;
-                case 'r':
-                case 'R':
-                    rflag = 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);
-
-                case 'a':
-                    iramsav();
-                    return(0);
-
-                case 'v':
-                case 'V':
-                    xramsav();
-                    return(0);
-
-                case 'w':
-                case 'W':
-                    codesav();
-                    return(0);
-
-                case 'z':
-                case 'Z':
-                        dflag = 1;
-                    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()
- *
- *  The function bassav() creates a linked structure containing
- *  the base address strings input to the linker.
- *
- *  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[]
- *
- *   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.
- */
-
-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);
-}
-
-/*)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) {
-                fprintf(stderr,
-                "ASlink-Warning-No definition of area %s\n", id);
-                lkerr++;
-            } else {
-                ap->a_addr = v;
-                ap->a_type = 1; /* JLH: value set */
-            }
-        } else {
-            fprintf(stderr, "ASlink-Warning-No '=' in base expression");
-            lkerr++;
-        }
-        bsp = bsp->b_base;
-    }
-}
-
-/*)Function VOID    gblsav()
- *
- *  The function gblsav() creates a linked structure containing
- *  the global variable strings input to the linker.
- *
- *  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
- *
- *  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.
- */
-
-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);
-}
-
-/*)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) {
-                fprintf(stderr,
-                "No definition of symbol %s\n", id);
-                lkerr++;
-            } else {
-                if (sp->s_flag & S_DEF) {
-                    fprintf(stderr,
-                    "Redefinition of symbol %s\n", id);
-                    lkerr++;
-                    sp->s_axp = NULL;
-                }
-                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:
- *      char    fb[]        constructed file specification string
- *      FILE *  fp          filehandle for opened file
- *
- *  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(char *fn, char *ft, int wf)
-{
-    FILE *fp;
-    char fb[PATH_MAX];
-    char *omode = (wf ? (wf == 2 ? "a" : "w") : "r");
-    int i;
-
-    /*Look backward the name path and get rid of the extension, if any*/
-    i=strlen(fn);
-    for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--);
-    if( (fn[i]=='.') && strcmp(ft, "lnk") )
-    {
-        strncpy(fb, fn, i);
-        fb[i]=0;
-    }
-    else
-    {
-        strcpy(fb, fn);
-    }
-
-    /*Add the extension*/
-    if (fb[i] != '.')
-    {
-        strcat(fb, ".");
-        strcat(fb, strlen(ft)?ft:"rel");
-    }
-
-    fp = fopen(fb, omode);
-    if (fp==NULL)
-    {
-        if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/
-        {
-            fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
-            lkerr++;
-        }
-    }
-    return (fp);
-}
-
-/*)Function VOID    iramsav()
- *
- *  The function iramsav() stores the size of the chip's internal RAM.
- *  This is used after linking to check that variable assignment to this
- *  dataspace didn't overflow into adjoining segments.  Variables in the
- *  DSEG, OSEG, and ISEG are assigned to this dataspace.
- *
- *  local variables:
- *      none
- *
- *  global variables:
- *      char    *ip         pointer into the REL file
- *                          text line in ib[]
- *      unsigned int        size of chip's internal
- *          iram_size       RAM segment
- *
- *   functions called:
- *      char    getnb()     lklex.c
- *      VOID    unget()     lklex.c
- *      Addr_T  expr()      lkeval.c
- *
- *  side effects:
- *      The iram_size may be modified.
- */
-
-VOID
-iramsav()
-{
-  unget(getnb());
-  if (ip && *ip)
-    iram_size = expr(0);    /* evaluate size expression */
-  else
-    iram_size = 128;        /* Default is 128 (0x80) bytes */
-  if ((iram_size<=0) || (iram_size>256))
-    iram_size = 128;        /* Default is 128 (0x80) bytes */
-}
-
-/*Similar to iramsav but for xram memory*/
-VOID
-xramsav()
-{
-  unget(getnb());
-  if (ip && *ip)
-    xram_size = expr(0);    /* evaluate size expression */
-  else
-    xram_size = rflag?0x1000000:0x10000;
-}
-
-/*Similar to iramsav but for code memory*/
-VOID
-codesav()
-{
-  unget(getnb());
-  if (ip && *ip)
-    code_size = expr(0);    /* evaluate size expression */
-  else
-    code_size = rflag?0x1000000:0x10000;
-}
-
-
-/*)Function VOID    iramcheck()
- *
- *  The function iramcheck() is used at the end of linking to check that
- *  the internal RAM area wasn't overflowed by too many variable
- *  assignments.  Variables in the DSEG, ISEG, and OSEG are assigned to
- *  the chip's internal RAM.
- *
- *  local variables:
- *      none
- *
- *  global variables:
- *      unsigned int        size of chip's internal
- *          iram_size       RAM segment
- *      struct area         linked list of memory
- *          *areap          areas
- *
- *   functions called:
- *
- *  side effects:
- */
-
-VOID
-iramcheck()
-{
-  register unsigned int last_addr;
-  register struct area *ap;
-
-  for (ap = areap; ap; ap=ap->a_ap) {
-    if ((ap->a_size != 0) &&
-        (!strcmp(ap->a_id, "DSEG") ||
-         !strcmp(ap->a_id, "OSEG") ||
-         !strcmp(ap->a_id, "ISEG")
-        )
-       )
-    {
-      last_addr = ap->a_addr + ap->a_size - 1;
-      if (last_addr >= iram_size)
-        fprintf(stderr,
-          "\nWARNING! Segment %s extends past the end\n"
-          "         of internal RAM.  Check map file.\n",
-          ap->a_id);
-    }
-  }
-}
-
-char *usetxt[] = {
-    "Startup:",
-    "  -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",
-/*  "Usage: [-Options] file [file ...]", */
-    "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",
-    "Map format:",
-    "  -m   Map output generated as file[MAP]",
-    "  -x   Hexadecimal (default),  -d  Decimal,  -q  Octal",
-    "Output:",
-    "  -i   Intel Hex as file[IHX]",
-    "  -s   Motorola S19 as file[S19]",
-    "  -j   Produce NoICE debug as file[NOI]",
-    "  -z   Produce SDCdb debug as file[cdb]",
-/*  "List:", */
-    "  -u   Update listing file(s) with link data as file(s)[.RST]",
-    "Miscellaneous:\n"
-    "  -a   [iram-size] Check for internal RAM overflow",
-    "  -v   [xram-size] Check for external RAM overflow",
-    "  -w   [code-size] Check for code overflow",
-    "  -y   Generate memory usage summary file[mem]",
-    "  -Y   Pack internal ram",
-    "  -A   [stack-size] Allocate space for stack",
-    "End:",
-    "  -e   or null line terminates input",
-    0
-};
-
-/*)Function VOID    usage()
- *
- *  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.
- *
- *  global variables:
- *      FILE *  stderr      c_library
- *
- *  functions called:
- *      int     fprintf()   c_library
- *
- *  side effects:
- *      none
- */
-
-VOID
-usage()
-{
-    register char   **dp;
-
-    fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION);
-    for (dp = usetxt; *dp; dp++)
-        fprintf(stderr, "%s\n", *dp);
-    lkexit(1);
-}
-
-/*)Function VOID    copyfile()
- *
- *      FILE    *dest           destination file
- *      FILE    *src            source file
- *
- *      function will copy source file to destination file
- *
- *
- *  functions called:
- *      int     fgetc()         c_library
- *      int     fputc()         c_library
- *
- *  side effects:
- *      none
- */
-VOID copyfile (dest,src)
-FILE *src,*dest ;
-{
-    int ch;
-    while ((ch = fgetc(src)) != EOF) {
-
-    fputc(ch,dest);
-    }
-}
diff --git a/as/mcs51/lkmem.c b/as/mcs51/lkmem.c
deleted file mode 100644 (file)
index 47fc14d..0000000
+++ /dev/null
@@ -1,613 +0,0 @@
-/*-------------------------------------------------------------------------
-  lkmem.c - Create a memory summary file with extension .mem
-
-   Written By -  Jesus Calvino-Fraga, jesusc@ieee.org (2002)
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
--------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "aslink.h"
-#include "strcmpi.h"
-
-int summary(struct area * areap)
-{
-    #define EQ(A,B) !as_strcmpi((A),(B))
-    #define MIN_STACK 16
-    #define REPORT_ERROR(A, H) \
-    {\
-        fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
-        fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
-        toreturn=1; \
-    }
-
-    #define REPORT_WARNING(A, H) \
-    { \
-        fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
-        fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
-    }
-
-    char buff[128];
-    int j, toreturn=0;
-    unsigned int Total_Last=0, k;
-
-    struct area * xp;
-    FILE * of;
-
-    /*Artifacts used for printing*/
-    char start[15], end[15], size[15], max[15];
-    char format[]="   %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
-    char line[]="---------------------";
-
-    typedef struct
-    {
-        unsigned long Start;
-        unsigned long Size;
-        unsigned long Max;
-        char Name[NCPS];
-        unsigned long flag;
-    } _Mem;
-
-    unsigned int dram[0x100];
-    _Mem Ram[]={
-        {0,     8,  8,   "REG_BANK_0", 0x0001},
-        {0x8,   8,  8,   "REG_BANK_1", 0x0002},
-        {0x10,  8,  8,   "REG_BANK_2", 0x0004},
-        {0x18,  8,  8,   "REG_BANK_3", 0x0008},
-        {0x20,  0,  16,  "BSEG_BYTES", 0x0010},
-        {0,     0,  128, "UNUSED",     0x0000},
-        {0x7f,  0,  128, "DATA",       0x0020},
-        {0,     0,  128, "TOTAL:",     0x0000}
-    };
-
-    _Mem IRam= {0xff,   0,   128, "INDIRECT RAM",       0x0080};
-    _Mem Stack={0xff,   0,     1, "STACK",              0x0000};
-    _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM",       0x0100};
-    _Mem Rom=  {0xffff, 0, 65536, "ROM/EPROM/FLASH",    0x0200};
-
-    if(stacksize==0) stacksize=MIN_STACK;
-
-    if(rflag) /*For the DS390*/
-    {
-        XRam.Max=0x1000000; /*24 bits*/
-        XRam.Start=0xffffff;
-        Rom.Max=0x1000000;
-        Rom.Start=0xffffff;
-    }
-
-    if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
-    {
-        Ram[5].Max=0x80;
-        Ram[6].Max=0x80;
-        Ram[7].Max=0x80;
-        IRam.Max=0x80;
-        iram_size=0x100;
-    }
-    else if(iram_size<0x80)
-    {
-        Ram[5].Max=iram_size;
-        Ram[6].Max=iram_size;
-        Ram[7].Max=iram_size;
-        IRam.Max=0;
-    }
-    else
-    {
-        Ram[5].Max=0x80;
-        Ram[6].Max=0x80;
-        Ram[7].Max=0x80;
-        IRam.Max=iram_size-0x80;
-    }
-
-    for(j=0; j<(int)iram_size; j++) dram[j]=0;
-    for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
-
-    /* Open Memory Summary File*/
-    of = afile(linkp->f_idp, "mem", 1);
-    if (of == NULL)
-    {
-        lkexit(1);
-    }
-
-    xp=areap;
-    while (xp)
-    {
-        /**/ if (EQ(xp->a_id, "REG_BANK_0"))
-        {
-            Ram[0].Size=xp->a_size;
-        }
-        else if (EQ(xp->a_id, "REG_BANK_1"))
-        {
-            Ram[1].Size=xp->a_size;
-        }
-        else if (EQ(xp->a_id, "REG_BANK_2"))
-        {
-            Ram[2].Size=xp->a_size;
-        }
-        else if (EQ(xp->a_id, "REG_BANK_3"))
-        {
-            Ram[3].Size=xp->a_size;
-        }
-        else if (EQ(xp->a_id, "BSEG_BYTES"))
-        {
-            Ram[4].Size+=xp->a_size;
-        }
-        else if (EQ(xp->a_id, "BIT_BANK"))
-        {
-            Ram[4].Size+=xp->a_size;
-        }
-
-        else if(xp->a_flag & A_CODE)
-        {
-            if(xp->a_size>0)
-            {
-                Rom.Size+=xp->a_size;
-                if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
-            }
-        }
-
-        else if (EQ(xp->a_id, "SSEG"))
-        {
-            Stack.Size+=xp->a_size;
-            if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
-        }
-
-        else if(xp->a_flag & A_XDATA)
-        {
-            if(xp->a_size>0)
-            {
-                XRam.Size+=xp->a_size;
-                if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
-            }
-        }
-
-        else if (EQ(xp->a_id, "ISEG"))
-        {
-            IRam.Size+=xp->a_size;
-            if(xp->a_addr<IRam.Start) IRam.Start=xp->a_addr;
-        }
-
-        /*If is not a register bank, bit, stack, or idata, then it should be data*/
-        else if((xp->a_flag & (A_CODE|A_BIT|A_XDATA))==0)
-        {
-            if(xp->a_size)
-            {
-                Ram[6].Size+=xp->a_size;
-                if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
-            }
-        }
-
-        xp=xp->a_ap;
-    }
-
-    for(j=0; j<7; j++)
-        for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
-            dram[k]|=Ram[j].flag; /*Mark as used*/
-
-    for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
-        dram[k]|=IRam.flag; /*Mark as used*/
-
-    /*Compute the amount of unused memory in direct data Ram.  This is the
-    gap between the last register bank or bit segment and the data segment.*/
-    for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
-    Ram[5].Start=k+1;
-    Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
-
-    /*Compute the data Ram totals*/
-    for(j=0; j<7; j++)
-    {
-        if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
-        Ram[7].Size+=Ram[j].Size;
-    }
-    Total_Last=Ram[6].Size+Ram[6].Start-1;
-
-    /*Report the Ram totals*/
-    fprintf(of, "Direct Internal RAM:\n");
-    fprintf(of, format, "Name", "Start", "End", "Size", "Max");
-
-    for(j=0; j<8; j++)
-    {
-        if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
-        if((j!=5) || (Ram[j].Size>0))
-        {
-            sprintf(start, "0x%02lx", Ram[j].Start);
-            if(Ram[j].Size==0)
-                end[0]=0;/*Empty string*/
-            else
-                sprintf(end,  "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
-            sprintf(size, "%5lu", Ram[j].Size);
-            sprintf(max, "%5lu", Ram[j].Max);
-            fprintf(of, format, Ram[j].Name, start, end, size, max);
-        }
-    }
-
-    for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
-    {
-        if(dram[k]!=Ram[6].flag)
-        {
-            sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
-            REPORT_ERROR(buff, 1);
-            break;
-        }
-    }
-
-    if(Ram[4].Size>Ram[4].Max)
-    {
-        k=Ram[4].Size-Ram[4].Max;
-        sprintf(buff, "Insufficient bit addressable memory.  "
-                    "%d byte%s short.\n", k, (k==1)?"":"s");
-        REPORT_ERROR(buff, 1);
-    }
-
-    if(Ram[5].Size!=0)
-    {
-        sprintf(buff, "%ld bytes in data memory wasted.  "
-                    "SDCC link could use: --data-loc 0x%02lx\n",
-                    Ram[5].Size, Ram[6].Start-Ram[5].Size);
-        REPORT_WARNING(buff, 1);
-    }
-
-    if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
-    {
-        k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
-        sprintf(buff, "Insufficient space in data memory.   "
-                    "%d byte%s short.\n", k, (k==1)?"":"s");
-        REPORT_ERROR(buff, 1);
-    }
-
-    /*Report the position of the beginning of the stack*/
-    fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
-        rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
-
-    /*Check that the stack pointer is landing in a safe place:*/
-    if( (dram[Stack.Start] & 0x8000) == 0x8000 )
-    {
-        fprintf(of, ".\n");
-        sprintf(buff, "Stack set to unavailable memory.\n");
-        REPORT_ERROR(buff, 1);
-    }
-    else if(dram[Stack.Start])
-    {
-        fprintf(of, ".\n");
-        sprintf(buff, "Stack overlaps area ");
-        REPORT_ERROR(buff, 1);
-        for(j=0; j<7; j++)
-        {
-                        if(dram[Stack.Start]&Ram[j].flag)
-            {
-                sprintf(buff, "'%s'\n", Ram[j].Name);
-                break;
-            }
-        }
-        if(dram[Stack.Start]&IRam.flag)
-        {
-            sprintf(buff, "'%s'\n", IRam.Name);
-        }
-        REPORT_ERROR(buff, 0);
-    }
-    else
-    {
-        for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
-        fprintf(of, " with %d bytes available\n", k);
-        if ((int)k<stacksize)
-        {
-            sprintf(buff, "Only %d byte%s available for stack.\n",
-                k, (k==1)?"":"s");
-            REPORT_WARNING(buff, 1);
-        }
-    }
-
-    fprintf(of, "\nOther memory:\n");
-    fprintf(of, format, "Name", "Start", "End", "Size", "Max");
-    fprintf(of, format, line, line, line, line, line);
-
-    /*Report IRam totals:*/
-    if(IRam.Size==0)
-    {
-        start[0]=0;/*Empty string*/
-        end[0]=0;/*Empty string*/
-    }
-    else
-    {
-        sprintf(start, "0x%02lx", IRam.Start);
-        sprintf(end,  "0x%02lx", IRam.Size+IRam.Start-1);
-    }
-    sprintf(size, "%5lu", IRam.Size);
-    sprintf(max, "%5lu", IRam.Max);
-    fprintf(of, format, IRam.Name, start, end, size, max);
-
-    /*Report XRam totals:*/
-    if(XRam.Size==0)
-    {
-        start[0]=0;/*Empty string*/
-        end[0]=0;/*Empty string*/
-    }
-    else
-    {
-        sprintf(start, "0x%04lx", XRam.Start);
-        sprintf(end,  "0x%04lx", XRam.Size+XRam.Start-1);
-    }
-    sprintf(size, "%5lu", XRam.Size);
-    sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
-    fprintf(of, format, XRam.Name, start, end, size, max);
-
-    /*Report Rom/Flash totals:*/
-    if(Rom.Size==0)
-    {
-        start[0]=0;/*Empty string*/
-        end[0]=0;/*Empty string*/
-    }
-    else
-    {
-        sprintf(start, "0x%04lx", Rom.Start);
-        sprintf(end,  "0x%04lx", Rom.Size+Rom.Start-1);
-    }
-    sprintf(size, "%5lu", Rom.Size);
-    sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
-    fprintf(of, format, Rom.Name, start, end, size, max);
-
-    /*Report any excess:*/
-    if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
-    {
-        sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
-        REPORT_ERROR(buff, 1);
-    }
-    if( ((XRam.Start+XRam.Size)>XRam.Max) ||
-        (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
-    {
-        sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
-        REPORT_ERROR(buff, 1);
-    }
-    if( ((Rom.Start+Rom.Size)>Rom.Max) ||
-        (((int)Rom.Size>code_size)&&(code_size>=0)) )
-    {
-        sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
-        REPORT_ERROR(buff, 1);
-    }
-
-    fclose(of);
-    return toreturn;
-}
-
-extern char idatamap[]; //0:not used, 1:used
-
-
-int summary2(struct area * areap)
-{
-    #define EQ(A,B) !as_strcmpi((A),(B))
-
-    char buff[128];
-    int toreturn = 0;
-    unsigned int j;
-    unsigned long int Stack_Start=0, Stack_Size;
-
-    struct area * xp;
-    struct area * xstack_xp = NULL;
-    FILE * of;
-
-    /*Artifacts used for printing*/
-    char start[15], end[15], size[15], max[15];
-    char format[]="   %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
-    char line[]="---------------------";
-
-    typedef struct
-    {
-        unsigned long Start;
-        unsigned long End;
-        unsigned long Size;
-        unsigned long Max;
-        char Name[NCPS];
-        unsigned long flag;
-    } _Mem;
-
-    _Mem Stack={0xff,   0, 0,     1, "STACK",           0x0000};
-    _Mem Paged={0xff,   0, 0,   256, "PAGED EXT. RAM",  A_PAG};
-    _Mem XRam= {0xffff, 0, 0, 65536, "EXTERNAL RAM",    0x0100};
-    _Mem Rom=  {0xffff, 0, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
-
-    if(rflag) /*For the DS390*/
-    {
-        XRam.Max=0x1000000; /*24 bits*/
-        XRam.Start=0xffffff;
-        Rom.Max=0x1000000;
-        Rom.Start=0xffffff;
-    }
-
-    /* Open Memory Summary File*/
-    of = afile(linkp->f_idp, "mem", 1);
-    if (of == NULL)
-    {
-        lkexit(1);
-    }
-
-    xp=areap;
-    while (xp)
-    {
-        if(xp->a_flag & A_CODE)
-        {
-            if(xp->a_size)
-            {
-                Rom.Size += xp->a_size;
-                if(xp->a_addr < Rom.Start)
-                    Rom.Start = xp->a_addr;
-                if(xp->a_addr + xp->a_size > Rom.End)
-                    Rom.End = xp->a_addr + xp->a_size;
-            }
-        }
-
-        else if (EQ(xp->a_id, "SSEG"))
-        {
-            Stack.Size += xp->a_size;
-            if(xp->a_addr < Stack.Start)
-                Stack.Start = xp->a_addr;
-            if(xp->a_addr + xp->a_size > Stack.End)
-                Stack.End = xp->a_addr + xp->a_size;
-        }
-
-        else if (EQ(xp->a_id, "PSEG"))
-        {
-            Paged.Size += xp->a_size;
-            if(xp->a_addr < Paged.Start)
-                Paged.Start = xp->a_addr;
-            if(xp->a_addr + xp->a_size > Paged.End)
-                Paged.End = xp->a_addr + xp->a_size;
-        }
-
-        else if (EQ(xp->a_id, "XSTK"))
-        {
-            xstack_xp = xp;
-            Paged.Size += xp->a_size;
-            if(xp->a_addr < Paged.Start)
-                Paged.Start = xp->a_addr;
-            if(xp->a_addr + xp->a_size > Paged.End)
-                Paged.End = xp->a_addr + xp->a_size;
-        }
-
-        else if(xp->a_flag & A_XDATA)
-        {
-            if(xp->a_size)
-            {
-                XRam.Size += xp->a_size;
-                if(xp->a_addr < XRam.Start)
-                    XRam.Start = xp->a_addr;
-                if(xp->a_addr + xp->a_size > XRam.End)
-                    XRam.End = xp->a_addr + xp->a_size;
-            }
-        }
-
-        xp = xp->a_ap;
-    }
-
-    /*Report the Ram totals*/
-    fprintf(of, "Internal RAM layout:\n");
-    fprintf(of, "      0 1 2 3 4 5 6 7 8 9 A B C D E F");
-    for(j=0; j<256; j++)
-    {
-        if(j%16==0) fprintf(of, "\n0x%02x:|", j);
-        fprintf(of, "%c|", idatamap[j]);
-    }
-       fprintf(of, "\n0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute\n");
-
-    for(j=0; j<256; j++)
-    {
-        if(idatamap[j]=='S')
-        {
-            Stack_Start=j;
-            break;
-        }
-    }
-
-    for(j=Stack_Start, Stack_Size=0; j<((iram_size)?iram_size:256); j++)
-    {
-        if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_Size++;
-        else break;
-    }
-
-    xp=areap;
-    while (xp)
-    {
-        if(xp->a_unaloc>0)
-        {
-            fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
-                        " in internal RAM for area %s.",
-                        xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id);
-            toreturn=1;
-        }
-        xp=xp->a_ap;
-    }
-
-    /*Report the position of the begining of the stack*/
-    if(Stack_Start!=256)
-        fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
-            rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_Size);
-    else
-        fprintf(of, "\nI don't have a clue where the stack ended up! Sorry...");
-
-    /*Report about xstack*/
-    if (xstack_xp)
-    {
-        Stack_Start = xstack_xp->a_addr;
-        Stack_Size = xstack_xp->a_size;
-        fprintf(of, "\nXstack starts at: 0x%04lx with %ld bytes available.",
-            Stack_Start, Stack_Size);
-    }
-
-    fprintf(of, "\n\nOther memory:\n");
-    fprintf(of, format, "Name", "Start", "End", "Size", "Max");
-    fprintf(of, format, line, line, line, line, line);
-
-    /*Report Paged XRam totals:*/
-    if(Paged.Size==0)
-    {
-        start[0]=0;/*Empty string*/
-        end[0]=0;/*Empty string*/
-    }
-    else
-    {
-        sprintf(start, "0x%04lx", Paged.Start);
-        sprintf(end,  "0x%04lx", Paged.End-1);
-    }
-    sprintf(size, "%5lu", Paged.Size);
-    sprintf(max, "%5lu", xram_size<0 ? Paged.Max : xram_size<256 ? xram_size : 256);
-    fprintf(of, format, Paged.Name, start, end, size, max);
-
-    /*Report XRam totals:*/
-    if(XRam.Size==0)
-    {
-        start[0]=0;/*Empty string*/
-        end[0]=0;/*Empty string*/
-    }
-    else
-    {
-        sprintf(start, "0x%04lx", XRam.Start);
-        sprintf(end,  "0x%04lx", XRam.End-1);
-    }
-    sprintf(size, "%5lu", XRam.Size);
-    sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
-    fprintf(of, format, XRam.Name, start, end, size, max);
-
-    /*Report Rom/Flash totals:*/
-    if(Rom.Size==0)
-    {
-        start[0]=0;/*Empty string*/
-        end[0]=0;/*Empty string*/
-    }
-    else
-    {
-        sprintf(start, "0x%04lx", Rom.Start);
-        sprintf(end,  "0x%04lx", Rom.End-1);
-    }
-    sprintf(size, "%5lu", Rom.Size);
-    sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
-    fprintf(of, format, Rom.Name, start, end, size, max);
-
-    /*Report any excess:*/
-    if( ((XRam.End) > XRam.Max) ||
-        (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
-    {
-        sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
-        REPORT_ERROR(buff, 1);
-    }
-    if( ((Rom.End) > Rom.Max) ||
-        (((int)Rom.Size>code_size)&&(code_size>=0)) )
-    {
-        sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
-        REPORT_ERROR(buff, 1);
-    }
-
-    fclose(of);
-    return toreturn;
-}
diff --git a/as/mcs51/lknoice.c b/as/mcs51/lknoice.c
deleted file mode 100644 (file)
index 2cd6a91..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/* lknoice.c */
-
-/*
- * Extensions to CUG 292 linker ASLINK to produce NoICE debug files
- *
- * 31-Oct-1997 by John Hartman
- * 30-Jan-98 JLH add page to DefineNoICE for 8051
- *  2-Feb-98 JLH Allow optional .nest on local vars - C scoping rules...
- */
-
-#include <stdio.h>
-#include <setjmp.h>
-#include <string.h>
-#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 );
-static void DefineFile( char *name, Addr_T value, int page );
-static void DefineFunction( char *name, Addr_T value, int page );
-static void DefineStaticFunction( char *name, Addr_T value, int page );
-static void DefineEndFunction( Addr_T value, int page );
-static void DefineLine( char *lineString, Addr_T value, int page );
-static void PagedAddress( Addr_T value, int page );
-
-/*
- * Called from lstarea in lklist.c for each symbol.
- *
- * Generates appropriate NoICE commands into output file, if any is open
- *
- */
-void DefineNoICE( char *name, Addr_T value, int page )
-{
-       char token1[NCPS];                      /* parse for file.function.symbol */
-       char token2[NCPS];
-       char token3[NCPS];
-       //      char token4[NCPS];
-       char sep1, sep2;
-       int  j, level;
-
-       /* no output if file is not open */
-       if (jfp == NULL) return;
-
-        j = sscanf( name, "%[^.]%c%[^.]%c%s",
-                   token1, &sep1, token2, &sep2, token3 );
-        switch (j)
-       {
-               /* file.function.symbol, or file.function..SPECIAL */
-               case 5:
-                       DefineFile( token1, 0, 0 );
-                       if (token3[0] == '.')
-                       {
-                               if (strcmp( token3, ".FN" ) == 0)
-                               {
-                                       /* Global function */
-                                        DefineFunction( token2, value, page );
-                               }
-                               else if (strcmp( token3, ".SFN" ) == 0)
-                               {
-                                       /* Static (file-scope) function */
-                                       DefineStaticFunction( token2, value, page );
-                               }
-                               else if (strcmp( token3, ".EFN" ) == 0)
-                               {
-                                       /* End of function */
-                                        DefineEndFunction( value, page );
-                                }
-                       }
-                       else
-                       {
-                               /* Function-scope var. */
-                               DefineFunction( token2, 0, 0 );
-
-                                /* Look for optional level integer */
-                               j = sscanf( token3, "%[^.]%c%u", token1, &sep1, &level );
-                                if ((j == 3) && (level != 0))
-                                {
-                                       sprintf( &token1[ strlen(token1) ], "_%u", level );
-                               }
-                                       DefineScoped( token1, value, page );
-                        }
-                       break;
-
-               /* file.func. is illegal */
-               case 4:
-                       break;
-
-               /* either file.symbol or file.line# */
-               case 3:
-                       DefineFile( token1, 0, 0 );
-                       if ((token2[0] >= '0') && (token2[0] <= '9'))
-                       {
-                               /* Line number */
-                                DefineLine( token2, value, page );
-                        }
-                       else
-                       {
-                               /* File-scope symbol.  (Kill any function) */
-                               DefineEndFunction( 0, 0 );
-                                DefineScoped( token2, value, page );
-                        }
-                       break;
-
-               /* symbol. is illegal */
-               case 2:
-                       break;
-
-               /* just a symbol */
-               case 1:
-                        DefineGlobal( token1, value, page );
-                        break;
-       }
-}
-
-static char currentFile[NCPS];
-static char currentFunction[NCPS];
-
-/*
- * static function:
- * Define "name" as a global symbol
- */
-void DefineGlobal( char *name, Addr_T value, int page )
-{
-       fprintf( jfp, "DEF %s ", name );
-       PagedAddress( value, page );
-}
-
-/*
- * static function:
- * Define "name" as a static (scoped) symbol
- */
-void DefineScoped( char *name, Addr_T value, int page )
-{
-       fprintf( jfp, "DEFS %s ", name );
-       PagedAddress( value, page );
-}
-
-/*
- * static function:
- * Define "name" as the current file
- */
-void DefineFile( char *name, Addr_T value, int page )
-{
-       if (as_strcmpi( name, currentFile ) != 0)
-       {
-               strcpy( currentFile, name );
-               if (value != 0)
-               {
-                       fprintf( jfp, "FILE %s ", name );
-                       PagedAddress( value, page );
-               }
-               else
-               {
-                       fprintf( jfp, "FILE %s\n", name );
-               }
-       }
-}
-
-/*
- * static function:
- * Define "name" as the current function
- */
-void DefineFunction( char *name, Addr_T value, int page )
-{
-       if (as_strcmpi( name, currentFunction ) != 0)
-       {
-               strcpy( currentFunction, name );
-                if (value != 0)
-                {
-                        fprintf( jfp, "DEF %s ", name );
-                       PagedAddress( value, page );
-                        fprintf( jfp, "FUNC %s ", name );
-                       PagedAddress( value, page );
-                }
-                else
-                {
-                        fprintf( jfp, "FUNC %s\n", name );
-               }
-       }
-}
-
-/*
- * static function:
- * Define "name" as the current static (scoped) function
- */
-void DefineStaticFunction( char *name, Addr_T value, int page )
-{
-       if (as_strcmpi( name, currentFunction ) != 0)
-       {
-               strcpy( currentFunction, name );
-               if (value != 0)
-               {
-                        fprintf( jfp, "DEFS %s ", name );
-                       PagedAddress( value, page );
-                       fprintf( jfp, "SFUNC %s ", name );
-                       PagedAddress( value, page );
-               }
-               else
-               {
-                       fprintf( jfp, "SFUNC %s\n", name );
-               }
-       }
-}
-
-/*
- * static function:
- * Define the end of the current function
- */
-void DefineEndFunction( Addr_T value, int page )
-{
-       if (currentFunction[0] != 0)
-       {
-               if (value != 0)
-               {
-                       fprintf( jfp, "ENDF " );
-                       PagedAddress( value, page );
-               }
-               else
-               {
-                       fprintf( jfp, "ENDF\n" );
-               }
-
-               currentFunction[0] = 0;
-       }
-}
-
-/*
- * static function:
- * Define "lineNumber" as a line in the current file
- */
-void DefineLine( char *lineString, Addr_T value, int page )
-{
-       int indigit, lineNumber = 0;
-
-       while( (indigit=digit( *lineString++, 10 )) >= 0)
-       {
-               lineNumber = 10*lineNumber + indigit;
-       }
-       fprintf( jfp, "LINE %u ", lineNumber );
-        PagedAddress( value, page );
-}
-
-void PagedAddress( Addr_T value, int page )
-{
-       fprintf( jfp, "%X:0x%X\n", page, value );
-}
diff --git a/as/mcs51/lkrloc.c b/as/mcs51/lkrloc.c
deleted file mode 100644 (file)
index 2771ec5..0000000
+++ /dev/null
@@ -1,1523 +0,0 @@
-/* lkrloc.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * 29-Oct-97 JLH:
- *       - errdmp: show s_id as string rather than array [NCPS]
- *       - relr: add support for 11 bit 8051 addressing
- * 02-Apr-98 JLH: don't output empty hex records
- */
-
-#include <stdio.h>
-#include <string.h>
-#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[].
- *
- */
-
-/* Global which holds the upper 16 bits of the last 32 bit area adress
- * output. Useful only for iHex mode.
- */
-int    lastExtendedAddress=-1;
-
-/* Static variable which holds the index of last processed area.
- * Useful only for iHex mode.
- */
-static int lastAreaIndex = -1;
-
-/*)Function VOID    reloc(c)
- *
- *          char c      process code
- *
- *  The function reloc() calls a particular relocation
- *  function determined by the process code.
- *
- *  local variable:
- *      none
- *
- *  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
- *
- *  side effects:
- *      Refer to the called relocation functions.
- *
- */
-
-VOID reloc(char c)
-{
-    switch(c) {
-
-    case 'T':
-        relt();
-        break;
-
-    case 'R':
-        relr();
-        break;
-
-    case 'P':
-        relp();
-        break;
-
-    case 'E':
-        rele();
-        break;
-
-    default:
-        fprintf(stderr, "Undefined Relocation Operation\n");
-        lkerr++;
-        break;
-
-    }
-}
-
-
-/*)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.
- *
- *      T Line
- *
- *      T xx xx nn nn nn nn nn ...
- *
- *
- *      In: "T n0 n1 n2 n3 ... nn"
- *
- *      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.
- *
- *  local variable:
- *      none
- *
- *  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
- *
- *  side effects:
- *      Linker input T line evaluated.
- *
- */
-
-VOID relt(VOID)
-{
-    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.
- *
- */
-
-VOID relr(VOID)
-{
-    register int mode;
-    register Addr_T reli, relv;
-    int aindex, rindex, rtp, error;
-    Addr_T r, rtbase, rtofst, paga, pags, 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);
-
-    #if 0
-    printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
-        a[aindex]->a_addr, a[aindex]->a_size, rtbase);
-    #endif
-    /*
-     * Do remaining relocations
-     */
-    while (more()) {
-        error = 0;
-        mode = eval();
-
-        if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
-        {
-            mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
-            /* printf("unescaping rmode\n"); */
-        }
-
-        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_BYT3)
-            {
-                /* This is a three byte address, of which
-                 * we will select one byte.
-                 */
-                if (mode & R_BIT)
-                {
-                    relv = adb_24_bit(reli, rtp);
-                }
-                else if (mode & R_HIB)
-                {
-                    /* printf("24 bit address selecting hi byte.\n"); */
-                    relv = adb_24_hi(reli, rtp);
-                }
-                else if (mode & R_MSB)
-                {
-                    /* Note that in 24 bit mode, R_MSB
-                     * is really the middle byte, not
-                     * the most significant byte.
-                     *
-                     * This is ugly and I can only apologize
-                     * for any confusion.
-                     */
-                    /* printf("24 bit address selecting middle byte.\n"); */
-                    relv = adb_24_mid(reli, rtp);
-                }
-                else
-                {
-                    /* printf("24 bit address selecting lo byte.\n"); */
-                    relv = adb_24_lo(reli, rtp);
-                }
-            }
-            else if (mode & R_BYT2) {
-                /* This is a two byte address, of
-                 * which we will select one byte.
-                 */
-                if (mode & R_BIT) {
-                    relv = adb_bit(reli, rtp);
-                } else if (mode & R_MSB) {
-                    relv = adb_hi(reli, rtp);
-                } else {
-                    relv = adb_lo(reli, rtp);
-                }
-            } else {
-                relv = adb_b(reli, rtp);
-            }
-        } else if (IS_R_J11(mode)) {
-            /* JLH: 11 bit jump destination for 8051.  Forms
-            /  two byte instruction with op-code bits
-            /  in the MIDDLE!
-            /  rtp points at 3 byte locus: first two
-            /  will get the instructiion. third one
-            /  has raw op-code.
-            */
-
-            /* Calculate absolute destination
-            /  relv must be on same 2K page as pc
-            */
-            relv = adw_w(reli, rtp);
-
-            if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) {
-                    error = 2;
-            }
-
-            /* Merge MSB (byte 0) with op-code, ignoring
-            /  top 5 bits of address.  Then hide the op-code
-            */
-            rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
-            rtflg[rtp+2] = 0;
-            rtofst += 1;
-        }
-        else if (IS_R_J19(mode)) {
-            /* 19 bit jump destination for DS80C390.  Forms
-            /  three byte instruction with op-code bits
-            /  in the MIDDLE!
-            /  rtp points at 4 byte locus: first three
-            /  will get the instructiion. fourth one
-            /  has raw op-code.
-             */
-
-            /* Calculate absolute destination
-            /  relv must be on same 512K page as pc
-            */
-            relv = adw_24(reli, rtp);
-
-            if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) {
-                error = 2;
-            }
-
-            /* Merge MSB (byte 0) with op-code, ignoring
-            /  top 5 bits of address.  Then hide the op-code
-            */
-            rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
-            rtflg[rtp+3] = 0;
-            rtofst += 1;
-        }
-        else if (IS_C24(mode))
-        {
-            /* 24 bit address */
-            relv = adw_24(reli, rtp);
-            }
-        else
-        {
-            /* 16 bit address. */
-            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;
-        if ((mode & R_BIT) && (relv & ~0x87FF))
-            error = 5;
-
-        /*
-         * 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);
-    }
-
-    /* JLH: output only if data (beyond two byte address) */
-    if ((oflag == 1) && (rtcnt > 2)) {
-        int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff;
-
-        /* Boy, is this a hack: for ABS sections, the
-         * base address is stored as zero, and the T records
-         * indicate the offset from zero.
-         *
-         * Since T records can only indicate a 16 bit offset, this
-         * obviously creates a problem for ABS segments located
-         * above 64K (this is only meaningful in flat24 mode).
-         *
-         * However, the size of an ABS area is stored as
-         * base address + section size (I suspect this is a bug,
-         * but it's a handy one right now). So the upper 8 bits of
-         * the 24 bit address are stored in the size record.
-         * Thus we add it in.
-         *
-         * This is another reason why we can't have areas greater
-         * than 64K yet, even in flat24 mode.
-         */
-    //  extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
-    //  commented out by jr
-
-        if (lastAreaIndex != aindex) {
-            lastAreaIndex = aindex;
-            newArea();
-        }
-
-        if (extendedAddress != lastExtendedAddress)
-        {
-
-            if (lastExtendedAddress!=-1) {
-              printf("output extended linear address record 0x%x 0x%x\n",
-                 extendedAddress, lastExtendedAddress);
-            }
-
-            if (rflag)
-            {
-                ihxEntendedLinearAddress(extendedAddress);
-            }
-            else if (extendedAddress)
-            {
-                /* Not allowed to generate extended address records,
-                 * but one is called for here...
-                 */
-                fprintf(stderr,
-                    "warning: extended linear address encountered; "
-                    "you probably want the -r flag.\n");
-            }
-            lastExtendedAddress = extendedAddress;
-        }
-        ihx(1);
-    } else
-    if ((oflag == 2) && (rtcnt > 2)) {
-        s19(1);
-    }
-}
-
-char *errmsg[] = {
-    "Unsigned Byte error",
-    "Byte PCR relocation error",
-    "Page0 relocation error",
-    "Page Mode relocation error",
-    "Bit-addressable 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.
- *
- */
-
-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");
-}
-
-/*)Function VOID    rele()
- *
- *  The function rele() closes all open output files
- *  at the end of the linking process.
- *
- *  local variable:
- *      none
- *
- *  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
- *
- *  side effects:
- *      All open output files are closed.
- *
- */
-
-VOID rele(VOID)
-{
-    if (uflag != 0) {
-        lkulist(0);
-    }
-    if (oflag == 1) {
-        ihx(0);
-    } else
-    if (oflag == 2) {
-        s19(0);
-    }
-}
-
-/*)Function Addr_T      evword()
- *
- *  The function evword() combines two byte values
- *  into a single word value.
- *
- *  local variable:
- *      Addr_T  v       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      int eval()      lkeval.c
- *
- *  side effects:
- *      Relocation text line is scanned to combine
- *      two byte values into a single word value.
- *
- */
-
-Addr_T evword(VOID)
-{
-    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)
- *
- *      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.
- *
- *  local variable:
- *      none
- *
- *  global variables:
- *      none
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *
- */
-
-Addr_T adb_b(register Addr_T v, register int i)
-{
-    return(rtval[i] += v);
-}
-
-/*)Function Addr_T      adb_bit(v, i)
- *
- *      int v       value to add to byte
- *      int i       rtval[] index
- *
- *  The function adb_bit() converts the single
- *  byte address value contained in rtval[i] to bit-
- *  addressable space and adds the value of v to it.
- *  The new value of rtval[i] is returned.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      none
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *
- */
-
-Addr_T adb_bit(register Addr_T v, register int i)
-{
-    register Addr_T j;
-
-    j = adb_lo(v, i) & 0xFF;
-    if ((j >= 0x20) && (j <= 0x2F)) {
-        j = (j - 0x20) * 8;
-    } else if ((j < 0x80) || ((j & 0x07) != 0)) {
-        return(0x100);//error
-    }
-
-    if (hilo) {
-        j = rtval[i+1] = j + (rtval[i] & 0x07);
-    } else {
-        j = rtval[i] = j + (rtval[i+1] & 0x07);
-    }
-    return(j);
-}
-
-/*)Function Addr_T      adb_lo(v, i)
- *
- *      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.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  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.
- *
- */
-
-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);
-}
-
-/*)Function Addr_T      adb_hi(v, i)
- *
- *      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.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  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.
- *
- */
-
-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);
-}
-
-/*)Function Addr_T      adb_24_bit(v, i)
- *
- *      int v       value to add to byte
- *      int i       rtval[] index
- *
- *  The function adb_24_bit() converts the single
- *  byte address value contained in rtval[i] to bit-
- *  addressable space and adds the value of v to it.
- *  The new value of rtval[i] is returned.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      none
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *
- */
-
-Addr_T adb_24_bit(register Addr_T v, register int i)
-{
-    register Addr_T j;
-
-    j = adb_24_lo(v, i) & 0xFF;
-    if ((j >= 0x20) && (j <= 0x2F)) {
-        j = (j - 0x20) * 8;
-    } else if ((j < 0x80) || ((j & 0x07) != 0)) {
-        return(0x100);//error
-    }
-
-    if (hilo) {
-        j = rtval[i+2] = j + (rtval[i+1] & 0x07);
-    } else {
-        j = rtval[i] = j + (rtval[i+1] & 0x07);
-    }
-    return(j);
-}
-
-/*)Function Addr_T      adb_24_hi(v, i)
- *
- *      int v       value to add to byte
- *      int i       rtval[] index
- *
- *  The function adb_24_hi() adds the value of v to the
- *  24 bit value contained in rtval[i] - rtval[i+2].
- *  The new value of rtval[i] / rtval[i+1] is returned.
- *  The LSB & middle byte rtflg[] is cleared.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *      The rtflg[] value corresponding to the
- *      LSB & middle byte of the word value is cleared to
- *      reflect the fact that the MSB is the selected byte.
- *
- */
-
-Addr_T adb_24_hi(Addr_T v, int i)
-{
-    register Addr_T j;
-
-    j = adw_24(v, i);
-
-    /* Remove the lower two bytes. */
-    if (hilo)
-    {
-        rtflg[i+2] = 0;
-    }
-    else
-    {
-        rtflg[i] = 0;
-    }
-    rtflg[i+1] = 0;
-
-    return (j);
-}
-
-/*)Function Addr_T      adb_24_mid(v, i)
- *
- *      int v       value to add to byte
- *      int i       rtval[] index
- *
- *  The function adb_24_mid() adds the value of v to the
- *  24 bit value contained in rtval[i] - rtval[i+2].
- *  The new value of rtval[i] / rtval[i+1] is returned.
- *  The LSB & MSB byte rtflg[] is cleared.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *      The rtflg[] value corresponding to the
- *      LSB & MSB of the 24 bit value is cleared to reflect
- *      the fact that the middle byte is the selected byte.
- *
- */
-
-Addr_T adb_24_mid(Addr_T v, int i)
-{
-    register Addr_T j;
-
-    j = adw_24(v, i);
-
-    /* remove the MSB & LSB. */
-    rtflg[i+2] = 0;
-    rtflg[i] = 0;
-
-    return (j);
-}
-
-/*)Function Addr_T      adb_24_lo(v, i)
- *
- *      int v       value to add to byte
- *      int i       rtval[] index
- *
- *  The function adb_24_lo() adds the value of v to the
- *  24 bit value contained in rtval[i] - rtval[i+2].
- *  The new value of rtval[i] / rtval[i+1] is returned.
- *  The MSB & middle byte rtflg[] is cleared.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *      The rtflg[] value corresponding to the
- *      MSB & middle byte  of the word value is cleared to
- *      reflect the fact that the LSB is the selected byte.
- *
- */
-
-Addr_T adb_24_lo(Addr_T v, int i)
-{
-    register Addr_T j;
-
-    j = adw_24(v, i);
-
-    /* Remove the upper two bytes. */
-    if (hilo)
-    {
-        rtflg[i] = 0;
-    }
-    else
-    {
-        rtflg[i+2] = 0;
-    }
-    rtflg[i+1] = 0;
-
-    return (j);
-}
-
-/*)Function Addr_T      adw_w(v, i)
- *
- *      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.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The word value of rtval[] is changed.
- *
- */
-
-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);
-}
-
-/*)Function Addr_T      adw_24(v, i)
- *
- *      int v       value to add to word
- *      int i       rtval[] index
- *
- *  The function adw_w() adds the value of v to the
- *  24 bit value contained in rtval[i] - rtval[i+2].
- *  The new value of rtval[i] - rtval[i+2] is returned.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The word value of rtval[] is changed.
- *
- */
-Addr_T adw_24(Addr_T v, int i)
-{
-    register Addr_T j;
-
-    if (hilo) {
-        j = v + ((rtval[i] & 0xff) << 16)
-              + ((rtval[i+1] & 0xff) << 8)
-              + (rtval[i+2] & 0xff);
-        rtval[i] = (j >> 16) & 0xff;
-        rtval[i+1] = (j >> 8) & 0xff;
-        rtval[i+2] = j & 0xff;
-    } else {
-        j = v + (rtval[i] & 0xff)
-              + ((rtval[i+1] & 0xff) << 8)
-              + ((rtval[i+2] & 0xff) << 16);
-        rtval[i] = j & 0xff;
-        rtval[i+1] = (j >> 8) & 0xff;
-        rtval[i+2] = (j >> 16) & 0xff;
-    }
-    return(j);
-}
-
-/*)Function Addr_T      adw_lo(v, i)
- *
- *      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.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  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.
- *
- */
-
-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);
-}
-
-/*)Function Addr_T      adw_hi(v, i)
- *
- *      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.
- *
- *  local variable:
- *      Addr_T  j       temporary evaluation variable
- *
- *  global variables:
- *      hilo            byte ordering parameter
- *
- *  called functions:
- *      none
- *
- *  side effects:
- *      The value of rtval[] is changed.
- *      The MSB and LSB values are interchanged and
- *      then the MSB cleared.
- *
- */
-
-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);
-}
-
-/*)Function VOID    relerr(str)
- *
- *      char    *str        error string
- *
- *  The function relerr() outputs the error string to
- *  stderr and to the map file (if it is open).
- *
- *  local variable:
- *      none
- *
- *  global variables:
- *      FILE    *mfp        handle for the map file
- *
- *  called functions:
- *      VOID    errdmp()    lkrloc.c
- *
- *  side effects:
- *      Error message inserted into map file.
- *
- */
-
-VOID relerr(char *str)
-{
-    errdmp(stderr, str);
-    if (mfp)
-        errdmp(mfp, str);
-}
-
-/*)Function VOID    errdmp(fptr, str)
- *
- *      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.
- *
- *  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
- *
- *  called functions:
- *      int fprintf()   c_library
- *      VOID    prntval()   lkrloc.c
- *
- *  side effects:
- *      Error reported.
- *
- */
-
-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",
-            &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)
- *
- *      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.
- *
- *  local variable:
- *      none
- *
- *  global variables:
- *      int xflag       current radix
- *
- *  called functions:
- *      int fprintf()   c_library
- *
- *  side effects:
- *      none
- *
- */
-
-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);
-    }
-}
-
-/*)Function VOID    relerp(str)
- *
- *      char    *str        error string
- *
- *  The function relerp() outputs the paging error string to
- *  stderr and to the map file (if it is open).
- *
- *  local variable:
- *      none
- *
- *  global variables:
- *      FILE    *mfp        handle for the map file
- *
- *  called functions:
- *      VOID    erpdmp()    lkrloc.c
- *
- *  side effects:
- *      Error message inserted into map file.
- *
- */
-
-VOID relerp(char *str)
-{
-    erpdmp(stderr, str);
-    if (mfp)
-        erpdmp(mfp, str);
-}
-
-/*)Function VOID    erpdmp(fptr, str)
- *
- *      FILE    *fptr       output file handle
- *      char    *str        error string
- *
- *  The function erpdmp() outputs the error string str
- *  to the device specified by fptr.
- *
- *  local variable:
- *      head    *thp        pointer to head structure
- *
- *  global variables:
- *      int     lkerr       error flag
- *      sdp     sdp         base page structure
- *
- *  called functions:
- *      int fprintf()       c_library
- *      VOID    prntval()   lkrloc.c
- *
- *  side effects:
- *      Error reported.
- *
- */
-
-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);
-}
diff --git a/as/mcs51/lks19.c b/as/mcs51/lks19.c
deleted file mode 100644 (file)
index 26d8892..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* lks19.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "aslink.h"
-
-/*)Module      lks19.c
- *
- *     The module lks19.c contains the function to
- *     output the relocated object code in the
- *     Motorola S19 format.
- *
- *     lks19.c contains the following function:
- *             VOID    s19(i)
- *
- *     lks19.c contains no local variables.
- */
-
-/*)S19 Format
- *      Record Type Field    -  This  field  signifies  the  start  of a
- *                              record and  identifies  the  the  record
- *                              type as follows:  
- *
- *                                  Ascii S1 - Data Record 
- *                                  Ascii S9 - End of File Record 
- *
- *      Record Length Field  -  This  field  specifies the record length
- *                              which includes the  address,  data,  and
- *                              checksum   fields.   The  8  bit  record
- *                              length value is converted to  two  ascii
- *                              characters, high digit first.  
- *
- *      Load Address Field   -  This  field  consists  of the four ascii
- *                              characters which result from  converting
- *                              the  the  binary value of the address in
- *                              which to begin loading this record.  The
- *                              order is as follows:  
- *
- *                                  High digit of high byte of address. 
- *                                  Low digit of high byte of address.  
- *                                  High digit of low byte of address.  
- *                                  Low digit of low byte of address.  
- *
- *                              In an End of File record this field con-
- *                              sists of either four ascii zeros or  the
- *                              program  entry  address.   Currently the
- *                              entry address option is not supported.  
- *
- *      Data Field           -  This  field consists of the actual data,
- *                              converted to two ascii characters,  high
- *                              digit first.  There are no data bytes in
- *                              the End of File record.  
- *
- *      Checksum Field       -  The  checksum  field is the 8 bit binary
- *                              sum of the record length field, the load
- *                              address field, and the data field.  This
- *                              sum is then  complemented  (1's  comple-
- *                              ment)   and   converted   to  two  ascii
- *                              characters, high digit first.  
- */
-
-/*)Function    s19(i)
- *
- *             int     i               0 - process data
- *                                     1 - end of data
- *
- *     The function s19() outputs the relocated data
- *     in the standard Motorola S19 format.
- *
- *     local variables:
- *             Addr_T  chksum          byte checksum
- *
- *     global variables:
- *             int     hilo            byte order
- *             FILE *  ofp             output file handle
- *             int     rtcnt           count of data words
- *             int     rtflg[]         output the data flag
- *             Addr_T  rtval[]         relocated data
- *
- *     functions called:
- *             int     fprintf()       c_library
- *
- *     side effects:
- *             The data is output to the file defined by ofp.
- */
-
-VOID
-s19(i)
-{
-       register Addr_T chksum;
-
-       if (i) {
-               if (hilo == 0) {
-                       chksum = rtval[0];
-                       rtval[0] = rtval[1];
-                       rtval[1] = chksum;
-               }
-               for (i = 0, chksum = 1; i < rtcnt; i++) {
-                       if (rtflg[i])
-                               chksum++;
-               }
-               fprintf(ofp, "S1%02X", chksum);
-               for (i = 0; i < rtcnt ; i++) {
-                       if (rtflg[i]) {
-                               fprintf(ofp, "%02X", rtval[i]);
-                               chksum += rtval[i];
-                       }
-               }
-               fprintf(ofp, "%02X\n", (0-chksum-1) & 0xff);
-       } else {
-               fprintf(ofp, "S9030000FC\n");
-       }
-}
diff --git a/as/mcs51/lkstore.c b/as/mcs51/lkstore.c
deleted file mode 100644 (file)
index 063e89c..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* lkstore.c */
-
-/* 
- * Allocated string storage module.
- *
- * 31-Oct-1997 by John Hartman
- */
-
-#include <stdio.h>
-#include <setjmp.h>
-#include <string.h>
-#include "aslink.h"
-
-/*
- * Allocate space for "str", copy str into new space
- * Return a pointer to the allocated name, or NULL if out of memory
- */
-char *StoreString( char *str )
-{
-   /* To avoid wasting memory headers on small allocations, we
-   /  allocate a big chunk and parcel it out as required.
-   /  These static variables remember our hunk
-   */
-   #define STR_STORE_HUNK 2000
-   static char *pNextFree = NULL;
-   static int  bytesLeft = 0;
-   
-   int  length;
-   char *pStoredString;
-   
-   length = strlen( str ) + 1; /* what we need, including null */
-
-   if (length > bytesLeft)
-   {
-      /* no space.  Allocate a new hunk.  We lose the pointer to any
-      /  old hunk.  We don't care, as the names are never deleted.
-      */
-      pNextFree = (char*)new( STR_STORE_HUNK );
-      bytesLeft = STR_STORE_HUNK;
-   }
-
-   /* Copy the name and terminating null into the name store */
-   pStoredString = pNextFree;
-   memcpy( pStoredString, str, length );
-
-   pNextFree += length;
-   bytesLeft -= length;
-
-   return pStoredString;
-}
diff --git a/as/mcs51/lksym.c b/as/mcs51/lksym.c
deleted file mode 100644 (file)
index 1ebc49c..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/* lksym.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
- * 28-Oct-97 JLH: 
- *          - lkpsym: Use StoreString for sym construction
- *          - change symeq() to do length-independent string compare
- *          - change hash() to do length-independent hash calculation
- */
-
-#include <stdio.h>
-#include <string.h>
-#if defined(_MSC_VER)
-#include <malloc.h>
-#else
-#include <alloc.h>
-#endif
-#include "aslink.h"
-
-/*)Module      lksym.c
- *
- *     The module lksym.c contains the functions that operate
- *     on the symbol structures.
- *
- *     lksym.c contains the following functions:
- *             int     hash()
- *             sym *   lkpsym()
- *             VOID *  new()
- *             sym *   newsym()
- *             VOID    symdef()
- *             int     symeq()
- *             VOID    syminit()
- *             VOID    symmod()
- *             Addr_T  symval()
- *
- *     lksym.c contains no local/static variables.
- */
-
-/*)Function    VOID    syminit()
- *
- *     The function syminit() is called to clear the hashtable.
- *
- *     local variables:
- *             int     h               computed hash value
- *             sym **  spp             pointer to an array of
- *                                     sym structure pointers
- *
- *     global variables:
- *             sym * symhash[]         array of pointers to NHASH
- *                                     linked symbol lists
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             (1)     The symbol hash tables are cleared
- */
-
-VOID
-syminit()
-{
-    // register int h;
-       struct sym **spp;
-
-       spp = &symhash[0];
-       while (spp < &symhash[NHASH])
-               *spp++ = NULL;
-}
-
-/*)Function    sym *   newsym()
- *
- *     The function newsym() is called to evaluate the symbol
- *     definition/reference directive from the .rel file(s).
- *     If the symbol is not found in the symbol table a new
- *     symbol structure is created.  Evaluation of the
- *     directive determines if this is a reference or a definition.
- *     Multiple definitions of the same variable will be flagged
- *     as an error if the values are not identical.  A symbol
- *     definition places the symbol value and area extension
- *     into the symbols data structure.  And finally, a pointer
- *     to the symbol structure is placed into the head structure
- *     symbol list.  Refer to the description of the header, symbol,
- *     area, and areax structures in lkdata.c for structure and
- *     linkage details.
- *
- *     local variables:
- *             int     c               character from input text
- *             int     i               evaluation value
- *             char    id[]            symbol name
- *             int     nglob           number of symbols in this header
- *             sym *   tsp             pointer to symbol structure
- *             sym **  s               list of pointers to symbol structures
- *
- *     global variables:
- *             areax   *axp            Pointer to the current
- *                                     areax structure
- *             head    *headp          The pointer to the first
- *                                     head structure of a linked list
- *             int     lkerr           error flag
- *
- *     functions called:
- *             Addr_T  eval()          lkeval.c
- *             VOID    exit()          c_library
- *             int     fprintf()       c_library
- *             char    getSid()        lklex.c
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             sym *   lkpsym()        lksym.c
- *
- *     side effects:
- *             A symbol structure is created and/or modified.
- *             If structure space allocation fails linker will abort.
- *             Several severe errors (these are internal errors
- *             indicating a corrupted .rel file or corrupted
- *             assembler or linker) will terminated the linker.
- */
-
-/*
- * Find/Create a global symbol entry.
- *
- * S xxxxxx Defnnnn
- *   |      |  |
- *   |      |  `-- sp->s_addr
- *   |      `----- sp->s_type
- *   `------------ sp->s_id
- *
- */
-struct sym *
-newsym()
-{
-  register unsigned i ;
-  register unsigned nglob ;
-       register int c ;
-       struct sym *tsp;
-       struct sym **s;
-       char id[NCPS];
-
-       getSid(id);     // old: getid(id, -1);
-       tsp = lkpsym(id, 1);
-       c = getnb();get();get();
-       if (c == 'R') {
-               tsp->s_type |= S_REF;
-               if (eval()) {
-                       fprintf(stderr, "Non zero S_REF\n");
-                       lkerr++;
-               }
-       } else
-       if (c == 'D') {
-               i = eval();
-               if (tsp->s_type & S_DEF && tsp->s_addr != i) {
-                       fprintf(stderr, "Multiple definition of %8s\n", id);
-                       lkerr++;
-               }
-               tsp->s_type |= S_DEF;
-               /*
-                * Set value and area extension link.
-                */
-               tsp->s_addr = i;
-               tsp->s_axp = axp;
-       } else {
-               fprintf(stderr, "Invalid symbol type %c for %8s\n", c, id);
-               lkexit(1);
-       }
-       /*
-        * Place pointer in header symbol list
-        */
-       if (headp == NULL) {
-               fprintf(stderr, "No header defined\n");
-               lkexit(1);
-       }
-       nglob = hp->h_nglob;
-       s = hp->s_list;
-       for (i=0; i < nglob ;++i) {
-               if (s[i] == NULL) {
-                       s[i] = tsp;
-                       return(tsp);
-               }
-       }
-       fprintf(stderr, "Header symbol list overflow\n");
-       lkexit(1);
-       return(0);
-}
-
-/*)Function    sym *   lkpsym(id,f)
- *
- *             char *  id              symbol name string
- *             int     f               f == 0, lookup only
- *                                     f != 0, create if not found
- *
- *     The function lookup() searches the symbol hash tables for
- *     a symbol name match returning a pointer to the sym structure.
- *     If the symbol is not found then a sym structure is created,
- *     initialized, and linked to the appropriate hash table if f != 0.
- *     A pointer to this new sym structure is returned or a NULL
- *     pointer is returned if f == 0.
- *
- *     local variables:
- *             int     h               computed hash value
- *             sym *   sp              pointer to a sym structure
- *
- *     global varaibles:
- *             sym * symhash[]         array of pointers to NHASH
- *                                     linked symbol lists
- *
- *     functions called:
- *             int     hash()          lksym.c
- *             VOID *  new()           lksym.c
- *             int     symeq()         lksym.c
- *
- *     side effects:
- *             If the function new() fails to allocate space
- *             for the new sym structure the linker terminates.
- */
-
-struct sym *
-lkpsym(id, f)
-char *id;
-{
-       register struct sym *sp;
-       register int h;
-
-       h = hash(id);
-       sp = symhash[h];
-       while (sp != NULL) {
-               if (symeq(id, sp->s_id))
-                       return (sp);
-               sp = sp->s_sp;
-       }
-       if (f == 0)
-               return (NULL);
-       sp = (struct sym *) new (sizeof(struct sym));
-       sp->s_sp = symhash[h];
-       symhash[h] = sp;
-       sp->s_id = StoreString( id );   /* JLH */
-       return (sp);
-}
-
-/*)Function    Addr_T  symval(tsp)
- *
- *             sym *   tsp             pointer to a symbol structure
- *
- *     The function symval() returns the value of the
- *     relocated symbol by adding the variable definition
- *     value to the areax base address.
- *
- *     local variables:
- *             Addr_T  val             relocated address value
- *
- *     global variables:
- *             none
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-
-Addr_T
-symval(tsp)
-register struct sym *tsp;
-{
-       register Addr_T val;
-
-       val = tsp->s_addr;
-       if (tsp->s_axp) {
-               val += tsp->s_axp->a_addr;
-       }
-       return(val);
-}
-
-/*)Function    VOID    symdef(fp)
- *
- *             FILE *  fp              file handle for output
- *
- *     The function symdef() scans the hashed symbol table
- *     searching for variables referenced but not defined.
- *     Undefined variables are linked to the default
- *     area "_CODE" and reported as referenced by the
- *     appropriate module.
- *
- *     local variables:
- *             int     i               hash table index loop variable
- *             sym *   sp              pointer to linked symbol structure
- *
- *     global variables:
- *             area    *areap          The pointer to the first
- *                                     area structure of a linked list
- *             sym *symhash[NHASH]     array of pointers to NHASH
- *                                     linked symbol lists
- *
- *     functions called:
- *             symmod()                lksym.c
- *
- *     side effects:
- *             Undefined variables have their areas set to "_CODE".
- */
-
-VOID
-symdef(fp)
-FILE *fp;
-{
-       register struct sym *sp;
-       register int i;
-
-       for (i=0; i<NHASH; ++i) {
-               sp = symhash[i];
-               while (sp) {
-                       if (sp->s_axp == NULL)
-                               sp->s_axp = areap->a_axp;
-                       if ((sp->s_type & S_DEF) == 0)
-                               symmod(fp, sp);
-                       sp = sp->s_sp;
-               }
-       }
-}
-
-/*)Function    VOID    symmod(fp,tsp)
- *
- *             FILE *  fp              output file handle
- *             sym *   tsp             pointer to a symbol structure
- *
- *     The function symmod() scans the header structures
- *     searching for a reference to the symbol structure
- *     pointer to by tsp.  The function then generates an error
- *     message whichs names the module having referenced the
- *     undefined variable.
- *
- *     local variables:
- *             int     i               loop counter
- *             sym **  p               pointer to a list of pointers
- *                                     to symbol structures
- *
- *     global variables:
- *             head    *headp          The pointer to the first
- *                                     head structure of a linked list
- *             head    *hp             Pointer to the current
- *                                     head structure
- *             int     lkerr           error flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *
- *     side effects:
- *             Error output generated.
- */
-
-VOID
-symmod(fp, tsp)
-FILE *fp;
-struct sym *tsp;
-{
-       register int i;
-       struct sym **p;
-
-       if ((hp = headp) != NULL) {
-           while(hp) {
-               p = hp->s_list;
-               for (i=0; i<hp->h_nglob; ++i) {
-                   if (p[i] == tsp) {
-                       fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
-                       fprintf(fp, "referenced by module '%s'\n", hp->m_id);
-                       lkerr++;
-                   }
-               }
-           hp = hp->h_hp;
-           }
-       }
-}
-
-/*)Function    int     symeq(p1, p2)
- *
- *             char *  p1              name string
- *             char *  p2              name string
- *
- *     The function symeq() compares the two name strings for a match.
- *     The return value is 1 for a match and 0 for no match.
- *
- *     local variables:
- *             int     h               loop counter
- *
- *     global variables:
- *             char    ccase[]         an array of characters which
- *                                     perform the case translation function
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- *
- */
-
-int
-symeq(p1, p2)
-register char *p1, *p2;
-{
-#if    CASE_SENSITIVE
-               return (strcmp( p1, p2 ) == 0);
-#else
-               return (as_strcmpi( p1, p2 ) == 0);
-#endif
-}
-
-/*)Function    int     hash(p)
- *
- *             char *  p               pointer to string to hash
- *
- *     The function hash() computes a hash code using the sum
- *     of all characters mod table size algorithm.
- *
- *     local variables:
- *             int     h               accumulated character sum
- *             int     n               loop counter
- *
- *     global variables:
- *             char    ccase[]         an array of characters which
- *                                     perform the case translation function
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- *
- */
-int
-hash(p)
-register char *p;
-{
-       register int h;
-
-       h = 0;
-       while (*p) {
-
-#if    CASE_SENSITIVE
-               h += *p++;
-#else
-               h += ccase[*p++];
-#endif
-
-       };
-       return (h&HMASK);
-}
-
-/*)Function    VOID *  new(n)
- *
- *             unsigned int    n       allocation size in bytes
- *
- *     The function new() allocates n bytes of space and returns
- *     a pointer to this memory.  If no space is available the
- *     linker is terminated.
- *
- *     local variables:
- *             char *  p               a general pointer
- *             char *  q               a general pointer
- *
- *     global variables:
- *             none
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID *  malloc()        c_library
- *
- *     side effects:
- *             Memory is allocated, if allocation fails
- *             the linker is terminated.
- */
-
-VOID *
-new(n)
-unsigned int n;
-{
-       register char *p;
-
-       if ((p = (char *) calloc(n, 1)) == NULL) {
-               fprintf(stderr, "Out of space!\n");
-               lkexit(1);
-       }
-       return (p);
-}
index 5c3bf82379fd19a4b165d95cc432a354b41cecd0..6d3de06d139151515047e77317ee02aa634a49cd 100755 (executable)
--- a/configure
+++ b/configure
@@ -8135,7 +8135,7 @@ if test $OPT_DISABLE_HC08 = 0; then
 fi
 
 if test $OPT_DISABLE_MCS51 = 0; then
-                                ac_config_files="$ac_config_files src/mcs51/Makefile as/mcs51/Makefile debugger/mcs51/Makefile"
+                                ac_config_files="$ac_config_files src/mcs51/Makefile as/mcs51/Makefile as/link/mcs51/Makefile debugger/mcs51/Makefile"
 
   test $OPT_DISABLE_DEVICE_LIB = 0 &&                                         ac_config_files="$ac_config_files device/lib/mcs51/Makefile device/lib/small/Makefile device/lib/medium/Makefile device/lib/large/Makefile"
 
index 954f07aac3413d2bae0f7ca894ff9f24304db92b..f710d00013abf02be72d70caf825f3c22ec1a72a 100644 (file)
--- a/sdcc.dsw
+++ b/sdcc.dsw
@@ -87,7 +87,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "aslink"=.\as\aslink.dsp - Package Owner=<4>
+Project: "aslink"=.\as\link\mcs51\aslink.dsp - Package Owner=<4>
 
 Package=<5>
 {{{