moved link/ to as/link/
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 14 Sep 2006 18:32:41 +0000 (18:32 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 14 Sep 2006 18:32:41 +0000 (18:32 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4377 4a8a32a2-be11-0410-ad9d-d568d2c75423

50 files changed:
ChangeLog
Makefile.in
as/link/Makefile.in [new file with mode: 0644]
as/link/README [new file with mode: 0644]
as/link/clean.mk [new file with mode: 0644]
as/link/z80/Makefile.in [new file with mode: 0644]
as/link/z80/aslink.h [new file with mode: 0644]
as/link/z80/clean.mk [new file with mode: 0644]
as/link/z80/conf.mk [new file with mode: 0644]
as/link/z80/linkgbz80.dsp [new file with mode: 0644]
as/link/z80/linkz80.dsp [new file with mode: 0644]
as/link/z80/lkarea.c [new file with mode: 0644]
as/link/z80/lkdata.c [new file with mode: 0644]
as/link/z80/lkeval.c [new file with mode: 0644]
as/link/z80/lkgb.c [new file with mode: 0644]
as/link/z80/lkgg.c [new file with mode: 0644]
as/link/z80/lkhead.c [new file with mode: 0644]
as/link/z80/lkihx.c [new file with mode: 0644]
as/link/z80/lklex.c [new file with mode: 0644]
as/link/z80/lklibr.c [new file with mode: 0644]
as/link/z80/lklist.c [new file with mode: 0644]
as/link/z80/lkmain.c [new file with mode: 0644]
as/link/z80/lkrloc.c [new file with mode: 0644]
as/link/z80/lks19.c [new file with mode: 0644]
as/link/z80/lksym.c [new file with mode: 0644]
configure
link/Makefile.in [deleted file]
link/README [deleted file]
link/clean.mk [deleted file]
link/z80/Makefile.in [deleted file]
link/z80/aslink.h [deleted file]
link/z80/clean.mk [deleted file]
link/z80/conf.mk [deleted file]
link/z80/linkgbz80.dsp [deleted file]
link/z80/linkz80.dsp [deleted file]
link/z80/lkarea.c [deleted file]
link/z80/lkdata.c [deleted file]
link/z80/lkeval.c [deleted file]
link/z80/lkgb.c [deleted file]
link/z80/lkgg.c [deleted file]
link/z80/lkhead.c [deleted file]
link/z80/lkihx.c [deleted file]
link/z80/lklex.c [deleted file]
link/z80/lklibr.c [deleted file]
link/z80/lklist.c [deleted file]
link/z80/lkmain.c [deleted file]
link/z80/lkrloc.c [deleted file]
link/z80/lks19.c [deleted file]
link/z80/lksym.c [deleted file]
sdcc.dsw

index e7a9acdef999b15f34384de13ae79a406fa72ac1..0e3315f240ffae7b4eed05553e09329c92fdea04 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2006-09-14 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * as/link,
+       * as/link/Makefile.in,
+       * as/link/z80/linkgbz80.dsp,
+       * as/link/z80/linkz80.dsp,
+       * configure,
+       * link,
+       * link/clean.mk,
+       * link/Makefile.in,
+       * link/README,
+       * link/z80,
+       * link/z80/aslink.h,
+       * link/z80/clean.mk,
+       * link/z80/conf.mk,
+       * link/z80/linkgbz80.dsp,
+       * link/z80/linkz80.dsp,
+       * link/z80/lkarea.c,
+       * link/z80/lkdata.c,
+       * link/z80/lkeval.c,
+       * link/z80/lkgb.c,
+       * link/z80/lkgg.c,
+       * link/z80/lkhead.c,
+       * link/z80/lkihx.c,
+       * link/z80/lklex.c,
+       * link/z80/lklibr.c,
+       * link/z80/lklist.c,
+       * link/z80/lkmain.c,
+       * link/z80/lkrloc.c,
+       * link/z80/lks19.c,
+       * link/z80/lksym.c,
+       * link/z80/Makefile.in,
+       * Makefile.in,
+       * sdcc.dsw: moved link/ to as/link/
+
 2006-09-11 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * as/mcs51/i51mch.c (machine): fixed warning
index 72c60ff67ea33d3522915c2b4b98001ea13786c6..fd9410ad3d75da386b22c607b150f9b7ed41630d 100644 (file)
@@ -30,7 +30,7 @@ SDCC_MISC     += debugger/mcs51
 endif
 
 ifeq ($(OPT_DISABLE_Z80), 0)
-SDCC_ASLINK     += as link
+SDCC_ASLINK     += as as/link
 endif
 
 ifeq ($(OPT_DISABLE_UCSIM), 0)
diff --git a/as/link/Makefile.in b/as/link/Makefile.in
new file mode 100644 (file)
index 0000000..9776ae6
--- /dev/null
@@ -0,0 +1,21 @@
+VPATH        = @srcdir@
+srcdir       = @srcdir@
+top_builddir = @top_builddir@
+
+include $(top_builddir)Makefile.common
+
+PORTS = z80 gbz80
+
+all: 
+       $(MAKE) -C z80 _link-z80 _link-gbz80 E=$(E) BUILDDIR=../../../bin/
+
+install: all
+       $(INSTALL) $(top_builddir)bin/link-z80$(EXEEXT) `echo $(DESTDIR)$(bindir)/link-z80$(EXEEXT)|sed '$(transform)'`
+       $(STRIP) `echo $(DESTDIR)$(bindir)/link-z80$(EXEEXT)|sed '$(transform)'`
+       $(INSTALL) $(top_builddir)bin/link-gbz80$(EXEEXT) `echo $(DESTDIR)$(bindir)/link-gbz80$(EXEEXT)|sed '$(transform)'`
+       $(STRIP) `echo $(DESTDIR)$(bindir)/link-gbz80$(EXEEXT)|sed '$(transform)'`
+
+uninstall:
+       cd $(DESTDIR)$(bindir); rm -f link-z80$(EXEEXT) link-gbz80$(EXEEXT)
+
+include $(srcdir)/clean.mk
diff --git a/as/link/README b/as/link/README
new file mode 100644 (file)
index 0000000..5aba86d
--- /dev/null
@@ -0,0 +1,8 @@
+sdcc/link
+---------
+
+In gbdk the linker and assembler were split into seperate packages.
+
+For now I'm keeping that split, and leaving the mcs51 version as is.
+
+-- Michael
diff --git a/as/link/clean.mk b/as/link/clean.mk
new file mode 100644 (file)
index 0000000..e843581
--- /dev/null
@@ -0,0 +1,6 @@
+clean:
+       $(MAKE) -C z80 clean
+
+distclean: clean
+       $(MAKE) -C z80 distclean
+       rm -f Makefile
diff --git a/as/link/z80/Makefile.in b/as/link/z80/Makefile.in
new file mode 100644 (file)
index 0000000..1f67a7f
--- /dev/null
@@ -0,0 +1,47 @@
+VPATH        = @srcdir@
+srcdir       = @srcdir@
+top_builddir = @top_builddir@
+top_srcdir   = @top_srcdir@
+
+include $(top_builddir)Makefile.common
+
+OBJDIR = obj/$(EXT)
+
+SLIBSRC        = NewAlloc.c
+
+SRC    = lkarea.c lkdata.c lkeval.c lkhead.c lkihx.c lklex.c \
+         lklibr.c lklist.c lkmain.c lkrloc.c lks19.c lksym.c \
+         lkgb.c lkgg.c
+
+OBJS   = $(SRC:%.c=$(OBJDIR)/%.o) 
+SLIBOBJS       = $(SLIBSRC:%.c=$(OBJDIR)/%.o) 
+
+BINS   = $(BUILDDIR)link$(EXT)$(EXEEXT)
+
+CFLAGS += $(CPPFLAGS) $(OPTS) -DINDEXLIB -DMLH_MAP -DUNIX -DSDK
+CFLAGS += -funsigned-char -DUNIX
+CFLAGS += -I$(top_builddir)as/$(PORT) -I$(SLIB) 
+
+LDFLAGS += -lm $(EXTRALIBS)
+
+all:   $(BINS)
+
+$(BINS): $(OBJDIR) $(OBJS) $(SLIBOBJS)
+       $(CC) -g -o $(BINS) $(OBJS) $(SLIBOBJS) $(LDFLAGS)
+
+$(OBJDIR):
+       mkdir -p $(OBJDIR)
+
+$(OBJDIR)/%.o: %.c
+       $(CC) -c $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: $(SLIB)/%.c
+       $(CC) -c $(CFLAGS) -o $@ $<
+
+_link-z80:
+       $(MAKE) EXT=-z80$(E) PORT=z80
+
+_link-gbz80:
+       $(MAKE) EXT=-gbz80$(E) OPTS=-DGAMEBOY PORT=z80
+
+include $(srcdir)/clean.mk
diff --git a/as/link/z80/aslink.h b/as/link/z80/aslink.h
new file mode 100644 (file)
index 0000000..e18cd02
--- /dev/null
@@ -0,0 +1,737 @@
+/* aslink.h */
+
+/*
+ * (C) Copyright 1989-1996
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+/*
+ * Extensions: P. Felber
+ */
+#define        VERSION "V01.75"
+
+/*
+ * Case Sensitivity Flag
+ */
+#define        CASE_SENSITIVE  1
+
+/*)Module      asmlnk.h
+ *
+ *     The module asmlnk.h contains the definitions for constants,
+ *     structures, global variables, and LKxxxx functions
+ *     contained in the LKxxxx.c files.
+ */
+
+/*)BUILD
+       $(PROGRAM) =    ASLINK
+       $(INCLUDE) =    ASLINK.H
+       $(FILES) = {
+               LKMAIN.C
+               LKLEX.C
+               LKAREA.C
+               LKHEAD.C
+               LKSYM.C
+               LKEVAL.C
+               LKDATA.C
+               LKLIST.C
+               LKRLOC.C
+               LKLIBR.C
+               LKS19.C
+               LKIHX.C
+       }
+       $(STACK) = 2000
+*/
+
+/* DECUS C void definition */
+/* File/extension seperator */
+
+#ifdef decus
+#define        VOID    char
+#define        FSEPX   '.'
+#endif
+
+/* PDOS C void definition */
+/* File/extension seperator */
+
+#ifdef PDOS
+#define        VOID    char
+#define        FSEPX   ':'
+#endif
+
+/* Default void definition */
+/* File/extension seperator */
+
+#ifndef        VOID
+#define        VOID    void
+#define        FSEPX   '.'
+#define        OTHERSYSTEM
+#endif
+
+/*
+ * PATH_MAX
+ */
+#include <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.
+ */
+
+#ifdef SDK
+#define        NCPS    80              /* characters per symbol.  Used to be 32... */
+#else /* SDK */
+#define        NCPS    8               /* characters per symbol */
+#endif /* SDK */
+/* #define     NCPS    32 */   /* characters per symbol */
+#define        NDATA   16              /* actual data */
+#define        NINPUT  PATH_MAX        /* Input buffer size */
+#define        NHASH   64              /* Buckets in hash table */
+#define        HMASK   077             /* Hash mask */
+#define        NLPP    60              /* Lines per page */
+#define        NTXT    16              /* T values */
+#define        FILSPC  PATH_MAX        /* File spec length */
+
+/*
+ *     The "R_" relocation constants define values used in
+ *     generating the assembler relocation output data for
+ *     areas, symbols, and code.
+ *
+ *
+ *     Relocation types.
+ *
+ *            7     6     5     4     3     2     1     0
+ *         +-----+-----+-----+-----+-----+-----+-----+-----+
+ *         | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT |
+ *         +-----+-----+-----+-----+-----+-----+-----+-----+
+ */
+
+#define        R_WORD  0x00            /* 16 bit */
+#define        R_BYTE  0x01            /*  8 bit */
+
+#define        R_AREA  0x00            /* Base type */
+#define        R_SYM   0x02
+
+#define        R_NORM  0x00            /* PC adjust */
+#define        R_PCR   0x04
+
+#define        R_BYT1  0x00            /* Byte count for R_BYTE = 1 */
+#define        R_BYT2  0x08            /* Byte count for R_BYTE = 2 */
+
+#define        R_SGND  0x00            /* Signed value */
+#define        R_USGN  0x10            /* Unsigned value */
+
+#define        R_NOPAG 0x00            /* Page Mode */
+#define        R_PAG0  0x20            /* Page '0' */
+#define        R_PAG   0x40            /* Page 'nnn' */
+
+/*
+ * Valid for R_BYT2:
+ */
+#define        R_LSB   0x00            /* output low byte */
+#define        R_MSB   0x80            /* output high byte */
+
+/*
+ * Global symbol types.
+ */
+#define        S_REF   1               /* referenced */
+#define        S_DEF   2               /* defined */
+
+/*
+ * Area types
+ */
+#define        A_CON   0000            /* concatenate */
+#define        A_OVR   0004            /* overlay */
+#define        A_REL   0000            /* relocatable */
+#define        A_ABS   0010            /* absolute */
+#define        A_NOPAG 0000            /* non-paged */
+#define        A_PAG   0020            /* paged */
+
+/*
+ * File types
+ */
+#define F_INV  0               /* invalid */
+#define        F_STD   1               /* stdin */
+#define        F_LNK   2               /* File.lnk */
+#define        F_REL   3               /* File.rel */
+#ifdef SDK
+#define        F_CMD   4               /* Command line */
+#endif /* SDK */
+
+#ifdef GAMEBOY
+/*
+ * Multiple banks support
+ */
+extern int nb_rom_banks;
+extern int nb_ram_banks;
+extern int current_rom_bank;
+extern int mbc_type;
+extern char cart_name[];
+/*
+ * ROM patching support
+ */
+typedef struct _patch {
+  unsigned int addr;
+  unsigned char value;
+  struct _patch *next;
+} patch;
+extern patch* patches;
+#endif /* GAMEBOY */
+/*
+ *     General assembler address type
+ */
+typedef unsigned int Addr_T;
+
+/*
+ *     The structures of head, area, areax, and sym are created
+ *     as the REL files are read during the first pass of the
+ *     linker.  The struct head is created upon encountering a
+ *     H directive in the REL file.  The structure contains a
+ *     link to a link file structure (struct lfile) which describes
+ *     the file containing the H directive, the number of data/code
+ *     areas contained in this header segment, the number of
+ *     symbols referenced/defined in this header segment, a pointer
+ *     to an array of pointers to areax structures (struct areax)
+ *     created as each A directive is read, and a pointer to an
+ *     array of pointers to symbol structures (struct sym) for
+ *     all referenced/defined symbols.  As H directives are read
+ *     from the REL files a linked list of head structures is
+ *     created by placing a link to the new head structure
+ *     in the previous head structure.
+ */
+struct head
+{
+       struct  head   *h_hp;   /* Header link */
+       struct  lfile  *h_lfile;/* Associated file */
+       int     h_narea;        /* # of areas */
+       struct  areax **a_list; /* Area list */
+       int     h_nglob;        /* # of global symbols */
+       struct  sym   **s_list; /* Globle symbol list */
+       char    m_id[NCPS];     /* Module name */
+};
+
+/*
+ *     A structure area is created for each 'unique' data/code
+ *     area definition found as the REL files are read.  The
+ *     struct area contains the name of the area, a flag byte
+ *     which contains the area attributes (REL/CON/OVR/ABS),
+ *     an area subtype (not used in this assembler), and the
+ *     area base address and total size which will be filled
+ *     in at the end of the first pass through the REL files.
+ *     As A directives are read from the REL files a linked
+ *     list of unique area structures is created by placing a
+ *     link to the new area structure in the previous area structure.
+ */
+struct area
+{
+       struct  area    *a_ap;  /* Area link */
+       struct  areax   *a_axp; /* Area extension link */
+       Addr_T  a_addr;         /* Beginning address of area */
+       Addr_T  a_size;         /* Total size of the area */
+       char    a_type;         /* Area subtype */
+       char    a_flag;         /* Flag byte */
+       char    a_id[NCPS];     /* Name */
+};
+
+/*
+ *     An areax structure is created for every A directive found
+ *     while reading the REL files.  The struct areax contains a
+ *     link to the 'unique' area structure referenced by the A
+ *     directive and to the head structure this area segment is
+ *     a part of.  The size of this area segment as read from the
+ *     A directive is placed in the areax structure.  The beginning
+ *     address of this segment will be filled in at the end of the
+ *     first pass through the REL files.  As A directives are read
+ *     from the REL files a linked list of areax structures is
+ *     created for each unique area.  The final areax linked
+ *     list has at its head the 'unique' area structure linked
+ *     to the linked areax structures (one areax structure for
+ *     each A directive for this area).
+ */
+struct areax
+{
+       struct  areax   *a_axp; /* Area extension link */
+       struct  area    *a_bap; /* Base area link */
+       struct  head    *a_bhp; /* Base header link */
+       Addr_T  a_addr;         /* Beginning address of section */
+       Addr_T  a_size;         /* Size of the area in section */
+};
+
+/*
+ *     A sym structure is created for every unique symbol
+ *     referenced/defined while reading the REL files.  The
+ *     struct sym contains the symbol's name, a flag value
+ *     (not used in this linker), a symbol type denoting
+ *     referenced/defined, and an address which is loaded
+ *     with the relative address within the area in which
+ *     the symbol was defined.  The sym structure also
+ *     contains a link to the area where the symbol was defined.
+ *     The sym structures are linked into linked lists using
+ *     the symbol link element.
+ */
+struct sym
+{
+       struct  sym     *s_sp;  /* Symbol link */
+       struct  areax   *s_axp; /* Symbol area link */
+       char    s_type;         /* Symbol subtype */
+       char    s_flag;         /* Flag byte */
+       Addr_T  s_addr;         /* Address */
+       char    s_id[NCPS];     /* Name */
+};
+
+/*
+ *     The structure lfile contains a pointer to a
+ *     file specification string, the file type, and
+ *     a link to the next lfile structure.
+ */
+struct lfile
+{
+       struct  lfile   *f_flp; /* lfile link */
+       int     f_type;         /* File type */
+       char    *f_idp;         /* Pointer to file spec */
+};
+
+/*
+ *     The struct base contains a pointer to a
+ *     base definition string and a link to the next
+ *     base structure.
+ */
+struct base
+{
+       struct  base  *b_base;  /* Base link */
+       char          *b_strp;  /* String pointer */
+};
+
+/*
+ *     The struct globl contains a pointer to a
+ *     global definition string and a link to the next
+ *     global structure.
+ */
+struct globl
+{
+       struct  globl *g_globl; /* Global link */
+       char          *g_strp;  /* String pointer */
+};
+
+/*
+ *     A structure sdp is created for each 'unique' paged
+ *     area definition found as the REL files are read.
+ *     As P directives are read from the REL files a linked
+ *     list of unique sdp structures is created by placing a
+ *     link to the new sdp structure in the previous area structure.
+ */
+struct sdp
+{
+       struct  area  *s_area;  /* Paged Area link */
+       struct  areax *s_areax; /* Paged Area Extension Link */
+       Addr_T  s_addr;         /* Page address offset */
+};
+
+/*
+ *     The structure rerr is loaded with the information
+ *     required to report an error during the linking
+ *     process.  The structure contains an index value
+ *     which selects the areax structure from the header
+ *     areax structure list, a mode value which selects
+ *     symbol or area relocation, the base address in the
+ *     area section, an area/symbol list index value, and
+ *     an area/symbol offset value.
+ */
+struct rerr
+{
+       int     aindex;         /* Linking area */
+       int     mode;           /* Relocation mode */
+       Addr_T  rtbase;         /* Base address in section */
+       int     rindex;         /* Area/Symbol reloaction index */
+       Addr_T  rval;           /* Area/Symbol offset value */
+};
+
+/*
+ *     The structure lbpath is created for each library
+ *     path specification input by the -k option.  The
+ *     lbpath structures are linked into a list using
+ *     the next link element.
+ */
+struct lbpath {
+       struct  lbpath  *next;
+       char            *path;
+};
+
+/*
+ *     The structure lbname is created for all combinations of the
+ *     library path specifications (input by the -k option) and the
+ *     library file specifications (input by the -l option) that
+ *     lead to an existing file.  The element path points to
+ *     the path string, element libfil points to the library
+ *     file string, and the element libspc is the concatenation
+ *     of the valid path and libfil strings.
+ *
+ *     The lbpath structures are linked into a list
+ *     using the next link element.
+ *
+ *     Each library file contains a list of object files
+ *     that are contained in the particular library. e.g.:
+ *
+ *             \iolib\termio
+ *             \inilib\termio
+ *
+ *     Only one specification per line is allowed.
+ */
+struct lbname {
+       struct  lbname  *next;
+       char            *path;
+       char            *libfil;
+       char            *libspc;
+};
+
+/*
+ *     The function fndsym() searches through all combinations of the
+ *     library path specifications (input by the -k option) and the
+ *     library file specifications (input by the -l option) that
+ *     lead to an existing file for a symbol definition.
+ *
+ *     The structure lbfile is created for the first library
+ *     object file which contains the definition for the
+ *     specified undefined symbol.
+ *
+ *     The element libspc points to the library file path specification
+ *     and element relfil points to the object file specification string.
+ *     The element filspc is the complete path/file specification for
+ *     the library file to be imported into the linker.  The
+ *     file specicifation may be formed in one of two ways:
+ *
+ *     (1)     If the library file contained an absolute
+ *             path/file specification then this becomes filspc.
+ *             (i.e. C:\...)
+ *
+ *     (2)     If the library file contains a relative path/file
+ *             specification then the concatenation of the path
+ *             and this file specification becomes filspc.
+ *             (i.e. \...)
+ *
+ *     The lbpath structures are linked into a list
+ *     using the next link element.
+ */
+struct lbfile {
+       struct  lbfile  *next;
+       char            *libspc;
+       char            *relfil;
+       char            *filspc;
+    long               offset; /*>=0 if rel file is embedded in a lib file at this offset*/
+};
+
+/*
+ *     External Definitions for all Global Variables
+ */
+
+extern char    *_abs_;         /*      = { ".  .ABS." };
+                                */
+extern int     lkerr;          /*      ASLink error flag
+                                */
+extern char    *ip;            /*      pointer into the REL file
+                                *      text line in ib[]
+                                */
+extern char    ib[NINPUT];     /*      REL file text line
+                                */
+extern char    *rp;            /*      pointer into the LST file
+                                *      text line in rb[]
+                                */
+extern char    rb[NINPUT];     /*      LST file text line being
+                                *      address relocated
+                                */
+extern unsigned char   ctype[];        /*      array of character types, one per
+                                *      ASCII character
+                                */
+
+extern char sdccopt[NINPUT];
+extern char sdccopt_module[NINPUT];
+extern char curr_module[NINPUT];
+
+/*
+ *     Character Type Definitions
+ */
+#define        SPACE   0000
+#define ETC    0000
+#define        LETTER  0001
+#define        DIGIT   0002
+#define        BINOP   0004
+#define        RAD2    0010
+#define        RAD8    0020
+#define        RAD10   0040
+#define        RAD16   0100
+#define        ILL     0200
+
+#define        DGT2    DIGIT|RAD16|RAD10|RAD8|RAD2
+#define        DGT8    DIGIT|RAD16|RAD10|RAD8
+#define        DGT10   DIGIT|RAD16|RAD10
+#define        LTR16   LETTER|RAD16
+
+#if    CASE_SENSITIVE
+#else
+extern char    ccase[];        /*      an array of characters which
+                                *      perform the case translation function
+                                */
+#endif
+
+extern struct  lfile   *filep; /*      The pointers (lfile *) filep,
+                                *      (lfile *) cfp, and (FILE *) sfp
+                                *      are used in conjunction with
+                                *      the routine lk_getline() to read
+                                *      asmlnk commands from
+                                *      (1) the standard input or
+                                *      (2) or a command file
+                                *      and to read the REL files
+                                *      sequentially as defined by the
+                                *      asmlnk input commands.
+                                *
+                                *      The pointer *filep points to the
+                                *      beginning of a linked list of
+                                *      lfile structures.
+                                */
+extern struct  lfile   *cfp;   /*      The pointer *cfp points to the
+                                *      current lfile structure
+                                */
+extern struct  lfile   *startp;/*      asmlnk startup file structure
+                                */
+extern struct  lfile   *linkp; /*      pointer to first lfile structure
+                                *      containing an input REL file
+                                *      specification
+                                */
+extern struct  lfile   *lfp;   /*      pointer to current lfile structure
+                                *      being processed by parse()
+                                */
+extern struct  head    *headp; /*      The pointer to the first
+                                *      head structure of a linked list
+                                */
+extern struct  head    *hp;    /*      Pointer to the current
+                                *      head structure
+                                */
+extern struct  area    *areap; /*      The pointer to the first
+                                *      area structure of a linked list
+                                */
+extern struct  area    *ap;    /*      Pointer to the current
+                                *      area structure
+                                */
+extern struct  areax   *axp;   /*      Pointer to the current
+                                *      areax structure
+                                */
+extern struct  sym *symhash[NHASH]; /* array of pointers to NHASH
+                                     * linked symbol lists
+                                     */
+extern struct  base    *basep; /*      The pointer to the first
+                                *      base structure
+                                */
+extern struct  base    *bsp;   /*      Pointer to the current
+                                *      base structure
+                                */
+extern struct  globl   *globlp;/*      The pointer to the first
+                                *      globl structure
+                                */
+extern struct  globl   *gsp;   /*      Pointer to the current
+                                *      globl structure
+                                */
+extern struct  sdp     sdp;    /*      Base Paged structure
+                                */
+extern struct  rerr    rerr;   /*      Structure containing the
+                                *      linker error information
+                                */
+extern FILE    *ofp;           /*      Linker Output file handle
+                                */
+extern FILE    *mfp;           /*      Map output file handle
+                                */
+extern FILE    *rfp;           /*      File handle for output
+                                *      address relocated ASxxxx
+                                *      listing file
+                                */
+extern FILE    *sfp;           /*      The file handle sfp points to the
+                                *      currently open file
+                                */
+extern FILE    *tfp;           /*      File handle for input
+                                *      ASxxxx listing file
+                                */
+extern int     oflag;          /*      Output file type flag
+                                */
+extern int     mflag;          /*      Map output flag
+                                */
+#ifdef SDK
+extern int     symflag;        /*      no$gmb .sym output flag
+                                */
+#endif
+extern int     xflag;          /*      Map file radix type flag
+                                */
+extern int     pflag;          /*      print linker command file flag
+                                */
+extern int     uflag;          /*      Listing relocation flag
+                                */
+extern int     radix;          /*      current number conversion radix:
+                                *      2 (binary), 8 (octal), 10 (decimal),
+                                *      16 (hexadecimal)
+                                */
+extern int     line;           /*      current line number
+                                */
+extern int     page;           /*      current page number
+                                */
+extern int     lop;            /*      current line number on page
+                                */
+extern int     pass;           /*      linker pass number
+                                */
+extern int     rtcnt;          /*      count of elements in the
+                                *      rtval[] and rtflg[] arrays
+                                */
+extern Addr_T  rtval[];        /*      data associated with relocation
+                                */
+extern int     rtflg[];        /*      indicates if rtval[] value is
+                                *      to be sent to the output file.
+                                *      (always set in this linker)
+                                */
+extern int     hilo;           /*      REL file byte ordering
+                                */
+extern int     gline;          /*      LST file relocation active
+                                *      for current line
+                                */
+extern int     gcntr;          /*      LST file relocation active
+                                *      counter
+                                */
+extern struct lbpath *lbphead; /*      pointer to the first
+                                *      library path structure
+                                */
+extern struct lbname *lbnhead; /*      pointer to the first
+                                *      library name structure
+                                */
+extern struct lbfile *lbfhead; /*      pointer to the first
+                                *      library file structure
+                                */
+
+/* C Library function definitions */
+/* for reference only
+extern VOID            exit();
+extern int             fclose();
+extern char *          fgets();
+extern FILE *          fopen();
+extern int             fprintf();
+extern VOID            free();
+extern VOID *          malloc();
+extern char            putc();
+extern char *          strcpy();
+extern int             strlen();
+extern char *          strncpy();
+*/
+
+/* Program function definitions */
+
+/* lkmain.c */
+extern FILE *          afile();
+extern VOID            bassav();
+extern VOID            gblsav();
+extern VOID            link();
+extern VOID            lkexit();
+extern int             main();
+extern VOID            map();
+#ifdef SDK
+extern VOID            sym();
+#endif
+extern int             parse();
+extern VOID            setbas();
+extern VOID            setgbl();
+extern VOID            usage();
+
+/* lklex.c */
+extern char            endline();
+extern char            get();
+extern VOID            getfid();
+extern VOID            getid();
+extern int             lk_getline();
+extern int             getmap();
+extern char            getnb();
+extern int             more();
+extern VOID            skip();
+extern VOID            unget();
+extern VOID            chop_crlf();
+
+/* lkarea.c */
+extern VOID            lkparea();
+extern VOID            lnkarea();
+extern VOID            lnksect();
+extern VOID            newarea();
+
+/* lkhead.c */
+extern VOID            module();
+extern VOID            newhead();
+
+/* lksym.c */
+extern int             hash();
+extern struct  sym *   lkpsym();
+extern VOID *          new();
+extern struct  sym *   newsym();
+extern VOID            symdef();
+extern int             symeq();
+extern VOID            syminit();
+extern VOID            symmod();
+extern Addr_T          symval();
+
+/* lkeval.c */
+extern int             digit();
+extern Addr_T          eval();
+extern Addr_T          expr();
+extern int             oprio();
+extern Addr_T          term();
+
+/* lklist.c */
+extern int             dgt();
+extern VOID            lkulist();
+extern VOID            lkalist();
+extern VOID            lkglist();
+extern VOID            lstarea();
+extern VOID            newpag();
+extern VOID            slew();
+
+/* lkrloc.c */
+extern Addr_T          adb_b();
+extern Addr_T          adb_hi();
+extern Addr_T          adb_lo();
+extern Addr_T          adw_w();
+extern Addr_T          adw_hi();
+extern Addr_T          adw_lo();
+extern Addr_T          evword();
+extern VOID            rele();
+extern VOID            reloc();
+extern VOID            relt();
+extern VOID            relr();
+extern VOID            relp();
+extern VOID            relerr();
+extern char *          errmsg[];
+extern VOID            errdmp();
+extern VOID            relerp();
+extern VOID            erpdmp();
+extern VOID            prntval();
+
+/* lklibr.c */
+extern int             addfile();
+extern VOID            addlib();
+extern VOID            addpath();
+extern int             fndsym();
+extern VOID            library();
+extern VOID            loadfile();
+extern VOID            search();
+
+/* lks19.c */
+extern VOID            s19();
+
+/* lkihx.c */
+extern VOID            ihx();
+
+/* lkgb.h */
+VOID gb(int in);
+VOID gg(int in);
+
diff --git a/as/link/z80/clean.mk b/as/link/z80/clean.mk
new file mode 100644 (file)
index 0000000..4e13a89
--- /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/link-z80$(EXEEXT) link-z80$(EXEEXT) \
+             $(top_builddir)bin/link-gbz80$(EXEEXT) link-gbz80$(EXEEXT)
+       rm -f *.dep
+       rm -rf obj
+
+# Deleting all files created by configuring or building the program
+# -----------------------------------------------------------------
+distclean: clean
+       rm -f Makefile
+
+# 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/z80/conf.mk b/as/link/z80/conf.mk
new file mode 100644 (file)
index 0000000..3fa379d
--- /dev/null
@@ -0,0 +1,23 @@
+# Deleting all files created by building the program
+# --------------------------------------------------
+clean:
+       rm -f *core *[%~] *.[oa]
+       rm -f .[a-z]*~
+       rm -f $(top_builddir)bin/link-z80 link-z80
+
+
+# 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/z80/linkgbz80.dsp b/as/link/z80/linkgbz80.dsp
new file mode 100644 (file)
index 0000000..db0fa18
--- /dev/null
@@ -0,0 +1,174 @@
+# Microsoft Developer Studio Project File - Name="linkgbz80" - 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=linkgbz80 - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "linkgbz80.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 "linkgbz80.mak" CFG="linkgbz80 - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "linkgbz80 - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "linkgbz80 - Win32 Debug" (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)" == "linkgbz80 - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release_gbz80"\r
+# PROP BASE Intermediate_Dir "Release_gbz80"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release_gbz80"\r
+# PROP Intermediate_Dir "Release_gbz80"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\link-gbz80.exe"\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "linkgbz80 - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug_gbz80"\r
+# PROP BASE Intermediate_Dir "Debug_gbz80"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug_gbz80"\r
+# PROP Intermediate_Dir "Debug_gbz80"\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" /YX /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\link-gbz80.exe" /pdbtype:sept\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "linkgbz80 - Win32 Release"\r
+# Name "linkgbz80 - Win32 Debug"\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=.\lkarea.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkdata.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkeval.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkgb.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkgg.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkhead.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkihx.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklex.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklibr.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklist.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkmain.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkrloc.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lks19.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lksym.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\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=.\aslink.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/as/link/z80/linkz80.dsp b/as/link/z80/linkz80.dsp
new file mode 100644 (file)
index 0000000..cc287c7
--- /dev/null
@@ -0,0 +1,174 @@
+# Microsoft Developer Studio Project File - Name="linkz80" - 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=linkz80 - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "linkz80.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 "linkz80.mak" CFG="linkz80 - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "linkz80 - Win32 Release" (based on "Win32 (x86) Console Application")\r
+!MESSAGE "linkz80 - Win32 Debug" (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)" == "linkz80 - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release_z80"\r
+# PROP BASE Intermediate_Dir "Release_z80"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release_z80"\r
+# PROP Intermediate_Dir "Release_z80"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\..\bin_vc\link-z80.exe"\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ELSEIF  "$(CFG)" == "linkz80 - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug_z80"\r
+# PROP BASE Intermediate_Dir "Debug_z80"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug_z80"\r
+# PROP Intermediate_Dir "Debug_z80"\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" /YX /FD /GZ /c\r
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\bin_vc\link-z80.exe" /pdbtype:sept\r
+# SUBTRACT LINK32 /pdb:none\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "linkz80 - Win32 Release"\r
+# Name "linkz80 - Win32 Debug"\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=.\lkarea.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkdata.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkeval.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkgb.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkgg.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkhead.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkihx.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklex.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklibr.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lklist.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkmain.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lkrloc.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lks19.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\lksym.c\r
+# ADD CPP /D "SDK" /D "INDEXLIB"\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=.\aslink.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/as/link/z80/lkarea.c b/as/link/z80/lkarea.c
new file mode 100644 (file)
index 0000000..deb61c9
--- /dev/null
@@ -0,0 +1,430 @@
+/* lkarea.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      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 tha 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++;
+               }
+       }
+       /*
+        * 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(id)
+char *id;
+{
+       register struct area *tap;
+       register struct areax *taxp;
+
+       ap = areap;
+       axp = (struct areax *) new (sizeof(struct areax));
+       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);
+}
+
+/*)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 ae 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()        lksysm.c
+ *             char *  strncpy()       c_library
+ *             int     symeq()         lksysm.c
+ *
+ *     side effects:
+ *             All area and areax addresses and sizes are
+ *             determined and saved in their respective
+ *             structures.
+ */
+
+/*
+ * Resolve all area addresses.
+ */
+VOID
+lnkarea()
+{
+       register int rloc;
+       char temp[NCPS];
+       struct sym *sp;
+
+       rloc = 0;
+       ap = areap;
+       while (ap) {
+               if (ap->a_flag&A_ABS) {
+                       /*
+                        * Absolute sections
+                        */
+                       lnksect(ap);
+               } else {
+                       /*
+                        * Relocatable sections
+                        */
+                       if (ap->a_addr == 0)
+                               ap->a_addr = rloc;
+                       lnksect(ap);
+                       rloc = 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 = 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;
+               }
+               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(tap)
+register struct area *tap;
+{
+       register Addr_T size, addr;
+       register struct areax *taxp;
+
+       size = 0;
+       addr = tap->a_addr;
+       if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
+           fprintf(stderr,
+           "\n?ASlink-Warning-Paged Area %.8s Boundary Error\n", tap->a_id);
+           lkerr++;
+       }
+       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++;
+       }
+}
diff --git a/as/link/z80/lkdata.c b/as/link/z80/lkdata.c
new file mode 100644 (file)
index 0000000..3d075b7
--- /dev/null
@@ -0,0 +1,470 @@
+/* lkdata.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+//#include <alloc.h>
+#include "aslink.h"
+
+/*)Module      lkdata.c
+ *
+ *     The module lkdata contains the global variables
+ *     and structures used in the linker aslink.
+ */
+
+/*
+ *     Definitions for all Global Variables
+ */
+
+char   *_abs_  = { ".  .ABS." };
+
+int    lkerr;          /*      Linker error flag
+                        */
+char   *ip;            /*      Pointer into the REL file text line in ib[]
+                        */
+char   ib[NINPUT];     /*      REL file text line
+                        */
+char   *rp;            /*      pointer into the LST file
+                        *      text line in rb[]
+                        */
+char   rb[NINPUT];     /*      LST file text line being
+                        *      address relocated
+                        */
+
+char sdccopt[NINPUT]="";
+char sdccopt_module[NINPUT]="";
+char curr_module[NINPUT]="";
+
+int    oflag;          /*      Output file type flag
+                        */
+int    mflag;          /*      Map output flag
+                        */
+#ifdef SDK
+int    symflag;        /*      no$gmb .sym output flag
+                        */
+#endif
+int    xflag;          /*      Map file radix type flag
+                        */
+int    pflag;          /*      print linker command file flag
+                        */
+int    uflag;          /*      Listing relocation flag
+                        */
+int    radix;          /*      current number conversion radix:
+                        *      2 (binary), 8 (octal), 10 (decimal),
+                        *      16 (hexadecimal)
+                        */
+int    line;           /*      current line number
+                        */
+int    page;           /*      current page number
+                        */
+int    lop;            /*      current line number on page
+                        */
+int    pass;           /*      linker pass number
+                        */
+int    rtcnt;          /*      count of elements in the
+                        *      rtval[] and rtflg[] arrays
+                        */
+Addr_T rtval[NTXT];    /*      data associated with relocation
+                        */
+int    rtflg[NTXT];    /*      indicates if rtval[] value is
+                        *      to be sent to the output file.
+                        *      (always set in this linker)
+                        */
+int    hilo;           /*      REL file byte ordering
+                        */
+int    gline;          /*      LST file relocation active
+                        *      for current line
+                        */
+int    gcntr;          /*      LST file relocation active
+                        *      counter
+                        */
+
+/*
+ *     The structure lfile contains a pointer to a
+ *     file specification string, the file type, and
+ *     a link to the next lfile structure.
+ *
+ *     struct  lfile
+ *     {
+ *             struct  lfile   *f_flp;         lfile link
+ *             int     f_type;                 File type
+ *             char    *f_idp;                 Pointer to file spec
+ *     };
+ */
+struct lfile   *filep; /*      The pointers (lfile *) filep,
+                        *      (lfile *) cfp, and (FILE *) sfp
+                        *      are used in conjunction with
+                        *      the routine lk_getline() to read
+                        *      asmlnk commands from
+                        *      (1) the standard input or
+                        *      (2) or a command file
+                        *      and to read the REL files
+                        *      sequentially as defined by the
+                        *      asmlnk input commands.
+                        *
+                        *      The pointer *filep points to the
+                        *      beginning of a linked list of
+                        *      lfile structures.
+                        */
+struct lfile   *cfp;   /*      The pointer *cfp points to the
+                        *      current lfile structure
+                        */
+struct lfile   *startp;/*      asmlnk startup file structure
+                        */
+struct lfile   *linkp; /*      pointer to first lfile structure
+                        *      containing an input REL file
+                        *      specification
+                        */
+struct lfile   *lfp;   /*      pointer to current lfile structure
+                        *      being processed by parse()
+                        */
+FILE   *ofp;           /*      Output file handle
+                        *      for word formats
+                        */
+FILE   *mfp;           /*      Map output file handle
+                        */
+FILE   *rfp;           /*      File handle for output
+                        *      address relocated ASxxxx
+                        *      listing file
+                        */
+FILE   *sfp;           /*      The file handle sfp points to the
+                        *      currently open file
+                        */
+FILE   *tfp;           /*      File handle for input
+                        *      ASxxxx listing file
+                        */
+
+/*
+ *     The structures of head, area, areax, and sym are created
+ *     as the REL files are read during the first pass of the
+ *     linker.  The struct head is created upon encountering a
+ *     H directive in the REL file.  The structure contains a
+ *     link to a link file structure (struct lfile) which describes
+ *     the file containing the H directive, the number of data/code
+ *     areas contained in this header segment, the number of
+ *     symbols referenced/defined in this header segment, a pointer
+ *     to an array of pointers to areax structures (struct areax)
+ *     created as each A directive is read, and a pointer to an
+ *     array of pointers to symbol structures (struct sym) for
+ *     all referenced/defined symbols.  As H directives are read
+ *     from the REL files a linked list of head structures is
+ *     created by placing a link to the new head structure
+ *     in the previous head structure.
+ *
+ *     struct  head
+ *     {
+ *             struct  head   *h_hp;           Header link
+ *             struct  lfile  *h_lfile;        Associated file
+ *             int     h_narea;                # of areas
+ *             struct  areax **a_list;         Area list
+ *             int     h_nglob;                # of global symbols
+ *             struct  sym   **s_list;         Global symbol list
+ *             char    m_id[NCPS];             Module name
+ *     };
+ */
+struct head    *headp; /*      The pointer to the first
+                        *      head structure of a linked list
+                        */
+struct head    *hp;    /*      Pointer to the current
+                        *      head structure
+                        */
+
+/*
+ *     A structure area is created for each 'unique' data/code
+ *     area definition found as the REL files are read.  The
+ *     struct area contains the name of the area, a flag byte
+ *     which contains the area attributes (REL/CON/OVR/ABS),
+ *     an area subtype (not used in this assembler), and the
+ *     area base address and total size which will be filled
+ *     in at the end of the first pass through the REL files.
+ *     As A directives are read from the REL files a linked
+ *     list of unique area structures is created by placing a
+ *     link to the new area structure in the previous area structure.
+ *
+ *     struct  area
+ *     {
+ *             struct  area    *a_ap;          Area link
+ *             struct  areax   *a_axp;         Area extension link
+ *             Addr_T  a_addr;                 Beginning address of area
+ *             Addr_T  a_size;                 Total size of the area
+ *             char    a_type;                 Area subtype
+ *             char    a_flag;                 Flag byte
+ *             char    a_id[NCPS];             Name
+ *     };
+ */
+struct area    *areap; /*      The pointer to the first
+                        *      area structure of a linked list
+                        */
+struct area    *ap;    /*      Pointer to the current
+                        *      area structure
+                        */
+
+/*
+ *     An areax structure is created for every A directive found
+ *     while reading the REL files.  The struct areax contains a
+ *     link to the 'unique' area structure referenced by the A
+ *     directive and to the head structure this area segment is
+ *     a part of.  The size of this area segment as read from the
+ *     A directive is placed in the areax structure.  The beginning
+ *     address of this segment will be filled in at the end of the
+ *     first pass through the REL files.  As A directives are read
+ *     from the REL files a linked list of areax structures is
+ *     created for each unique area.  The final areax linked
+ *     list has at its head the 'unique' area structure linked
+ *     to the linked areax structures (one areax structure for
+ *     each A directive for this area).
+ *
+ *     struct  areax
+ *     {
+ *             struct  areax   *a_axp;         Area extension link
+ *             struct  area    *a_bap;         Base area link
+ *             struct  head    *a_bhp;         Base header link
+ *             Addr_T  a_addr;                 Beginning address of section
+ *             Addr_T  a_size;                 Size of the area in section
+ *     };
+ */
+struct areax   *axp;   /*      Pointer to the current
+                        *      areax structure
+                        */
+
+/*
+ *     A sym structure is created for every unique symbol
+ *     referenced/defined while reading the REL files.  The
+ *     struct sym contains the symbol's name, a flag value
+ *     (not used in this linker), a symbol type denoting
+ *     referenced/defined, and an address which is loaded
+ *     with the relative address within the area in which
+ *     the symbol was defined.  The sym structure also
+ *     contains a link to the area where the symbol was defined.
+ *     The sym structures are linked into linked lists using
+ *     the symbol link element.
+ *
+ *     struct  sym
+ *     {
+ *             struct  sym     *s_sp;          Symbol link
+ *             struct  areax   *s_axp;         Symbol area link
+ *             char    s_type;                 Symbol subtype
+ *             char    s_flag;                 Flag byte
+ *             Addr_T  s_addr;                 Address
+ *             char    s_id[NCPS];             Name
+ *     };
+ */
+struct sym *symhash[NHASH]; /* array of pointers to NHASH
+                             * linked symbol lists
+                             */
+/*
+ *     The struct base contains a pointer to a
+ *     base definition string and a link to the next
+ *     base structure.
+ *
+ *     struct  base
+ *     {
+ *             struct  base  *b_base;          Base link
+ *             char          *b_strp;          String pointer
+ *     };
+ */
+struct base    *basep; /*      The pointer to the first
+                        *      base structure
+                        */
+struct base    *bsp;   /*      Pointer to the current
+                        *      base structure
+                        */
+
+/*
+ *     The struct globl contains a pointer to a
+ *     global definition string and a link to the next
+ *     global structure.
+ *
+ *     struct  globl
+ *     {
+ *             struct  globl *g_globl;         Global link
+ *             char          *g_strp;          String pointer
+ *     };
+ */
+struct globl   *globlp;/*      The pointer to the first
+                        *      globl structure
+                        */
+struct globl   *gsp;   /*      Pointer to the current
+                        *      globl structure
+                        */
+
+/*
+ *     A structure sdp is created for each 'unique' paged
+ *     area definition found as the REL files are read.
+ *     As P directives are read from the REL files a linked
+ *     list of unique sdp structures is created by placing a
+ *     link to the new sdp structure in the previous area structure.
+ *
+ *     struct  sdp
+ *     {
+ *             struct  area  *s_area;  Paged Area link
+ *             struct  areax *s_areax; Paged Area Extension Link
+ *             Addr_T  s_addr;         Page address offset
+ *     };
+ */
+struct sdp     sdp;    /* Base Page Structure */
+
+/*
+ *     The structure rerr is loaded with the information
+ *     required to report an error during the linking
+ *     process.  The structure contains an index value
+ *     which selects the areax structure from the header
+ *     areax structure list, a mode value which selects
+ *     symbol or area relocation, the base address in the
+ *     area section, an area/symbol list index value, and
+ *     an area/symbol offset value.
+ *
+ *     struct  rerr
+ *     {
+ *             int     aindex;         Linking area
+ *             int     mode;           Relocation mode
+ *             Addr_T  rtbase;         Base address in section
+ *             int     rindex;         Area/Symbol reloaction index
+ *             Addr_T  rval;           Area/Symbol offset value
+ *     };
+ */
+struct rerr    rerr;   /*      Structure containing the
+                        *      linker error information
+                        */
+
+/*
+ *     The structure lbpath is created for each library
+ *     path specification input by the -k option.  The
+ *     lbpath structures are linked into a list using
+ *     the next link element.
+ *
+ *     struct lbpath {
+ *             struct  lbpath  *next;
+ *             char            *path;
+ *     };
+ */
+struct lbpath  *lbphead;       /*      pointer to the first
+                                *      library path structure
+                                */
+
+/*
+ *     The structure lbname is created for all combinations of the
+ *     library path specifications (input by the -k option) and the
+ *     library file specifications (input by the -l option) that
+ *     lead to an existing file.  The element path points to
+ *     the path string, element libfil points to the library
+ *     file string, and the element libspc is the concatenation
+ *     of the valid path and libfil strings.
+ *
+ *     The lbpath structures are linked into a list
+ *     using the next link element.
+ *
+ *     Each library file contains a list of object files
+ *     that are contained in the particular library. e.g.:
+ *
+ *             \iolib\termio
+ *             \inilib\termio
+ *
+ *     Only one specification per line is allowed.
+ *
+ *     struct lbname {
+ *             struct  lbname  *next;
+ *             char            *path;
+ *             char            *libfil;
+ *             char            *libspc;
+ *     };
+ */
+struct lbname  *lbnhead;       /*      pointer to the first
+                                *      library name structure
+                                */
+
+/*
+ *     The function fndsym() searches through all combinations of the
+ *     library path specifications (input by the -k option) and the
+ *     library file specifications (input by the -l option) that
+ *     lead to an existing file for a symbol definition.
+ *
+ *     The structure lbfile is created for the first library
+ *     object file which contains the definition for the
+ *     specified undefined symbol.
+ *
+ *     The element libspc points to the library file path specification
+ *     and element relfil points to the object file specification string.
+ *     The element filspc is the complete path/file specification for
+ *     the library file to be imported into the linker.  The
+ *     file specicifation may be formed in one of two ways:
+ *
+ *     (1)     If the library file contained an absolute
+ *             path/file specification then this becomes filspc.
+ *             (i.e. C:\...)
+ *
+ *     (2)     If the library file contains a relative path/file
+ *             specification then the concatenation of the path
+ *             and this file specification becomes filspc.
+ *             (i.e. \...)
+ *
+ *     The lbpath structures are linked into a list
+ *     using the next link element.
+ *
+ *     struct lbfile {
+ *             struct  lbfile  *next;
+ *             char            *libspc;
+ *             char            *relfil;
+ *             char            *filspc;
+ *     };
+ */
+struct lbfile  *lbfhead;       /*      pointer to the first
+                                *      library file structure
+                                */
+
+/*
+ *     array of character types, one per
+ *     ASCII character
+ */
+unsigned char  ctype[128] = {
+/*NUL*/        ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
+/*BS*/ ILL,    SPACE,  ILL,    ILL,    SPACE,  ILL,    ILL,    ILL,
+/*DLE*/        ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
+/*CAN*/        ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
+/*SPC*/        SPACE,  ETC,    ETC,    ETC,    LETTER, BINOP,  BINOP,  ETC,
+/*(*/  ETC,    ETC,    BINOP,  BINOP,  ETC,    BINOP,  LETTER, BINOP,
+/*0*/  DGT2,   DGT2,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,
+/*8*/  DGT10,  DGT10,  ETC,    ETC,    BINOP,  ETC,    BINOP,  ETC,
+/*@*/  ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
+/*H*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*P*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*X*/  LETTER, LETTER, LETTER, ETC,    ETC,    ETC,    BINOP,  LETTER,
+/*`*/  ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
+/*h*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*p*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
+/*x*/  LETTER, LETTER, LETTER, ETC,    BINOP,  ETC,    ETC,    ETC
+};
+
+/*
+ *     an array of characters which
+ *     perform the case translation function
+ */
+#if    CASE_SENSITIVE
+#else
+char   ccase[128] = {
+/*NUL*/        '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+/*DLE*/        '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+/*CAN*/        '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+/*SPC*/        '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+/*(*/  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+/*0*/  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+/*8*/  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+/*@*/  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+/*H*/  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+/*P*/  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+/*X*/  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+/*`*/  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+/*h*/  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+/*p*/  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+/*x*/  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177'
+};     
+#endif
diff --git a/as/link/z80/lkeval.c b/as/link/z80/lkeval.c
new file mode 100644 (file)
index 0000000..e4bfe1d
--- /dev/null
@@ -0,0 +1,398 @@
+/* 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 <alloc.h>
+#include "aslink.h"
+
+/*)Module      lkeval.c
+ *
+ *     The module lkeval.c contains the routines to evaluate
+ *     arithmetic/numerical expressions.  The functions in
+ *     lkeval.c perform a recursive evaluation of the arithmetic
+ *     expression read from the input text line.
+ *     The expression may include binary/unary operators, brackets,
+ *     symbols, labels, and constants in hexadecimal, decimal, octal
+ *     and binary.  Arithmetic operations are prioritized and
+ *     evaluated by normal arithmetic conventions.
+ *
+ *     lkeval.c contains the following functions:
+ *             int     digit()
+ *             Addr_T  eval()
+ *             Addr_T  expr()
+ *             int     oprio()
+ *             Addr_T  term()
+ *
+ *     lkeval.c contains no local/static variables
+ */
+
+/*)Function    Addr_T  eval()
+ *
+ *     The function eval() evaluates a character string to a
+ *     numerical value.
+ *
+ *     local variables:
+ *             int     c               character from input string
+ *             int     v               value of character in current radix
+ *             Addr_T  n               evaluation value
+ *
+ *     global variables:
+ *             int     radix           current number conversion radix
+ *
+ *     functions called:
+ *             int     digit()         lkeval.c
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             Input test is scanned and evaluated to a
+ *             numerical value.
+ */
+
+Addr_T
+eval()
+{
+       register int c, v;
+       register Addr_T n;
+
+       c = getnb();
+       n = 0;
+       while ((v = digit(c, radix)) >= 0) {
+               n = n*radix + v;
+               c = get();
+       }
+       unget(c);
+       return(n);
+}
+
+/*)Function    Addr_T  expr(n)
+ *
+ *             int     n               a firewall priority; all top
+ *                                     level calls (from the user)
+ *                                     should be made with n set to 0.
+ *
+ *     The function expr() evaluates an expression and
+ *     returns the value.
+ *
+ *     local variables:
+ *             int     c               current input text character
+ *             int     p               current operator priority
+ *             Addr_T  v               value returned by term()
+ *             Addr_T  ve              value returned by a
+ *                                     recursive call to expr()
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             int     lkerr           error flag
+ *             FILE *  stderr          c_library
+ *
+ *     functions called:
+ *             VOID    expr()          lkeval.c
+ *             int     fprintf()       c_library
+ *             int     getnb()         lklex.c
+ *             int     oprio()         lkeval.c
+ *             VOID    term()          lkeval.c
+ *             VOID    unget()         lklex.c
+ *
+ *
+ *     side effects:
+ *             An expression is evaluated by scanning the input
+ *             text string.
+ */
+
+Addr_T
+expr (n)
+{
+       register int c, p;
+       register Addr_T v, ve;
+
+       v = term();
+       while (ctype[c = getnb()] & BINOP) {
+               if ((p = oprio(c)) <= n)
+                       break;
+               if ((c == '>' || c == '<') && c != get()) {
+                       fprintf(stderr, "Invalid expression");
+                       lkerr++;
+                       return(v);
+               }
+               ve = expr(p);
+               if (c == '+') {
+                       v += ve;
+               } else
+               if (c == '-') {
+                       v -= ve;
+               } else {
+                       switch (c) {
+
+                       case '*':
+                               v *= ve;
+                               break;
+
+                       case '/':
+                               v /= ve;
+                               break;
+
+                       case '&':
+                               v &= ve;
+                               break;
+
+                       case '|':
+                               v |= ve;
+                               break;
+
+                       case '%':
+                               v %= ve;
+                               break;
+
+                       case '^':
+                               v ^= ve;
+                               break;
+
+                       case '<':
+                               v <<= ve;
+                               break;
+
+                       case '>':
+                               v >>= ve;
+                               break;
+                       }
+               }
+       }
+       unget(c);
+       return(v);
+}
+
+/*)Function    Addr_T  term()
+ *
+ *     The function term() evaluates a single constant
+ *     or symbol value prefaced by any unary operator
+ *     ( +, -, ~, ', ", >, or < ).
+ *
+ *     local variables:
+ *             int     c               current character
+ *             char    id[]            symbol name
+ *             int     n               value of digit in current radix
+ *             int     r               current evaluation radix
+ *             sym *   sp              pointer to a sym structure
+ *             Addr_T  v               evaluation value
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             int     lkerr           error flag
+ *
+ *     functions called:
+ *             int     digit()         lkeval.c
+ *             VOID    expr()          lkeval.c
+ *             int     fprintf()       c_library
+ *             int     get()           lklex.c
+ *             VOID    getid()         lklex.c
+ *             int     getmap()        lklex.c
+ *             int     getnb()         lklex.c
+ *             sym *   lkpsym()        lksym.c
+ *             Addr_T  symval()        lksym.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             An arithmetic term is evaluated by scanning input text.
+ */
+
+Addr_T
+term()
+{
+       register int c, r, n;
+       register Addr_T v;
+       struct sym *sp;
+       char id[NCPS];
+
+       c = getnb();
+       if (c == '#') { c = getnb(); }
+       if (c == '(') {
+               v = expr(0);
+               if (getnb() != ')') {
+                       fprintf(stderr, "Missing delimiter");
+                       lkerr++;
+               }
+               return(v);
+       }
+       if (c == '-') {
+               return(0-expr(100));
+       }
+       if (c == '~') {
+               return(~expr(100));
+       }
+       if (c == '\'') {
+               return(getmap(-1)&0377);
+       }
+       if (c == '\"') {
+               if (hilo) {
+                       v  = (getmap(-1)&0377)<<8;
+                       v |=  getmap(-1)&0377;
+               } else {
+                       v  =  getmap(-1)&0377;
+                       v |= (getmap(-1)&0377)<<8;
+               }
+               return(v);
+       }
+       if (c == '>' || c == '<') {
+               v = expr(100);
+               if (c == '>')
+                       v >>= 8;
+               return(v&0377);
+       }
+       if (ctype[c] & DIGIT) {
+               r = 10;
+               if (c == '0') {
+                       c = get();
+                       switch (c) {
+                       case 'b':
+                       case 'B':
+                               r = 2;
+                               c = get();
+                               break;
+                       case '@':
+                       case 'o':
+                       case 'O':
+                       case 'q':
+                       case 'Q':
+                               r = 8;
+                               c = get();
+                               break;
+                       case 'd':
+                       case 'D':
+                               r = 10;
+                               c = get();
+                               break;
+                       case 'h':
+                       case 'H':
+                       case 'x':
+                       case 'X':
+                               r = 16;
+                               c = get();
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               v = 0;
+               while ((n = digit(c, r)) >= 0) {
+                       v = r*v + n;
+                       c = get();
+               }
+               unget(c);
+               return(v);
+       }
+       if (ctype[c] & LETTER) {
+               getid(id, c);
+               if ((sp = lkpsym(id, 0)) == NULL) {
+                       fprintf(stderr, "Undefined symbol %8s\n", id);
+                       lkerr++;
+                       return(0);
+               } else {
+                       return(symval(sp));
+               }
+       }
+        /* Shouldn't get here. */
+        return 0;
+}
+
+/*)Function    int     digit(c, r)
+ *
+ *             int     c               digit character
+ *             int     r               current radix
+ *
+ *     The function digit() returns the value of c
+ *     in the current radix r.  If the c value is not
+ *     a number of the current radix then a -1 is returned.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+int
+digit(c, r)
+register int c, r;
+{
+       if (r == 16) {
+               if (ctype[c] & RAD16) {
+                       if (c >= 'A' && c <= 'F')
+                               return (c - 'A' + 10);
+                       if (c >= 'a' && c <= 'f')
+                               return (c - 'a' + 10);
+                       return (c - '0');
+               }
+       } else
+       if (r == 10) {
+               if (ctype[c] & RAD10)
+                       return (c - '0');
+       } else
+       if (r == 8) {
+               if (ctype[c] & RAD8)
+                       return (c - '0');
+       } else
+       if (r == 2) {
+               if (ctype[c] & RAD2)
+                       return (c - '0');
+       }
+       return (-1);
+}
+
+/*)Function    int     oprio(c)
+ *
+ *             int     c               operator character
+ *
+ *     The function oprio() returns a relative priority
+ *     for all valid unary and binary operators.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+int
+oprio(c)
+register int c;
+{
+       if (c == '*' || c == '/' || c == '%')
+               return (10);
+       if (c == '+' || c == '-')
+               return (7);
+       if (c == '<' || c == '>')
+               return (5);
+       if (c == '^')
+               return (4);
+       if (c == '&')
+               return (3);
+       if (c == '|')
+               return (1);
+       return (0);
+}
diff --git a/as/link/z80/lkgb.c b/as/link/z80/lkgb.c
new file mode 100644 (file)
index 0000000..55ae41f
--- /dev/null
@@ -0,0 +1,190 @@
+/* lkgb.c */
+
+/*
+ * P. Felber
+ */
+
+#ifdef GAMEBOY
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "aslink.h"
+
+/* Value used to fill the unused portions of the image */
+/* FFh puts less stress on a EPROM/Flash */
+#define FILLVALUE      0xFF
+
+#define CARTSIZE ((unsigned long)nb_rom_banks*16UL*1024UL)
+#define NBSEG 8UL
+#define SEGSIZE (CARTSIZE/NBSEG)
+
+#define ROMSIZE 0x8000UL
+#define BANKSTART 0x4000UL
+#define BANKSIZE 0x4000UL
+
+unsigned char *cart[NBSEG];
+
+int nb_rom_banks;
+int nb_ram_banks;
+int current_rom_bank;
+int mbc_type;
+char cart_name[16] = "";
+
+patch* patches = NULL;
+
+VOID gb(int in)
+{
+  static int first = 1;
+  unsigned long pos, chk;
+  int i;
+  patch *p;
+
+  if(first) {
+    for(i = 0; i < NBSEG; i++) {
+      if((cart[i] = malloc(SEGSIZE)) == NULL) {
+       fprintf(stderr, "ERROR: can't allocate %dth segment of memory (%d bytes)\n", i, (int)SEGSIZE);
+       exit(EXIT_FAILURE);
+      }
+      memset(cart[i], FILLVALUE, SEGSIZE);
+    }
+    first = 0;
+  }
+  if(in) {
+    if(rtcnt > 2) {
+      if(hilo == 0)
+       pos = rtval[0] | (rtval[1]<<8);
+      else
+       pos = rtval[1] | (rtval[0]<<8);
+
+      /* Perform some validity checks */
+      if(pos >= ROMSIZE) {
+       fprintf(stderr, "ERROR: address overflow (addr %lx >= %lx)\n", pos, ROMSIZE);
+       exit(EXIT_FAILURE);
+      }
+      if(current_rom_bank >= nb_rom_banks) {
+       fprintf(stderr, "ERROR: bank overflow (addr %x > %x)\n", current_rom_bank, nb_rom_banks);
+       exit(EXIT_FAILURE);
+      }
+      if(current_rom_bank > 0 && pos < BANKSTART) {
+       fprintf(stderr, "ERROR: address underflow (addr %lx < %lx)\n", pos, BANKSTART);
+       exit(EXIT_FAILURE);
+      }
+      if(nb_rom_banks == 2 && current_rom_bank > 0) {
+       fprintf(stderr, "ERROR: only 1 32kB segment with 2 bank\n");
+       exit(EXIT_FAILURE);
+      }
+      if(current_rom_bank > 1)
+       pos += (current_rom_bank-1)*BANKSIZE;
+      for(i = 2; i < rtcnt; i++) {
+       if(rtflg[i]) {
+         if(pos < CARTSIZE) {
+           if(cart[pos/SEGSIZE][pos%SEGSIZE] != FILLVALUE)
+             fprintf(stderr, "WARNING: possibly wrote twice at addr %lx (%02X->%02X)\n", pos, rtval[i], cart[pos/SEGSIZE][pos%SEGSIZE]);
+           cart[pos/SEGSIZE][pos%SEGSIZE] = rtval[i];
+         } else {
+           fprintf(stderr, "ERROR: cartridge size overflow (addr %lx >= %lx)\n", pos, CARTSIZE);
+           exit(EXIT_FAILURE);
+         }
+         pos++;
+       }
+      }
+    }
+  } else {
+    /* EOF */
+    if(cart_name[0] == 0 && linkp->f_idp != NULL) {
+      for(i = strlen(linkp->f_idp);
+         i > 0 && (isalnum((unsigned char)linkp->f_idp[i-1]) || linkp->f_idp[i-1] == '.');
+         i--)
+       ;
+      for(pos = 0; pos < 16 && linkp->f_idp[i] != '.'; pos++, i++)
+       cart_name[pos] = toupper((unsigned char)linkp->f_idp[i]);
+      if(pos < 16)
+       cart_name[pos] = 0;
+    }
+    for(pos = 0x0134, i = 0;
+       pos < 0x0144 && cart_name[i];
+       pos++, i++)
+      cart[pos/SEGSIZE][pos%SEGSIZE] = cart_name[i];
+    for(; pos < 0x0144; pos++)
+      cart[pos/SEGSIZE][pos%SEGSIZE] = 0;
+    cart[0x147/SEGSIZE][0x147%SEGSIZE] = mbc_type;
+    switch(nb_rom_banks) {
+    case 2:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 0;
+      break;
+    case 4:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 1;
+      break;
+    case 8:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 2;
+      break;
+    case 16:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 3;
+      break;
+    case 32:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 4;
+      break;
+    case 64:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 5;
+      break;
+    case 128:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 6;
+      break;
+    case 256:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 7;
+      break;
+    case 512:
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 8;
+      break;
+    default:
+      fprintf(stderr, "WARNING: unsupported number of ROM banks (%d)\n", nb_rom_banks);
+      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 0;
+      break;
+    }
+    switch(nb_ram_banks) {
+    case 0:
+      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 0;
+      break;
+    case 1:
+      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 2;
+      break;
+    case 4:
+      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 3;
+      break;
+    case 16:
+      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 4;
+      break;
+    default:
+      fprintf(stderr, "WARNING: unsupported number of RAM banks (%d)\n", nb_ram_banks);
+      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 0;
+      break;
+    }
+
+    /* Patch before calculating the checksum */
+    if(patches)
+      for(p = patches; p; p = p->next)
+       cart[p->addr/SEGSIZE][p->addr%SEGSIZE] = p->value;
+
+    /* Update complement checksum */
+    chk = 0;
+    for(pos = 0x0134; pos < 0x014D; pos++)
+      chk += cart[pos/SEGSIZE][pos%SEGSIZE];
+    cart[0x014D/SEGSIZE][0x014D%SEGSIZE] = (unsigned char)(0xE7 - (chk&0xFF));
+    /* Update checksum */
+    chk = 0;
+    cart[0x014E/SEGSIZE][0x014E%SEGSIZE] = 0;
+    cart[0x014F/SEGSIZE][0x014F%SEGSIZE] = 0;
+    for(i = 0; i < NBSEG; i++)
+      for(pos = 0; pos < SEGSIZE; pos++)
+       chk += cart[i][pos];
+    cart[0x014E/SEGSIZE][0x014E%SEGSIZE] = (unsigned char)((chk>>8)&0xFF);
+    cart[0x014F/SEGSIZE][0x014F%SEGSIZE] = (unsigned char)(chk&0xFF);
+
+    for(i = 0; i < NBSEG; i++)
+      fwrite(cart[i], 1, SEGSIZE, ofp);
+  }
+}
+
+#endif /* GAMEBOY */
diff --git a/as/link/z80/lkgg.c b/as/link/z80/lkgg.c
new file mode 100644 (file)
index 0000000..3e8bb37
--- /dev/null
@@ -0,0 +1,78 @@
+/* lkgg.c */
+
+/*
+ * P. Felber
+ */
+
+#ifdef GAMEGEAR
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+#include "aslink.h"
+
+#define CARTSIZE ((unsigned long)4*16UL*1024UL)
+#define NBSEG 8UL
+#define SEGSIZE (CARTSIZE/NBSEG)
+
+unsigned char *cart[NBSEG];
+
+#define ROMSIZE 0x10000UL
+#define BANKSIZE 0x4000UL
+
+int current_rom_bank;
+
+VOID gg(int in)
+{
+  static int first = 1;
+  unsigned long pos;
+  int i;
+
+  if(first) {
+    for(i = 0; i < NBSEG; i++) {
+      if((cart[i] = malloc(SEGSIZE)) == NULL) {
+       fprintf(stderr, "ERROR: can't allocate %dth segment of memory (%d bytes)\n", i, (int)SEGSIZE);
+       exit(EXIT_FAILURE);
+      }
+      memset(cart[i], 0, SEGSIZE);
+    }
+    first = 0;
+  }
+  if(in) {
+    if(rtcnt > 2) {
+      if(hilo == 0)
+       pos = rtval[0] | (rtval[1]<<8);
+      else
+       pos = rtval[1] | (rtval[0]<<8);
+
+      /* Perform some validity checks */
+      if(pos >= ROMSIZE) {
+       fprintf(stderr, "ERROR: address overflow (addr %lx >= %lx)\n", pos, ROMSIZE);
+       exit(EXIT_FAILURE);
+      }
+      if(current_rom_bank > 1)
+       pos += (current_rom_bank-1)*BANKSIZE;
+      for(i = 2; i < rtcnt; i++) {
+       if(rtflg[i]) {
+         if(pos < CARTSIZE) {
+           if(cart[pos/SEGSIZE][pos%SEGSIZE] != 0)
+             fprintf(stderr, "WARNING: wrote twice at addr %lx (%02X->%02X)\n", pos, rtval[i], cart[pos/SEGSIZE][pos%SEGSIZE]);
+           cart[pos/SEGSIZE][pos%SEGSIZE] = rtval[i];
+         } else {
+           fprintf(stderr, "ERROR: cartridge size overflow (addr %lx >= %lx)\n", pos, CARTSIZE);
+           exit(EXIT_FAILURE);
+         }
+         pos++;
+       }
+      }
+    }
+  } else {
+    /* EOF */
+    /* Patch before calculating the checksum */
+    for(i = 0; i < NBSEG; i++)
+      fwrite(cart[i], 1, SEGSIZE, ofp);
+  }
+}
+
+#endif /* GAMEGEAR */
diff --git a/as/link/z80/lkhead.c b/as/link/z80/lkhead.c
new file mode 100644 (file)
index 0000000..3eb127d
--- /dev/null
@@ -0,0 +1,154 @@
+/* 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 <alloc.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|A_OVR;
+}
+
+/*)Function    VOID    module()
+ *
+ *     The function module() copies the module name into
+ *     the current head structure.
+ *
+ *     local variables:
+ *             char    id[]            module id string
+ *
+ *     global variables:
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             head    *hp             Pointer to the current
+ *                                     head structure
+ *             int     lkerr           error flag
+ *             FILE *  stderr          c_library
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    getid()         lklex.c
+ *             char *  strncpy()       c_library
+ *
+ *     side effects:
+ *             The module name is copied into the head structure.
+ */
+
+/*
+ * Module Name
+ */
+VOID
+module()
+{
+       char id[NCPS];
+
+       if (headp) {
+               getid(id, -1);
+               strncpy(hp->m_id, id, NCPS);
+       } else {
+               fprintf(stderr, "No header defined\n");
+               lkerr++;
+       }
+}
diff --git a/as/link/z80/lkihx.c b/as/link/z80/lkihx.c
new file mode 100644 (file)
index 0000000..082a5fc
--- /dev/null
@@ -0,0 +1,134 @@
+/* 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 <alloc.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 function:
+ *             VOID    ihx(i)
+ *
+ *     lkihx.c contains no local variables.
+ */
+
+/*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.  
+ */
+
+/*)Function    ihx(i)
+ *
+ *             int     i               0 - process data
+ *                                     1 - end of data
+ *
+ *     The function ihx() outputs the relocated data
+ *     in the standard Intel Hex 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
+ihx(i)
+{
+       register Addr_T chksum;
+
+       if (i) {
+               if (hilo == 0) {
+                       chksum = rtval[0];
+                       rtval[0] = rtval[1];
+                       rtval[1] = chksum;
+               }
+               for (i = 0, chksum = -2; i < rtcnt; i++) {
+                       if (rtflg[i])
+                               chksum++;
+               }
+               fprintf(ofp, ":%02X", chksum);
+               for (i = 0; i < rtcnt ; i++) {
+                       if (rtflg[i]) {
+                               fprintf(ofp, "%02X", rtval[i]);
+                               chksum += rtval[i];
+                       }
+                       if (i == 1) {
+                               fprintf(ofp, "00");
+                       }
+               }
+               fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
+       } else {
+               fprintf(ofp, ":00000001FF\n");
+       }
+}
diff --git a/as/link/z80/lklex.c b/as/link/z80/lklex.c
new file mode 100644 (file)
index 0000000..1ccdeea
--- /dev/null
@@ -0,0 +1,603 @@
+/* lklex.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+/*
+ * Extensions: P. Felber, M. Hope
+ */
+
+#include <stdio.h>
+#include <string.h>
+//#include <alloc.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()
+ *             int     lk_getline()
+ *             int     getmap()
+ *             char    getnb()
+ *             int     more()
+ *             VOID    skip()
+ *             VOID    unget()
+ *
+ *     lklex.c contains no local variables.
+ */
+
+/*)Function    VOID    getid(id,c)
+ *
+ *             char *  id              a pointer to a string of
+ *                                     maximum length NCPS
+ *             int     c               mode flag
+ *                                     >=0     this is first character to
+ *                                             copy to the string buffer
+ *                                     <0      skip white space
+ *
+ *     The function getid() scans the current input text line
+ *     from the current position copying the next LETTER | DIGIT string
+ *     into the external string buffer (id).  The string ends when a non
+ *     LETTER or DIGIT character is found. The maximum number of
+ *     characters copied is NCPS.  If the input string is larger than
+ *     NCPS characters then the string is truncated, if the input string
+ *     is shorter than NCPS characters then the string is NULL filled.
+ *     If the mode argument (c) is >=0 then (c) is the first character
+ *     copied to the string buffer, if (c) is <0 then intervening white
+ *     space (SPACES and TABS) are skipped.
+ *
+ *     local variables:
+ *             char *  p               pointer to external string buffer
+ *             int     c               current character value
+ *
+ *     global variables:
+ *             char    ctype[]         a character array which defines the
+ *                                     type of character being processed.
+ *                                     This index is the character
+ *                                     being processed.
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of getnb(), get(), and unget() updates the
+ *             global pointer ip the position in the current
+ *             input text line.
+ */
+
+VOID
+getid(id, c)
+register int c;
+char *id;
+{
+       register char *p;
+
+       if (c < 0) {
+               c = getnb();
+       }
+       p = id;
+       do {
+               if (p < &id[NCPS])
+                       *p++ = c;
+       } while (ctype[c=get()] & (LETTER|DIGIT));
+       unget(c);
+       while (p < &id[NCPS])
+               *p++ = 0;
+}
+
+/*)Function    VOID    getfid(fid,c)
+ *
+ *             char *  str             a pointer to a string of
+ *                                     maximum length FILSPC
+ *             int     c               this is first character to
+ *                                     copy to the string buffer
+ *
+ *     The function getfid() scans the current input text line
+ *     from the current position copying the next string
+ *     into the external string buffer (str).  The string ends when a
+ *     non SPACE type character is found. The maximum number of
+ *     characters copied is FILSPC. If the input string is larger than
+ *     FILSPC characters then the string is truncated, if the input string
+ *     is shorter than FILSPC characters then the string is NULL filled.
+ *
+ *     local variables:
+ *             char *  p               pointer to external string buffer
+ *             int     c               current character value
+ *
+ *     global variables:
+ *             char    ctype[]         a character array which defines the
+ *                                     type of character being processed.
+ *                                     This index is the character
+ *                                     being processed.
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *
+ *     side effects:
+ *             use of get() updates the global pointer ip
+ *             the position in the current input text line.
+ */
+
+VOID
+getfid(str, c)
+register int c;
+char *str;
+{
+       register char *p;
+
+       p = str;
+       do {
+               if (p < &str[FILSPC-1])
+                       *p++ = c;
+               c = get();
+               if (c == ';')
+                       while (c)
+                               c = get();
+#ifdef SDK
+       } while (c);
+#else /* SDK */
+       } while (c && (ctype[c] != SPACE));
+#endif /* SDK */
+       while (p < &str[FILSPC])
+               *p++ = 0;
+}
+
+/*)Function    char    getnb()
+ *
+ *     The function getnb() scans the current input text
+ *     line returning the first character not a SPACE or TAB.
+ *
+ *     local variables:
+ *             int     c               current character from input
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *
+ *     side effects:
+ *             use of get() updates the global pointer ip, the position
+ *             in the current input text line
+ */
+
+char
+getnb()
+{
+       register int c;
+
+       while ((c=get())==' ' || c=='\t')
+               ;
+       return (c);
+}
+
+/*)Function    VOID    skip()
+ *
+ *     The function skip() scans the input text skipping all
+ *     letters and digits.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             
+ *     functions called:
+ *             char    get()           lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             Input letters and digits are skipped.
+ */
+
+VOID
+skip(c)
+register int c;
+{
+       if (c < 0)
+               c = getnb();
+       while (ctype[c=get()] & (LETTER|DIGIT)) { ; }
+       unget(c);
+}
+
+/*)Function    char    get()
+ *
+ *     The function get() returns the next character in the
+ *     input text line, at the end of the line a
+ *     NULL character is returned.
+ *
+ *     local variables:
+ *             int     c               current character from
+ *                                     input text line
+ *
+ *     global variables:
+ *             char *  ip              pointer into the current
+ *                                     input text line
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             updates ip to the next character position in the
+ *             input text line.  If ip is at the end of the
+ *             line, ip is not updated.
+ */
+
+char
+get()
+{
+       register int c;
+
+       if ((c = *ip) != 0)
+               ++ip;
+       return (c);
+}
+
+/*)Function    VOID    unget(c)
+ *
+ *             int     c               value of last character
+ *                                     read from input text line
+ *
+ *     If (c) is not a NULL character then the global pointer ip
+ *     is updated to point to the preceeding character in the
+ *     input text line.
+ *
+ *     NOTE:   This function does not push the character (c)
+ *             back into the input text line, only
+ *             the pointer ip is changed.
+ *
+ *     local variables:
+ *             int     c               last character read
+ *                                     from input text line
+ *
+ *     global variables:
+ *             char *  ip              position into the current
+ *                                     input text line
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             ip decremented by 1 character position
+ */
+
+VOID
+unget(c)
+{
+       if (c != 0)
+               --ip;
+}
+
+/*)Function    int     getmap(d)
+ *
+ *             int     d               value to compare with the
+ *                                     input text line character
+ *
+ *     The function getmap() converts the 'C' style characters \b, \f,
+ *     \n, \r, and \t to their equivalent ascii values and also
+ *     converts 'C' style octal constants '\123' to their equivalent
+ *     numeric values.  If the first character is equivalent to (d) then
+ *     a (-1) is returned, if the end of the line is detected then
+ *     a 'q' error terminates the parse for this line, or if the first
+ *     character is not a \ then the character value is returned.
+ *
+ *     local variables:
+ *             int     c               value of character
+ *                                     from input text line
+ *             int     n               looping counter
+ *             int     v               current value of numeric conversion
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    get()           lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of get() updates the global pointer ip the position
+ *             in the current input text line
+ */
+
+int
+getmap(d)
+{
+       register int c, n, v;
+
+       if ((c = get()) == '\0')
+               return (-1);
+       if (c == d)
+               return (-1);
+       if (c == '\\') {
+               c = get();
+               switch (c) {
+
+               case 'b':
+                       c = '\b';
+                       break;
+
+               case 'f':
+                       c = '\f';
+                       break;
+
+               case 'n':
+                       c = '\n';
+                       break;
+
+               case 'r':
+                       c = '\r';
+                       break;
+
+               case 't':
+                       c = '\t';
+                       break;
+
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+                       n = 0;
+                       v = 0;
+                       while (++n<=3 && c>='0' && c<='7') {
+                               v = (v<<3) + c - '0';
+                               c = get();
+                       }
+                       unget(c);
+                       c = v;
+                       break;
+               }
+       }
+       return (c);
+}
+
+/*)Function    int     lk_getline()
+ *
+ *     The function lk_getline() reads a line of input text from a
+ *     .rel source text file, a .lnk command file or from stdin.
+ *     Lines of text are processed from a single .lnk file or
+ *     multiple .rel files until all files have been read.
+ *     The input text line is copied into the global string ib[]
+ *     and converted to a NULL terminated string.  The function
+ *     lk_getline() returns a (1) after succesfully reading a line
+ *     or a (0) if all files have been read.
+ *     This function also opens each input .lst file and output
+ *     .rst file as each .rel file is processed.
+ *
+ *     local variables:
+ *             int     i               string length
+ *             int     ftype           file type
+ *             char *  fid             file name
+ *
+ *     global variables:
+ *             lfile   *cfp            The pointer *cfp points to the
+ *                                     current lfile structure
+ *             lfile   *filep          The pointer *filep points to the
+ *                                     beginning of a linked list of
+ *                                     lfile structures.
+ *             int     gline           get a line from the LST file
+ *                                     to translate for the RST file
+ *             char    ib[NINPUT]      REL file text line
+ *             int     pass            linker pass number
+ *             int     pflag           print linker command file flag
+ *             FILE    *rfp            The file handle to the current
+ *                                     output RST file
+ *             FILE    *sfp            The file handle sfp points to the
+ *                                     currently open file
+ *             FILE *  stdin           c_library
+ *             FILE *  stdout          c_library
+ *             FILE    *tfp            The file handle to the current
+ *                                     LST file being scanned
+ *             int     uflag           update listing flag
+ *
+ *     called functions:
+ *             FILE *  afile()         lkmain.c
+ *             int     fclose()        c_library
+ *             char *  fgets()         c_library
+ *             int     fprintf()       c_library
+ *             VOID    lkulist()       lklist.c
+ *             VOID    lkexit()        lkmain.c
+ *             int     strlen()        c_library
+ *
+ *     side effects:
+ *             The input stream is scanned.  The .rel files will be
+ *             opened and closed sequentially scanning each in turn.
+ */
+
+int
+lk_getline()
+{
+       register int i, ftype;
+       register char *fid;
+
+loop:  if (pflag && cfp && cfp->f_type == F_STD)
+               fprintf(stdout, "ASlink >> ");
+
+#ifdef SDK
+       if(cfp == NULL && filep != NULL && filep->f_type == F_CMD) {
+               char **argv = (char **)filep->f_idp;
+               if(argv[0] != NULL && strlen(argv[0]) < sizeof ib) {
+                       strcpy(ib, argv[0]);
+                       filep->f_idp = (char *)&argv[1];                        
+               } else {
+                       filep = NULL;
+                       return(0);
+               }
+       } else
+#endif /* SDK */
+       if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) {
+               if (sfp) {
+                       fclose(sfp);
+#ifdef SDK
+                       sfp = NULL;
+#endif /* SDK */
+                       lkulist(0);
+               }
+               if (cfp == NULL) {
+                       cfp = filep;
+               } else {
+                       cfp = cfp->f_flp;
+               }
+               if (cfp) {
+                       ftype = cfp->f_type;
+                       fid = cfp->f_idp;
+                       if (ftype == F_STD) {
+                               sfp = stdin;
+                       } else
+                       if (ftype == F_LNK) {
+#ifdef SDK
+                               sfp = afile(fid, "lnk", 0);
+#else /* SDK */
+                               sfp = afile(fid, "LNK", 0);
+#endif /* SDK */
+                       } else
+                       if (ftype == F_REL) {
+#ifdef SDK
+                               sfp = afile(fid, "", 0);
+                               if (uflag && pass != 0) {
+                                if ((tfp = afile(fid, "lst", 0)) != NULL) {
+                                 if ((rfp = afile(fid, "rst", 1)) == NULL) {
+#else /* SDK */
+                               sfp = afile(fid, "REL", 0);
+                               if (uflag && pass != 0) {
+                                if ((tfp = afile(fid, "LST", 0)) != NULL) {
+                                 if ((rfp = afile(fid, "RST", 1)) == NULL) {
+#endif /* SDK */
+                                       fclose(tfp);
+                                       tfp = NULL;
+                                 }
+                                }
+                               }
+                               gline = 1;
+                       } else {
+                               fprintf(stderr, "Invalid file type\n");
+                               lkexit(1);
+                       }
+                       if (sfp == NULL) {
+                               lkexit(1);
+                       }
+                       goto loop;
+               } else {
+                       filep = NULL;
+                       return(0);
+               }
+       }
+       i = strlen(ib) - 1;
+       if (ib[i] == '\n')
+               ib[i] = 0;
+       return (1);
+}
+
+/*)Function    int     more()
+ *
+ *     The function more() scans the input text line
+ *     skipping white space (SPACES and TABS) and returns a (0)
+ *     if the end of the line or a comment delimeter (;) is found,
+ *     or a (1) if their are additional characters in the line.
+ *
+ *     local variables:
+ *             int     c               next character from
+ *                                     the input text line
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    getnb()         lklex.c
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             use of getnb() and unget() updates the global pointer ip
+ *             the position in the current input text line
+ */
+
+int
+more()
+{
+       register int c;
+
+       c = getnb();
+       unget(c);
+       return( (c == '\0' || c == ';') ? 0 : 1 );
+}
+
+/*)Function    char    endline()
+ *
+ *     The function endline() scans the input text line
+ *     skipping white space (SPACES and TABS) and returns the next
+ *     character or a (0) if the end of the line is found or a
+ *     comment delimiter (;) is found.
+ *
+ *     local variables:
+ *             int     c               next character from
+ *                                     the input text line
+ *
+ *     global variables:
+ *             none
+ *
+ *     called functions:
+ *             char    getnb()         lklex.c
+ *
+ *     side effects:
+ *             Use of getnb() updates the global pointer ip the
+ *             position in the current input text line.
+ */
+
+char
+endline()
+{
+       register int c;
+
+       c = getnb();
+       return( (c == '\0' || c == ';') ? 0 : c );
+}
+
+/*)Function    VOID    chop_crlf(str)
+ *
+ *             char    *str            string to chop
+ *
+ *     The function chop_crlf() removes trailing LF or CR/LF from
+ *     str, if present.
+ *
+ *     local variables:
+ *             int     i               string length
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+VOID
+chop_crlf(str)
+char *str;
+{
+       register int i;
+
+       i = strlen(str);
+       if (i >= 1 && str[i-1] == '\n') str[i-1] = 0;
+       if (i >= 2 && str[i-2] == '\r') str[i-2] = 0;
+}
diff --git a/as/link/z80/lklibr.c b/as/link/z80/lklibr.c
new file mode 100644 (file)
index 0000000..c3761bb
--- /dev/null
@@ -0,0 +1,1297 @@
+/* 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
+ *
+ */
+
+/*
+ * Extensions: P. Felber
+ */
+
+#define EQ(A,B) !strcmp((A),(B))
+#define MAXLINE 254 /*when using fgets*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "aslink.h"
+
+#ifdef OTHERSYSTEM
+#ifdef SDK
+#ifdef UNIX
+    #define LKDIRSEP '/'
+    #define LKDIRSEPSTR "/"
+#else /* UNIX */
+       #define LKDIRSEP '\\'
+       #define LKDIRSEPSTR "\\"
+#endif /* UNIX */
+#else /* SDK */
+       #define LKDIRSEP '\\'
+       #define LKDIRSEPSTR "\\"
+#endif /* SDK */
+#endif
+
+#ifdef SDK
+    #define LKOBJEXT "o"
+#else /* SDK */
+    #define LKOBJEXT "rel"
+#endif /* SDK */
+
+/*)Module      lklibr.c
+ *
+ *     The module lklibr.c contains the functions which
+ *     (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, "\n?ASlink-Warning-Couldn't find library '%s'", 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;
+    int libfilinc=0;
+
+       if (path != NULL)
+    {
+               str = (char *) new (strlen(path) + strlen(libfil) + 6);
+               strcpy(str, path);
+
+        if (str[strlen(str)-1] != LKDIRSEP)
+        {
+                       strcat(str, LKDIRSEPSTR);
+               }
+       }
+    else
+    {
+               str = (char *) new (strlen(libfil) + 5);
+       }
+
+       if (libfil[0] == LKDIRSEP)
+    {
+        libfil++;
+        libfilinc=1;
+    }
+       
+    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*/
+        if(libfilinc) libfil--;
+        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 '.o' files associated with
+        the library.  So, get 'path' from 'str' and then chop it off and recreate 'libfil'.
+        That way putting 'path' and 'libfil' together will result into the original filepath
+        as contained in 'str'.*/
+        int j;
+        path = (char *) new (strlen(str));
+        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();
+                       break;
+               }
+       }
+}
+
+/*)Function    VOID    fndsym(name)
+ *
+ *             char    *name           symbol name to find
+ *
+ *     The function fndsym() searches through all combinations of the
+ *     library path specifications (input by the -k option) and the
+ *     library file specifications (input by the -l option) that
+ *     lead to an existing file.
+ *
+ *     The file specicifation may be formed in one of two ways:
+ *
+ *     (1)     If the library file contained an absolute
+ *             path/file specification then this becomes filspc.
+ *             (i.e. C:\...)
+ *
+ *     (2)     If the library file contains a relative path/file
+ *             specification then the concatenation of the path
+ *             and this file specification becomes filspc.
+ *             (i.e. \...)
+ *
+ *     The structure lbfile is created for the first library
+ *     object file which contains the definition for the
+ *     specified undefined symbol.
+ *
+ *     If the library file [.LIB] contains file specifications for
+ *     non existant files, no errors are returned.
+ *
+ *     local variables:
+ *             char    buf[]           [.REL] file input line
+ *             char    c               [.REL] file input character
+ *             FILE    *fp             file handle for object file
+ *             lbfile  *lbf            temporary pointer
+ *             lbfile  *lbfh           pointer to lbfile structure
+ *             FILE    *libfp          file handle for library file
+ *             lbname  *lbnh           pointer to lbname structure
+ *             char    *path           file specification path
+ *             char    relfil[]        [.REL] file specification
+ *             char    *str            combined path and file specification
+ *             char    symname[]       [.REL] file symbol string
+ *
+ *     global variables:
+ *             lbname  *lbnhead        The pointer to the first
+ *                                     name structure
+ *             lbfile  *lbfhead        The pointer to the first
+ *                                     file structure
+ *
+ *      functions called:
+ *             int     fclose()        c_library
+ *             int     fgets()         c_library
+ *             FILE    *fopen()        c_library
+ *             VOID    free()          c_library
+ *             char    getnb()         lklex.c
+ *             VOID    lkexit()        lkmain.c
+ *             VOID    loadfile()      lklibr.c
+ *             VOID *  new()           lksym.c
+ *             char *  sprintf()       c_library
+ *             int     sscanf()        c_library
+ *             char *  strcat()        c_library
+ *             char *  strchr()        c_library
+ *             char *  strcpy()        c_library
+ *             int     strlen()        c_library
+ *             int     strncmp()       c_library
+ *             VOID    unget()         lklex.c
+ *
+ *     side effects:
+ *             If the symbol is found then a new lbfile structure
+ *             is created and added to the linked list of lbfile
+ *             structures.  The file containing the found symbol
+ *             is linked.
+ */
+
+#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)
+        {
+            //printf("ThisSym->name=%s\n", ThisSym->name);
+                       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*/
+                                           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%c%s", DirLib, ModName, FSEPX, LKOBJEXT);
+                    This->filename=(char *)new(strlen(buff)+1);
+                    strcpy(This->filename, buff);
+
+                    This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/
+                               }
+                else if(EQ(FLine, "</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;
+
+       /* Iterate through all library files */
+    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 (str[strlen(str)-1] != LKDIRSEP)
+                {
+                                       strcat(str, LKDIRSEPSTR);
+                }
+#endif
+                       }
+            else
+            {
+                strcpy(str, "");
+                       }
+
+            if(strcmp(relfil, "<SDCCLIB>")==0)
+                       {
+                /*Get the built in index of a library*/
+                               This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This);
+                               break; /*get the index for next library*/
+                       }
+            
+            /*From here down, build the index for the original library format*/
+
+            if (relfil[0] == LKDIRSEP)
+            {
+                               strcat(str, relfil+1);
+                       }
+            else
+            {
+                               strcat(str, relfil);
+                       }
+                               
+            if(strchr(relfil, FSEPX) == NULL)
+            {
+                               sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT);
+                       }
+
+            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; /*There should be a 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);
+
+                               ThisSym = This->symbols = NULL;
+
+                               /*
+                                * Read in the object file.  Look for lines that
+                                * begin with "S" and end with "D".  These are
+                                * symbol table definitions.  If we find one, see
+                                * if it is our symbol.  Make sure we only read in
+                                * our object file and don't go into the next one.
+                                */
+                       
+                               while (fgets(buf, NINPUT, fp) != NULL)
+                {
+                                       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 */
+               } /* 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 */
+
+
+/*Check for a symbol in a SDCC library.  If found, add the embedded .rel.
+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)], "%c%s", FSEPX, LKOBJEXT);
+
+                                               /*If this module has been loaded already don't load it again.*/
+                                               lbf = lbfhead;
+                                               while (lbf)
+                                               {
+                                                       if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/
+                                                       lbf=lbf->next;
+                                               }
+                                               
+                                               /*Add the embedded file to the list of files to be loaded in
+                                               the second pass.  That is performed latter by the function
+                                               library() below.*/
+                                               lbfh = (struct lbfile *) new (sizeof(struct lbfile));
+                                               if (lbfhead == NULL)
+                                               {
+                                                       lbfhead = lbfh;
+                                               }
+                                               else
+                                               {
+                                                       lbf = lbfhead;
+                                                       while (lbf->next)
+                                                       lbf = lbf->next;
+                                                       lbf->next = lbfh;
+                                               }
+
+                                               lbfh->libspc = PathLib;
+                                               lbfh->filspc = DirLib;
+                                               lbfh->relfil = (char *) new (strlen(ModName) + 1);
+                                               strcpy(lbfh->relfil, ModName);
+                                               /*Library embedded file, so lbfh->offset must be >=0*/
+                                               lbfh->offset = IndexOffset+FileOffset;
+                                               
+                                               /*Jump to where the .rel begins and load it.*/
+                                               fseek(libfp, lbfh->offset, SEEK_SET);
+                                               LoadRel(PathLib, libfp, ModName);
+
+                                               return 1; /*Found the symbol, so success!*/
+                                       }
+                               }
+            break;
+                       
+                       default:
+                               return 0; /*It should never reach this point, but just in case...*/
+                       break;
+        }
+    }
+
+       return 0; /*The symbol is not in this library*/
+}
+
+int
+fndsym(name)
+char *name;
+{
+       FILE *libfp, *fp;
+       struct lbname *lbnh;
+       struct lbfile *lbfh, *lbf;
+       char relfil[NINPUT+2];
+       char buf[NINPUT+2];
+       char symname[NINPUT];
+       char *path,*str;
+       char c;
+       int result;
+
+       /*
+        * Search through every library in the linked list "lbnhead".
+        */
+
+/*1*/  for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) {
+               if ((libfp = fopen(lbnh->libspc, "r")) == NULL) {
+                       fprintf(stderr, "Cannot open library file %s\n",
+                               lbnh->libspc);
+                       lkexit(1);
+               }
+               path = lbnh->path;
+
+               /*
+                * Read in a line from the library file.
+                * This is the relative file specification
+                * for a .REL file in this library.
+                */
+
+/*2*/          while (fgets(relfil, NINPUT, libfp) != NULL) {
+                   relfil[NINPUT+1] = '\0';
+                   chop_crlf(relfil);
+                   if (path != NULL) {
+                       str = (char *) new (strlen(path)+strlen(relfil)+6);
+                       strcpy(str,path);
+#ifdef OTHERSYSTEM
+#ifdef SDK
+#ifdef UNIX
+                       if (str[strlen(str)-1] != '/') {
+                               strcat(str,"/");
+#else /* UNIX */
+                       if (str[strlen(str)-1] != '\\') {
+                               strcat(str,"\\");
+#endif /* UNIX */
+#else /* SDK */
+                       if (str[strlen(str)-1] != '\\') {
+                               strcat(str,"\\");
+#endif /* SDK */
+                       }
+#endif
+                   } else {
+                       str = (char *) new (strlen(relfil) + 5);
+                   }
+
+            /*See if this is a library with embedded files*/
+                       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*/
+#ifdef SDK
+#ifdef UNIX
+                   if (relfil[0] == '/') {
+#else /* UNIX */
+                   if (relfil[0] == '\\') {
+#endif /* UNIX */
+#else /* SDK */
+                   if (relfil[0] == '\\') {
+#endif /* SDK */
+                       strcat(str,relfil+1);
+                   } else {
+                       strcat(str,relfil);
+                   }
+                   if(strchr(relfil, FSEPX) == NULL)
+            {
+                sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT);
+                   }
+
+/*3*/              if ((fp = fopen(str, "r")) != NULL) {
+
+                       /*
+                        * Read in the object file.  Look for lines that
+                        * begin with "S" and end with "D".  These are
+                        * symbol table definitions.  If we find one, see
+                        * if it is our symbol.  Make sure we only read in
+                        * our object file and don't go into the next one.
+                        */
+                       
+/*4*/                  while (fgets(buf, NINPUT, fp) != NULL) {
+
+                       buf[NINPUT+1] = '\0';
+                       buf[strlen(buf) - 1] = '\0';
+
+                       /*
+                        * Skip everything that's not a symbol record.
+                        */
+                       if (buf[0] != 'S')
+                               continue;
+
+                       /*
+                        * When a 'T line' is found terminate file scan.
+                        * All 'S line's preceed 'T line's in .REL files.
+                        */
+                       if (buf[0] == 'T')
+                               break;
+
+                       sscanf(buf, "S %s %c", symname, &c);
+
+                       /*
+                        * If we find a symbol definition for the
+                        * symbol we're looking for, load in the
+                        * file and add it to lbfhead so it gets
+                        * loaded on pass number 2.
+                        */
+/*5*/                  if (strncmp(symname, name, NCPS) == 0 && c == 'D') {
+
+                       lbfh = (struct lbfile *) new (sizeof(struct lbfile));
+                       if (lbfhead == NULL) {
+                               lbfhead = lbfh;
+                       } else {
+                               lbf = lbfhead;
+                               while (lbf->next)
+                                       lbf = lbf->next;
+                               lbf->next = lbfh;
+                       }
+                       lbfh->libspc = lbnh->libspc;
+                       lbfh->filspc = str;
+                       lbfh->relfil = (char *) new (strlen(relfil) + 1);
+                       lbfh->offset = -1; /*Stand alone rel file*/
+                       strcpy(lbfh->relfil,relfil);
+                       fclose(fp);
+                       fclose(libfp);
+                       loadfile(str);
+                       return (1);
+
+/*5*/                  }
+
+/*4*/                  }
+                   fclose(fp);
+/*3*/              }
+
+                   free(str);
+/*2*/          }
+               fclose(libfp);
+/*1*/  }
+       return(0);
+}
+#endif /* INDEXLIB */
+
+void loadfile_SdccLib(char * libspc, char * module, long offset)
+{
+       FILE *fp;
+
+#ifdef __CYGWIN__
+    char posix_path[PATH_MAX];
+    void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
+    cygwin_conv_to_full_posix_path(libspc, posix_path);
+    fp = fopen(posix_path, "r");
+#else
+    fp = fopen(libspc,"r");
+#endif
+
+       if (fp != NULL)
+       {
+               fseek(fp, offset, SEEK_SET);
+               LoadRel(libspc, fp, module);
+               fclose(fp);
+       }
+    else
+    {
+               fprintf(stderr, "?Aslink-Error-Opening library '%s'\n", libspc);
+               lkexit(1);
+    }
+}
+
+/*)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()          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];
+       int i;
+
+#ifdef __CYGWIN__
+    char posix_path[PATH_MAX];
+    void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
+    cygwin_conv_to_full_posix_path(filspc, posix_path);
+    fp = fopen(posix_path, "r");
+#else
+    fp = fopen(filspc,"r");
+#endif
+
+       if (fp != NULL)
+    {
+               while (fgets(str, NINPUT, fp) != NULL)
+        {
+                       str[NINPUT+1] = '\0';
+                       i = strlen(str) - 1;
+                       if (str[i] == '\n')
+                               str[i] = '\0';
+                       ip = str;
+                       link();
+               }
+               fclose(fp);
+       }
+    else
+    {
+               fprintf(stderr, "?Aslink-Error-Opening library '%s'\n", filspc);
+               lkexit(1);
+    }
+}
diff --git a/as/link/z80/lklist.c b/as/link/z80/lklist.c
new file mode 100644 (file)
index 0000000..827b44c
--- /dev/null
@@ -0,0 +1,1270 @@
+/* lklist.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "aslink.h"
+
+/*)Module      lklist.c
+ *
+ *     The module lklist.c contains the functions which
+ *     output the linker .map file and produce a relocated
+ *     listing .rst file.
+ *
+ *     lklist.c contains the following functions:
+ *             int     dgt()
+ *             VOID    lstarea()
+ *             VOID    lkulist()
+ *             VOID    lkalist()
+ *             VOID    lkglist()
+ *             VOID    newpag()
+ *             VOID    slew()
+ *
+ *     lklist.c contains no local variables.
+ */
+
+/*)Function    VOID    slew(fp)
+ *
+ *             FILE *  fp              output file handle
+ *
+ *     The function slew() increments the page line counter.
+ *     If the number of lines exceeds the maximum number of
+ *     lines per page then a page skip and a page header are
+ *     output.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *
+ *     global variables:
+ *             int     lop             current line number on page
+ *             int     xflag           Map file radix type flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    newpag()        lklist.c
+ *
+ *     side effects:
+ *             The page line and the page count may be updated.
+ */
+
+VOID
+slew(fp)
+FILE *fp;
+{
+       register int i;
+
+       if (lop++ >= NLPP) {
+               newpag(fp);
+               if (xflag == 0) {
+                       fprintf(fp, "Hexidecimal\n\n");
+               } else
+               if (xflag == 1) {
+                       fprintf(fp, "Octal\n\n");
+               } else
+               if (xflag == 2) {
+                       fprintf(fp, "Decimal\n\n");
+               }
+               fprintf(fp, "Area       Addr   Size");
+               fprintf(fp, "   Decimal Bytes (Attributes)\n");
+               for(i=0;i<4;++i)
+                       fprintf(fp, "      Value--Global");
+               fprintf(fp, "\n\n");
+               lop += 6;
+       }
+}
+
+/*)Function    VOID    newpag()
+ *
+ *     The function newpag() outputs a page skip, writes the
+ *     first page header line, sets the line count to 1, and
+ *     increments the page counter.
+ *
+ *     local variables:
+ *             none
+ *
+ *     global variables:
+ *             int     lop             current line number on page
+ *             int     page            current page number
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *
+ *     side effects:
+ *             The page and line counters are updated.
+ */
+
+VOID
+newpag(fp)
+FILE *fp;
+{
+       fprintf(fp, "\fASxxxx Linker %s,  page %u.\n", VERSION, ++page);
+       lop = 1;
+}
+
+#if    NCPS-8
+
+/* NCPS != 8 */
+/*)Function    VOID    lstarea(xp)
+ *
+ *             area *  xp              pointer to an area structure
+ *
+ *     The function lstarea() creates the linker map output for
+ *     the area specified by pointer xp.  The generated output
+ *     area header includes the area name, starting address,
+ *     size of area, number of words (in decimal), and the
+ *     area attributes.  The symbols defined in this area are
+ *     sorted by ascending address and output one per line
+ *     in the selected radix.
+ *
+ *     local variables:
+ *             areax * oxp             pointer to an area extension structure
+ *             int     c               character value
+ *             int     i               loop counter
+ *             int     j               bubble sort update status
+ *             char *  ptr             pointer to an id string
+ *             int     nmsym           number of symbols in area
+ *             Addr_T  a0              temporary
+ *             Addr_T  ai              temporary
+ *             Addr_T  aj              temporary
+ *             sym *   sp              pointer to a symbol structure
+ *             sym **  p               pointer to an array of
+ *                                     pointers to symbol structures
+ *
+ *     global variables:
+ *             FILE    *mfp            Map output file handle
+ *             sym *symhash[NHASH]     array of pointers to NHASH
+ *                                     linked symbol lists
+ *             int     xflag           Map file radix type flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    free()          c_library
+ *             char *  malloc()        c_library
+ *             char    putc()          c_library
+ *             VOID    slew()          lklist.c
+ *
+ *     side effects:
+ *             Map output generated.
+ */
+
+#ifndef MLH_MAP
+VOID
+lstarea(xp)
+struct area *xp;
+{
+//     register struct area *op;
+       register struct areax *oxp;
+       register c, i, j;
+       register char *ptr;
+       int nmsym;
+       Addr_T a0, ai, aj;
+       struct sym *sp;
+       struct sym **p;
+
+       putc('\n', mfp);
+       if (xflag == 0) {
+               fprintf(mfp, "Hexidecimal\n\n");
+       } else
+       if (xflag == 1) {
+               fprintf(mfp, "Octal\n\n");
+       } else
+       if (xflag == 2) {
+               fprintf(mfp, "Decimal\n\n");
+       }
+       fprintf(mfp, "Area                               ");
+       fprintf(mfp, "Addr   Size   Decimal Bytes (Attributes)\n");
+       fprintf(mfp, "--------------------------------   ");
+       fprintf(mfp, "----   ----   ------- ----- ------------\n");
+       /*
+        * Output Area Header
+        */
+       ptr = &xp->a_id[0];
+       while (ptr < &xp->a_id[NCPS]) {
+               if ((c = *ptr++) != 0) {
+                       putc(c, mfp);
+               } else {
+                       putc(' ', mfp);
+               }
+       }
+       ai = xp->a_addr;
+       aj = xp->a_size;
+       if (xflag == 0) {
+               fprintf(mfp, "   %04X   %04X", ai, aj);
+       } else
+       if (xflag == 1) {
+               fprintf(mfp, " %06o %06o", ai, aj);
+       } else
+       if (xflag == 2) {
+               fprintf(mfp, "  %05u  %05u", ai, aj);
+       }
+       fprintf(mfp, " = %6u. bytes ", aj);
+       if (xp->a_flag & A_ABS) {
+               fprintf(mfp, "(ABS");
+       } else {
+               fprintf(mfp, "(REL");
+       }
+       if (xp->a_flag & A_OVR) {
+               fprintf(mfp, ",OVR");
+       } else {
+               fprintf(mfp, ",CON");
+       }
+       if (xp->a_flag & A_PAG) {
+               fprintf(mfp, ",PAG");
+       }
+       fprintf(mfp, ")");
+       if (xp->a_flag & A_PAG) {
+               ai = (ai & 0xFF);
+               aj = (aj > 256);
+               if (ai || aj) { fprintf(mfp, "  "); }
+               if (ai)      { fprintf(mfp, " Boundary"); }
+               if (ai & aj)  { fprintf(mfp, " /"); }
+               if (aj)      { fprintf(mfp, " Length"); }
+               if (ai || aj) { fprintf(mfp, " Error"); }
+       }
+
+       /*
+        * 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;
+       }
+
+       /*
+        * 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;
+               }
+       }
+
+       /*
+        * Symbol Table Output
+        */
+       i = 0;
+       fprintf(mfp, "\n\n");
+       fprintf(mfp, "      Value  Global\n");
+       fprintf(mfp, "      -----  --------------------------------");
+       while (i < nmsym) {
+               fprintf(mfp, "\n");
+               fprintf(mfp, "     ");
+
+               sp = p[i];
+               aj = sp->s_addr + sp->s_axp->a_addr;
+               if (xflag == 0) {
+                       fprintf(mfp, "  %04X  ", aj);
+               } else
+               if (xflag == 1) {
+                       fprintf(mfp, "%06o  ", aj);
+               } else
+               if (xflag == 2) {
+                       fprintf(mfp, " %05u  ", aj);
+               }
+               ptr = &sp->s_id[0];
+               while (ptr < &sp->s_id[NCPS]) {
+                       if ((c = *ptr++) != 0) {
+                               putc(c, mfp);
+                       } else {
+                               putc(' ', mfp);
+                       }
+               }
+               i++;
+       }
+       putc('\n', mfp);
+       free(p);
+}
+#else
+VOID lstarea(struct area *xp)
+{
+       register struct areax *oxp;
+       register int i, j;
+       int nmsym;
+       Addr_T a0, ai = 0, aj = 0;
+       struct sym *sp;
+       struct sym **p;
+
+       /*
+        * Find number of symbols in area
+        */
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp)
+                                       ++nmsym;
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+
+       /*
+        * Symbol Table Output
+        */
+       if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) {
+               fprintf(mfp, "AREA %s\n", xp->a_id );
+               switch (xflag) {
+                       case 1:
+                               fprintf(mfp, "\tRADIX OCTAL\n" );
+                               break;
+                       case 2:
+                               fprintf(mfp, "\tRADIX DEC\n" );
+                               break;
+                       default:
+                               fprintf(mfp, "\tRADIX HEX\n" );
+                               break;
+               }
+               fprintf( mfp,   "\tBASE %04X\n"
+                               "\tSIZE %04X\n"
+                               "\tATTRIB "
+                       , xp->a_addr, xp->a_size );
+               if (xp->a_flag & A_ABS) {
+                       fprintf(mfp, "ABS");
+               } else {
+                       fprintf(mfp, "REL");
+               }
+               if (xp->a_flag & A_OVR) {
+                       fprintf(mfp, " OVR");
+               } else {
+                       fprintf(mfp, " CON");
+               }
+               if (xp->a_flag & A_PAG) {
+                       fprintf(mfp, " PAG");
+               }
+               if (xp->a_flag & A_PAG) {
+                       ai = (ai & 0xFF);
+                       aj = (aj > 256);
+                       if (ai || aj) { fprintf(mfp, "  "); }
+                       if (ai)      { fprintf(mfp, " Boundary"); }
+                       if (ai & aj)  { fprintf(mfp, " /"); }
+                       if (aj)      { fprintf(mfp, " Length"); }
+                       if (ai || aj) { fprintf(mfp, " Error"); }
+               }
+
+               fprintf( mfp,"\n");
+               if (nmsym>0) {
+                       /*
+                        * Allocate space for an array of pointers to symbols
+                        * and load array.
+                        */
+                       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
+                           == NULL) {
+                               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
+                               return;
+                       }
+                       nmsym = 0;
+                       oxp = xp->a_axp;
+                       while (oxp) {
+                               for (i=0; i<NHASH; i++) {
+                                       sp = symhash[i];
+                                       while (sp != NULL) {
+                                               if (oxp == sp->s_axp) {
+                                                       p[nmsym++] = sp;
+                                               }
+                                               sp = sp->s_sp;
+                                       }
+                               }
+                               oxp = oxp->a_axp;
+                       }
+
+                       /*
+                        * Bubble Sort of Addresses in Symbol Table Array
+                        */
+                       j = 1;
+                       while (j) {
+                               j = 0;
+                               sp = p[0];
+                               a0 = sp->s_addr + sp->s_axp->a_addr;
+                               for (i=1; i<nmsym; ++i) {
+                                       sp = p[i];
+                                       ai = sp->s_addr + sp->s_axp->a_addr;
+                                       if (a0 > ai) {
+                                               j = 1;
+                                               p[i] = p[i-1];
+                                               p[i-1] = sp;
+                                       }
+                                       a0 = ai;
+                               }
+                       }
+
+                       fprintf( mfp, "\tGLOBALS\n");
+                       i = 0;
+                       while (i < nmsym) {
+                               fprintf(mfp, "\t\t%s\t%04X\n", p[i]->s_id, p[i]->s_addr + p[i]->s_axp->a_addr );
+                               i++;
+                       }
+                       free(p);
+               }
+       }
+}
+#endif /* MLH_MAP */
+#else
+
+/* NCPS == 8 */
+/*)Function    VOID    lstarea(xp)
+ *
+ *             area *  xp              pointer to an area structure
+ *
+ *     The function lstarea() creates the linker map output for
+ *     the area specified by pointer xp.  The generated output
+ *     area header includes the area name, starting address,
+ *     size of area, number of words (in decimal), and the
+ *     area attributes.  The symbols defined in this area are
+ *     sorted by ascending address and output four per line
+ *     in the selected radix.
+ *
+ *     local variables:
+ *             areax * oxp             pointer to an area extension structure
+ *             int     c               character value
+ *             int     i               loop counter
+ *             int     j               bubble sort update status
+ *             char *  ptr             pointer to an id string
+ *             int     nmsym           number of symbols in area
+ *             Addr_T  a0              temporary
+ *             Addr_T  ai              temporary
+ *             Addr_T  aj              temporary
+ *             sym *   sp              pointer to a symbol structure
+ *             sym **  p               pointer to an array of
+ *                                     pointers to symbol structures
+ *
+ *     global variables:
+ *             FILE    *mfp            Map output file handle
+ *             sym *symhash[NHASH]     array of pointers to NHASH
+ *                                     linked symbol lists
+ *             int     xflag           Map file radix type flag
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID    free()          c_library
+ *             char *  malloc()        c_library
+ *             char    putc()          c_library
+ *             VOID    slew()          lklist.c
+ *
+ *     side effects:
+ *             Map output generated.
+ */
+
+VOID
+lstarea(xp)
+struct area *xp;
+{
+       register struct areax *oxp;
+       register c, i, j;
+       register char *ptr;
+       int nmsym;
+       Addr_T a0, ai, aj;
+       struct sym *sp;
+       struct sym **p;
+
+       putc('\n', mfp);
+       slew(mfp);
+       /*
+        * Output Area Header
+        */
+       ptr = &xp->a_id[0];
+       while (ptr < &xp->a_id[NCPS]) {
+               if ((c = *ptr++) != 0) {
+                       putc(c, mfp);
+               } else {
+                       putc(' ', mfp);
+               }
+       }
+       ai = xp->a_addr;
+       aj = xp->a_size;
+       if (xflag == 0) {
+               fprintf(mfp, "   %04X   %04X", ai, aj);
+       } else
+       if (xflag == 1) {
+               fprintf(mfp, " %06o %06o", ai, aj);
+       } else
+       if (xflag == 2) {
+               fprintf(mfp, "  %05u  %05u", ai, aj);
+       }
+       fprintf(mfp, " = %6u. bytes ", aj);
+       if (xp->a_flag & A_ABS) {
+               fprintf(mfp, "(ABS");
+       } else {
+               fprintf(mfp, "(REL");
+       }
+       if (xp->a_flag & A_OVR) {
+               fprintf(mfp, ",OVR");
+       } else {
+               fprintf(mfp, ",CON");
+       }
+       if (xp->a_flag & A_PAG) {
+               fprintf(mfp, ",PAG");
+       }
+       fprintf(mfp, ")");
+       if (xp->a_flag & A_PAG) {
+               ai = (ai & 0xFF);
+               aj = (aj > 256);
+               if (ai || aj) { fprintf(mfp, "  "); }
+               if (ai)      { fprintf(mfp, " Boundary"); }
+               if (ai & aj)  { fprintf(mfp, " /"); }
+               if (aj)      { fprintf(mfp, " Length"); }
+               if (ai || aj) { fprintf(mfp, " Error"); }
+       }
+
+       /*
+        * Find number of symbols in area
+        */
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp)
+                                       ++nmsym;
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+       if (nmsym == 0) {
+               putc('\n', mfp);
+               slew(mfp);
+               return;
+       }
+
+       /*
+        * Allocate space for an array of pointers to symbols
+        * and load array.
+        */
+       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
+               == NULL) {
+               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
+               slew(mfp);
+               return;
+       }
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp) {
+                                       p[nmsym++] = sp;
+                               }
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+
+       /*
+        * 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;
+               }
+       }
+
+       /*
+        * Symbol Table Output
+        */
+       i = 0;
+       while (i < nmsym) {
+               if (i % 4 == 0) {
+                       fprintf(mfp, "\n");
+                       slew(mfp);
+                       fprintf(mfp, "     ");
+               }
+               sp = p[i];
+               aj = sp->s_addr + sp->s_axp->a_addr;
+               if (xflag == 0) {
+                       fprintf(mfp, "  %04X  ", aj);
+               } else
+               if (xflag == 1) {
+                       fprintf(mfp, "%06o  ", aj);
+               } else
+               if (xflag == 2) {
+                       fprintf(mfp, " %05u  ", aj);
+               }
+               ptr = &sp->s_id[0];
+               while (ptr < &sp->s_id[NCPS]) {
+                       if ((c = *ptr++) != 0) {
+                               putc(c, mfp);
+                       } else {
+                               putc(' ', mfp);
+                       }
+               }
+               if (++i < nmsym)
+                       if (i % 4 != 0)
+                               fprintf(mfp, " | ");
+       }
+       putc('\n', mfp);
+       free(p);
+       slew(mfp);
+}
+#endif
+
+#ifdef SDK
+VOID lstareatosym(struct area *xp)
+{
+       /* Output the current area symbols to a NO$GMB .sym file */
+       register struct areax *oxp;
+       register int i, j;
+       int nmsym;
+       Addr_T a0, ai;
+       struct sym *sp;
+       struct sym **p;
+
+       /*
+        * Find number of symbols in area
+        */
+       nmsym = 0;
+       oxp = xp->a_axp;
+       while (oxp) {
+               for (i=0; i<NHASH; i++) {
+                       sp = symhash[i];
+                       while (sp != NULL) {
+                               if (oxp == sp->s_axp)
+                                       ++nmsym;
+                               sp = sp->s_sp;
+                       }
+               }
+               oxp = oxp->a_axp;
+       }
+
+       /*
+        * Symbol Table Output
+        */
+       if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) {
+               /* Dont worry about any area information */
+               fprintf(mfp, "; Area: %s\n", xp->a_id );
+               if (nmsym>0) {
+                       /*
+                        * Allocate space for an array of pointers to symbols
+                        * and load array.
+                        */
+                       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
+                           == NULL) {
+                               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
+                               return;
+                       }
+                       nmsym = 0;
+                       oxp = xp->a_axp;
+                       while (oxp) {
+                               for (i=0; i<NHASH; i++) {
+                                       sp = symhash[i];
+                                       while (sp != NULL) {
+                                               if (oxp == sp->s_axp) {
+                                                       p[nmsym++] = sp;
+                                               }
+                                               sp = sp->s_sp;
+                                       }
+                               }
+                               oxp = oxp->a_axp;
+                       }
+
+                       /*
+                        * Bubble Sort of Addresses in Symbol Table Array
+                        */
+                       j = 1;
+                       while (j) {
+                               j = 0;
+                               sp = p[0];
+                               a0 = sp->s_addr + sp->s_axp->a_addr;
+                               for (i=1; i<nmsym; ++i) {
+                                       sp = p[i];
+                                       ai = sp->s_addr + sp->s_axp->a_addr;
+                                       if (a0 > ai) {
+                                               j = 1;
+                                               p[i] = p[i-1];
+                                               p[i-1] = sp;
+                                       }
+                                       a0 = ai;
+                               }
+                       }
+                       i = 0;
+                       while (i < nmsym) {
+                               /* no$gmb requires the symbol names to be less than 32 chars long.  Truncate. */
+                               char name[32];
+                               strncpy(name, p[i]->s_id, 31);
+                               name[31] = '\0';
+                               if ((strncmp("l__", name, 3)!=0)&&(strchr(name,' ')==NULL)) {
+                                       a0=p[i]->s_addr + p[i]->s_axp->a_addr;
+                                       if (a0>0x7FFFU) {
+                                               /* Not inside the ROM, so treat as being in bank zero */
+                                               fprintf(mfp, "00:%04X %s\n", a0, name);
+                                       }
+                                       else {
+                                               fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, name);
+                                       }
+                               }
+                               i++;
+                       }
+                       free(p);
+               }
+       }
+}
+#endif
+
+/*)Function    VOID    lkulist(i)
+ *
+ *             int     i       i # 0   process LST to RST file
+ *                             i = 0   copy remainder of LST file
+ *                                     to RST file and close files
+ *
+ *     The function lkulist() creates a relocated listing (.rst)
+ *     output file from the ASxxxx assembler listing (.lst)
+ *     files.  The .lst file's program address and code bytes
+ *     are changed to reflect the changes made by ASlink as
+ *     the .rel files are combined into a single relocated
+ *     output file.
+ *
+ *     local variables:
+ *             Addr_T  pc              current program counter address
+ *
+ *     global variables:
+ *             int     hilo            byte order
+ *             int     gline           get a line from the LST file
+ *                                     to translate for the RST file
+ *             char    rb[]            read listing file text line
+ *             FILE    *rfp            The file handle to the current
+ *                                     output RST file
+ *             int     rtcnt           count of data words
+ *             int     rtflg[]         output the data flag
+ *             Addr_T  rtval[]         relocated data
+ *             FILE    *tfp            The file handle to the current
+ *                                     LST file being scanned
+ *
+ *     functions called:
+ *             int     fclose()        c_library
+ *             int     fgets()         c_library
+ *             int     fprintf()       c_library
+ *             VOID    lkalist()       lklist.c
+ *             VOID    lkglist()       lklist.c
+ *
+ *     side effects:
+ *             A .rst file is created for each available .lst
+ *             file associated with a .rel file.
+ */
+
+VOID
+lkulist(i)
+int i;
+{
+       Addr_T pc;
+
+       /*
+        * Exit if listing file is not open
+        */
+       if (tfp == NULL)
+               return;
+
+       /*
+        * Normal processing of LST to RST
+        */
+       if (i) {
+               /*
+                * Evaluate current code address
+                */
+               if (hilo == 0) {
+                       pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF);
+               } else {
+                       pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF);
+               }
+
+               /*
+                * Line with only address
+                */
+               if (rtcnt == 2) {
+                       lkalist(pc);
+
+               /*
+                * Line with address and code
+                */
+               } else {
+                       for (i=2; i < rtcnt; i++) {
+                               if (rtflg[i]) {
+                                       lkglist(pc++, rtval[i] & 0xFF);
+                               }
+                       }
+               }
+
+       /*
+        * Copy remainder of LST to RST
+        */
+       } else {
+               if (gline == 0)
+                       fprintf(rfp, rb);
+
+               while (fgets(rb, sizeof(rb), tfp) != 0) {
+                       fprintf(rfp, 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, 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, rb);
+               goto loop;
+       }
+
+       /*
+        * Must have an address in the expected radix
+        */
+       if (radix == 16) {
+               if (!dgt(RAD16, &rb[3], 4)) {
+                       fprintf(rfp, rb);
+                       goto loop;
+               }
+               sprintf(str, "%04X", pc);
+               strncpy(&rb[3], str, 4);
+       } else
+       if (radix == 10) {
+               if (!dgt(RAD10, &rb[3], 5)) {
+                       fprintf(rfp, rb);
+                       goto loop;
+               }
+               sprintf(str, "%05d", pc);
+               strncpy(&rb[3], str, 5);
+       } else
+       if (radix == 8) {
+               if (!dgt(RAD8, &rb[3], 6)) {
+                       fprintf(rfp, rb);
+                       goto loop;
+               }
+               sprintf(str, "%06o", pc);
+               strncpy(&rb[3], str, 6);
+       }
+
+       /*
+        * Copy updated LST text line to RST
+        */
+       fprintf(rfp, 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, 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, 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, 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, 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, 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, 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, rb);
+                       gline = 1;
+                       gcntr = -1;
+               }
+       }
+}
+
+/*)Function    int     dgt(rdx,str,n)
+ *
+ *             int     rdx             radix bit code
+ *             char    *str            pointer to the test string
+ *             int     n               number of characters to check
+ *
+ *     The function dgt() verifies that the string under test
+ *     is of the specified radix.
+ *
+ *     local variables:
+ *             int     i               loop counter
+ *
+ *     global variables:
+ *             ctype[]                 array of character types
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ */
+
+int
+dgt(rdx, str, n)
+int rdx, n;
+char *str;
+{
+       int i;
+
+       for (i=0; i<n; i++) {
+               if ((ctype[(unsigned char)(*str++)] & rdx) == 0)
+                       return(0);
+       }
+       return(1);
+}
diff --git a/as/link/z80/lkmain.c b/as/link/z80/lkmain.c
new file mode 100644 (file)
index 0000000..f2d071e
--- /dev/null
@@ -0,0 +1,1502 @@
+/* lkmain.c */
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+/*
+ * Extensions: P. Felber
+ */
+
+#include <stdio.h>
+#include <string.h>
+//#include <alloc.h>
+#include "aslink.h"
+#include <stdlib.h>
+
+#ifndef SDK_VERSION_STRING
+#define SDK_VERSION_STRING     "3.0.0"
+#endif
+#ifndef TARGET_STRING
+#define TARGET_STRING          "gbz80"
+#endif
+
+#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()
+ *             VOID    lkexit()
+ *             VOID    main(argc,argv)
+ *             VOID    map()
+ *             int     parse()
+ *             VOID    setbas()
+ *             VOID    setgbl()
+ *             VOID    usage()
+ *
+ *     lkmain.c contains the following local variables:
+ *             char *  usetext[]       array of pointers to the
+ *                                     command option tect lines
+ *
+ */
+
+/*)Function    VOID    main(argc,argv)
+ *
+ *             int     argc            number of command line arguments + 1
+ *             char *  argv[]          array of pointers to the command line
+ *                                     arguments
+ *
+ *     The function main() evaluates the command line arguments to
+ *     determine if the linker parameters are to input through 'stdin'
+ *     or read from a command file.  The functiond lk_getline() and parse()
+ *     are to input and evaluate the linker parameters.  The linking process
+ *     proceeds by making the first pass through each .rel file in the order
+ *     presented to the linker.  At the end of the first pass the setbase(),
+ *     lnkarea(), setgbl(), and symdef() functions are called to evaluate
+ *     the base address terms, link all areas, define global variables,
+ *     and look for undefined symbols.  Following these routines a linker
+ *     map file may be produced and the linker output files may be opened.
+ *     The second pass through the .rel files will output the linked data
+ *     in one of the four supported formats.
+ *
+ *     local variables:
+ *             char *  p               pointer to an argument string
+ *             int     c               character from argument string
+ *             int     i               loop counter
+ *
+ *     global variables:
+ *                                     text line in ib[]
+ *             lfile   *cfp            The pointer *cfp points to the
+ *                                     current lfile structure
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             lfile   *filep          The pointer *filep points to the
+ *                                     beginning of a linked list of
+ *                                     lfile structures.
+ *             head    *hp             Pointer to the current
+ *                                     head structure
+ *             char    ib[NINPUT]      .rel file text line
+ *             char    *ip             pointer into the .rel file
+ *             lfile   *linkp          pointer to first lfile structure
+ *                                     containing an input .rel file
+ *                                     specification
+ *             int     lkerr           error flag
+ *             int     mflag           Map output flag
+ *             int     oflag           Output file type flag
+ *             FILE    *ofp            Output file handle
+ *                                     for word formats
+ *             FILE    *ofph           Output file handle
+ *                                     for high byte format
+ *             FILE    *ofpl           Output file handle
+ *                                     for low byte format
+ *             int     pass            linker pass number
+ *             int     pflag           print linker command file flag
+ *             int     radix           current number conversion radix
+ *             FILE    *sfp            The file handle sfp points to the
+ *                                     currently open file
+ *             lfile   *startp         asmlnk startup file structure
+ *             FILE *  stdin           c_library
+ *             FILE *  stdout          c_library
+ *
+ *     functions called:
+ *             FILE *  afile()         lkmain.c
+ *             int     fclose()        c_library
+ *             int     fprintf()       c_library
+ *             int     lk_getline()    lklex.c
+ *             VOID    library()       lklibr.c
+ *             VOID    link()          lkmain.c
+ *             VOID    lkexit()        lkmain.c
+ *             VOID    lnkarea()       lkarea.c
+ *             VOID    map()           lkmain.c
+ *             VOID    new()           lksym.c
+ *             int     parse()         lkmain.c
+ *             VOID    reloc()         lkreloc.c
+ *             VOID    search()        lklibr.c
+ *             VOID    setbas()        lkmain.c
+ *             VOID    setgbl()        lkmain.c
+ *             VOID    symdef()        lksym.c
+ *             VOID    usage()         lkmain.c
+ *
+ *     side effects:
+ *             Completion of main() completes the linking process
+ *             and may produce a map file (.map) and/or a linked
+ *             data files (.ihx or .s19) and/or one or more
+ *             relocated listing files (.rst).
+ */
+
+#ifdef SDK
+int binary = 0;
+#endif /* SDK */
+#ifdef GAMEBOY
+char *default_basep[] = {
+  "_CODE=0x0200",
+  "_DATA=0xC0A0",
+  NULL
+};
+
+char *default_globlp[] = {
+  /* DMA transfer must start at multiples of 0x100 */
+  ".OAM=0xC000",
+  ".STACK=0xE000",
+  ".refresh_OAM=0xFF80",
+
+  ".init=0x0000",
+
+  NULL
+};
+#endif /* GAMEBOY */
+
+int
+main(argc, argv)
+char *argv[];
+{
+       register char *p;
+       register int c, i;
+
+#ifdef WIN32T
+    Timer(0, "");
+#endif
+
+#ifdef GAMEBOY
+       nb_rom_banks = 2;
+       nb_ram_banks = 0;
+       mbc_type = 0;
+       symflag=0;
+
+       for(i = 0; default_basep[i] != NULL; i++) {
+               if(basep == NULL) {
+                       basep = (struct base *)new(sizeof(struct base));
+                       bsp = basep;
+               } else {
+                       bsp->b_base = (struct base *)new(sizeof(struct base));
+                       bsp = bsp->b_base;
+               }
+               bsp->b_strp = default_basep[i];
+       }
+       for(i = 0; default_globlp[i] != NULL; i++) {
+               if(globlp == NULL) {
+                       globlp = (struct globl *)new(sizeof(struct globl));
+                       gsp = globlp;
+               } else {
+                       gsp->g_globl = (struct globl *)new(sizeof(struct globl));
+                       gsp = gsp->g_globl;
+               }
+               gsp->g_strp = default_globlp[i];
+       }
+#endif /* GAMEBOY */
+#ifndef SDK
+       fprintf(stdout, "\n");
+#endif /* SDK */
+
+       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();
+                               }
+                       }
+
+#ifdef SDK                     
+                       if(c == '-') {
+                               startp->f_type = F_CMD;
+                               startp->f_idp = (char *)&argv[i+1];
+                               break;
+                       }
+#endif /* SDK */
+
+               } else {
+                       if (startp->f_type == F_LNK) {
+                               startp->f_idp = p;
+                       }
+               }
+       }
+       if (startp->f_type == F_INV)
+               usage();
+       if (startp->f_type == F_LNK && startp->f_idp == NULL)
+               usage();
+#ifdef SDK
+       if (startp->f_type == F_CMD && startp->f_idp == NULL)
+               usage();
+#endif /* SDK */
+
+       cfp = NULL;
+       sfp = NULL;
+       filep = startp;
+       while (1) {
+               ip = ib;                                        
+               if (lk_getline() == 0)
+                       break;
+               if (pflag && sfp != stdin)
+                       fprintf(stdout, "%s\n", ip);
+               if (*ip == '\0' || parse())
+                       break;
+       }
+       if (sfp)
+               fclose(sfp);
+       if (linkp == NULL)
+               usage();
+#ifdef SDK
+       if (linkp->f_flp == NULL)
+               usage();
+#endif /* SDK */
+
+#ifdef GAMEBOY
+       for(i = 1; i < nb_rom_banks; i++) {
+               bsp->b_base = (struct base *)new(sizeof(struct base));
+               bsp = bsp->b_base;
+               bsp->b_strp = (char *)malloc(18);
+               sprintf(bsp->b_strp, "_CODE_%d=0x4000", i);
+       }
+       for(i = 0; i < nb_ram_banks; i++) {
+               bsp->b_base = (struct base *)new(sizeof(struct base));
+               bsp = bsp->b_base;
+               bsp->b_strp = (char *)malloc(18);
+               sprintf(bsp->b_strp, "_DATA_%d=0xA000", i);
+       }
+#endif /* GAMEBOY */
+
+       syminit();
+       for (pass=0; pass<2; ++pass) {
+               cfp = NULL;
+               sfp = NULL;
+#ifdef SDK
+               filep = linkp->f_flp;
+#else /* SDK */
+               filep = linkp;
+#endif /* SDK */
+               hp = NULL;
+               radix = 10;
+
+               while (lk_getline()) {
+                       ip = ib;
+                       link();
+               }
+               if (pass == 0) {
+                       /*
+                        * Search libraries for global symbols
+                        */
+                       search();
+                       /*
+                        * Set area base addresses.
+                        */
+                       setbas();
+                       /*
+                        * Link all area addresses.
+                        */
+                       lnkarea();
+                       /*
+                        * Process global definitions.
+                        */
+                       setgbl();
+                       /*
+                        * Check for undefined globals.
+                        */
+                       symdef(stderr);
+#ifdef SDK
+                       if (symflag) 
+                               sym();
+#endif
+                       /*
+                        * Output Link Map.
+                        */
+                       if (mflag)
+                               map();
+                       /*
+                        * Open output file
+                        */
+                       if (oflag == 1) {
+#ifdef SDK
+                               ofp = afile(linkp->f_idp, "ihx", 1);
+#else /* SDK */
+                               ofp = afile(linkp->f_idp, "IHX", 1);
+#endif /* SDK */
+                               if (ofp == NULL) {
+                                       lkexit(1);
+                               }
+                       } else
+                       if (oflag == 2) {
+#ifdef SDK
+                               ofp = afile(linkp->f_idp, "s19", 1);
+#else /* SDK */
+                               ofp = afile(linkp->f_idp, "S19", 1);
+#endif /* SDK */
+                               if (ofp == NULL) {
+                                       lkexit(1);
+                               }
+#ifdef SDK
+                       } else
+                       if (oflag == 3) {
+                               binary = 1;
+                               ofp = afile(linkp->f_idp, "", 1);
+                               binary = 0;
+                               if (ofp == NULL) {
+                                       lkexit(1);
+                               }
+#endif /* SDK */
+                       }
+               } else {
+                       /*
+                        * Link in library files
+                        */
+                       library();
+                       reloc('E');
+               }
+       }
+#ifdef WIN32T
+    Timer(1, "Linker time");
+#endif
+       lkexit(lkerr);
+
+        /* Never get here. */
+        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(i)
+int i;
+{
+       if (mfp != NULL) fclose(mfp);
+       if (ofp != NULL) fclose(ofp);
+       if (rfp != NULL) fclose(rfp);
+       if (sfp != NULL) fclose(sfp);
+       if (tfp != NULL) fclose(tfp);
+       exit(i);
+}
+
+/*)Function    link()
+ *
+ *     The function link() evaluates the directives for each line of
+ *     text read from the .rel file(s).  The valid directives processed
+ *     are:
+ *             X, D, Q, H, M, A, S, T, R, and P.
+ *
+ *     local variables:
+ *             int     c               first non blank character of a line
+ *
+ *     global variables:
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             head    *hp             Pointer to the current
+ *                                     head structure
+ *             int     pass            linker pass number
+ *             int     radix           current number conversion radix
+ *
+ *     functions called:
+ *             char    endline()       lklex.c
+ *             VOID    module()        lkhead.c
+ *             VOID    newarea()       lkarea.c
+ *             VOID    newhead()       lkhead.c
+ *             sym *   newsym()        lksym.c
+ *             VOID    reloc()         lkreloc.c
+ *
+ *     side effects:
+ *             Head, area, and symbol structures are created and
+ *             the radix is set as the .rel file(s) are read.
+ */
+
+VOID
+link()
+{
+       register int 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.
+ */
+
+#ifndef MLH_MAP
+VOID
+map()
+{
+       register i;
+       register struct head *hdp;
+       register struct lbfile *lbfh;
+
+       /*
+        * Open Map File
+        */
+#ifdef SDK
+       mfp = afile(linkp->f_idp, "map", 1);
+#else /* SDK */
+       mfp = afile(linkp->f_idp, "MAP", 1);
+#endif /* SDK */
+       if (mfp == NULL) {
+               lkexit(1);
+       }
+
+       /*
+        * Output Map Area Lists
+        */
+       page = 0;
+       lop  = NLPP;
+       ap = areap;
+       while (ap) {
+               lstarea(ap);
+               ap = ap->a_ap;
+       }
+       /*
+        * List Linked Files
+        */
+       newpag(mfp);
+       fprintf(mfp, "\nFiles Linked      [ module(s) ]\n\n");
+       hdp = headp;
+#ifdef SDK
+       filep = linkp->f_flp;
+#else /* SDK */
+       filep = linkp;
+#endif /* SDK */
+       while (filep) {
+               fprintf(mfp, "%-16s", filep->f_idp);
+               i = 0;
+               while ((hdp != NULL) && (hdp->h_lfile == filep)) {
+                       if (i % 5) {
+                           fprintf(mfp, ", %8.8s", hdp->m_id);
+                       } else {
+                           if (i) {
+                               fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id);
+                           } else {
+                               fprintf(mfp, "  [ %8.8s", hdp->m_id);
+                           }
+                       }
+                       hdp = hdp->h_hp;
+                       i++;
+               }
+               if (i)
+                       fprintf(mfp, " ]");
+               fprintf(mfp, "\n");
+               filep = filep->f_flp;
+       }
+       /*
+        * List Linked Libraries
+        */
+       if (lbfhead != NULL) {
+               fprintf(mfp,
+       "\nLibraries Linked                    [   object  file   ]\n\n");
+               for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) {
+                       fprintf(mfp, "%-32s    [ %16.16s ]\n",
+                               lbfh->libspc, lbfh->relfil);
+               }
+               fprintf(mfp, "\n");
+       }
+       /*
+        * List Base Address Definitions
+        */
+       if (basep) {
+               newpag(mfp);
+               fprintf(mfp, "\nUser Base Address Definitions\n\n");
+               bsp = basep;
+               while (bsp) {
+                       fprintf(mfp, "%s\n", bsp->b_strp);
+                       bsp = bsp->b_base;
+               }
+       }
+       /*
+        * List Global Definitions
+        */
+       if (globlp) {
+               newpag(mfp);
+               fprintf(mfp, "\nUser Global Definitions\n\n");
+               gsp = globlp;
+               while (gsp) {
+                       fprintf(mfp, "%s\n", gsp->g_strp);
+                       gsp = gsp->g_globl;
+               }
+       }
+       fprintf(mfp, "\n\f");
+       symdef(mfp);
+}
+#else
+VOID map()
+{
+       register struct head *hdp;
+       register struct lbfile *lbfh;
+
+       /*
+        * Open Map File
+        */
+#ifdef SDK
+       mfp = afile(linkp->f_idp, "map", 1);
+#else /* SDK */
+       mfp = afile(linkp->f_idp, "MAP", 1);
+#endif /* SDK */
+       if (mfp == NULL) {
+               lkexit(1);
+       }
+
+       /*
+        *Output Map Area Lists
+        */
+       page = 0;
+       lop  = NLPP;
+       ap = areap;
+       while (ap) {
+               lstarea(ap);
+               ap = ap->a_ap;
+       }
+       /*
+        * List Linked Files
+        */
+       hdp = headp;
+#ifdef SDK
+       filep = linkp->f_flp;
+#else /* SDK */
+       filep = linkp;
+#endif /* SDK */
+       if (filep) {
+               fprintf( mfp, "MODULES\n");
+       }
+       while (filep) {
+               fprintf(mfp, "\tFILE %s\n", filep->f_idp);
+               while ((hdp != NULL) && (hdp->h_lfile == filep)) {
+                       if (strlen(hdp->m_id)>0)
+                               fprintf(mfp, "\t\tNAME %s\n", hdp->m_id);
+                       hdp = hdp->h_hp;
+               }
+               filep = filep->f_flp;
+       }
+       /*
+        * List Linked Libraries
+        */
+       if (lbfhead != NULL) {
+               fprintf(mfp, "LIBRARIES\n");
+               for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) {
+                       fprintf(mfp,    "\tLIBRARY %s\n"
+                                       "\t\tMODULE %s\n",
+                               lbfh->libspc, lbfh->relfil);
+               }
+       }
+       /*
+        * List Base Address Definitions
+        */
+       if (basep) {
+               fprintf(mfp, "USERBASEDEF\n");
+               bsp = basep;
+               while (bsp) {
+                       fprintf(mfp, "\t%s\n", bsp->b_strp);
+                       bsp = bsp->b_base;
+               }
+       }
+       /*
+        * List Global Definitions
+        */
+       if (globlp) {
+               fprintf(mfp, "USERGLOBALDEF\n");
+               gsp = globlp;
+               while (gsp) {
+                       fprintf(mfp, "\t%s\n", gsp->g_strp);
+                       gsp = gsp->g_globl;
+               }
+       }
+       symdef(mfp);
+#ifdef SDK
+       if (mfp!=NULL) {
+               fclose(mfp);
+               mfp = NULL;
+       }
+#endif
+}
+#endif /* MLH_MAP */
+
+#ifdef SDK
+/* PENDING */
+VOID lstareatosym(struct area *xp);
+
+VOID sym()
+{
+       /*
+        * Open sym File
+        */
+       mfp = afile(linkp->f_idp, "sym", 1);
+       if (mfp == NULL) {
+               lkexit(1);
+       }
+       fprintf( mfp,   "; no$gmb format .sym file\n"
+                       "; Generated automagically by ASxxxx linker %s (SDK " SDK_VERSION_STRING ")\n"
+               , VERSION );
+       /*
+        * Output sym Area Lists
+        */
+       page = 0;
+       lop  = NLPP;
+       ap = areap;
+       while (ap) {
+               lstareatosym(ap);
+               ap = ap->a_ap;
+       }
+       if (mfp!=NULL) {
+               fclose(mfp);
+               mfp = NULL;
+       }
+}
+#endif /* SDK */
+
+/*)Function    int     parse()
+ *
+ *     The function parse() evaluates all command line or file input
+ *     linker directives and updates the appropriate variables.
+ *
+ *     local variables:
+ *             int     c               character value
+ *             char    fid[]           file id string
+ *
+ *     global variables:
+ *             char    ctype[]         array of character types, one per
+ *                                     ASCII character
+ *             lfile   *lfp            pointer to current lfile structure
+ *                                     being processed by parse()
+ *             lfile   *linkp          pointer to first lfile structure
+ *                                     containing an input REL file
+ *                                     specification
+ *             int     mflag           Map output flag
+ *             int     oflag           Output file type flag
+ *             int     pflag           print linker command file flag
+ *             FILE *  stderr          c_library
+ *             int     uflag           Relocated listing flag
+ *             int     xflag           Map file radix type flag
+ *
+ *     Functions called:
+ *             VOID    addlib()        lklibr.c
+ *             VOID    addpath()       lklibr.c
+ *             VOID    bassav()        lkmain.c
+ *             int     fprintf()       c_library
+ *             VOID    gblsav()        lkmain.c
+ *             VOID    getfid()        lklex.c
+ *             char    getnb()         lklex.c
+ *             VOID    lkexit()        lkmain.c
+ *             char *  strcpy()        c_library
+ *             int     strlen()        c_library
+ *
+ *     side effects:
+ *             Various linker flags are updated and the linked
+ *             structure lfile is created.
+ */
+
+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;
+#ifdef GAMEBOY
+                               case 'y':
+                               case 'Y':
+                                       c = get();
+                                       if(c == 'O' || c == 'o')
+                                               nb_rom_banks = expr(0);
+                                       else if(c == 'A' || c == 'a')
+                                               nb_ram_banks = expr(0);
+                                       else if(c == 'T' || c == 't')
+                                               mbc_type = expr(0);
+                                       else if(c == 'N' || c == 'n') {
+                                               int i = 0;
+                                               if(getnb() != '=' || getnb() != '"') {
+                                                       fprintf(stderr, "Syntax error in -YN=\"name\" flag\n");
+                                                       lkexit(1);
+                                               }
+                                               while((c = get()) != '"' && i < 16) {
+                                                       cart_name[i++] = c;
+                                               }
+                                               if(i < 16)
+                                                       cart_name[i] = 0;
+                                               else
+                                                       while(get() != '"')
+                                                               ;
+                                       } else if(c == 'P' || c == 'p') {
+                                               patch *p = patches;
+
+                                               patches = (patch *)malloc(sizeof(patch));
+                                               patches->next = p;
+                                               patches->addr = expr(0);
+                                               if(getnb() != '=') {
+                                                       fprintf(stderr, "Syntax error in -YHaddr=val flag\n");
+                                                       lkexit(1);
+                                               }
+                                               patches->value = expr(0);
+                                       } else {
+                                               fprintf(stderr, "Invalid option\n");
+                                               lkexit(1);
+                                       }
+                                       break;
+
+#endif /* GAMEBOY */
+#ifdef SDK
+                               case 'j':
+                               case 'J':
+                                       ++symflag;
+                                       break;
+                               case 'z':
+                               case 'Z':
+                                       oflag = 3;
+                                       break;
+#endif /* SDK */
+                               case 'm':
+                               case 'M':
+                                       ++mflag;
+                                       break;
+
+                               case 'u':
+                               case 'U':
+                                       uflag = 1;
+                                       break;
+
+                               case 'x':
+                               case 'X':
+                                       xflag = 0;
+                                       break;
+
+                               case 'q':
+                               case 'Q':
+                                       xflag = 1;
+                                       break;
+
+                               case 'd':
+                               case 'D':
+                                       xflag = 2;
+                                       break;
+
+                               case 'e':
+                               case 'E':
+                                       return(1);
+
+                               case 'n':
+                               case 'N':
+                                       pflag = 0;
+                                       break;
+
+                               case 'p':
+                               case 'P':
+                                       pflag = 1;
+                                       break;
+
+                               case 'b':
+                               case 'B':
+                                       bassav();
+                                       return(0);
+
+                               case 'g':
+                               case 'G':
+                                       gblsav();
+                                       return(0);
+
+                               case 'k':
+                               case 'K':
+                                       addpath();
+                                       return(0);
+
+                               case 'l':
+                               case 'L':
+                                       addlib();
+                                       return(0);
+
+                               default:
+                                       fprintf(stderr, "Invalid option\n");
+                                       lkexit(1);
+                               }
+                       }
+                       if (c == ';')
+                               return(0);
+               } else
+               if (ctype[c] != ILL) {
+                       if (linkp == NULL) {
+                               linkp = (struct lfile *)
+                                       new (sizeof (struct lfile));
+                               lfp = linkp;
+                       } else {
+                               lfp->f_flp = (struct lfile *)
+                                               new (sizeof (struct lfile));
+                               lfp = lfp->f_flp;
+                       }
+                       getfid(fid, c);
+                       lfp->f_idp = (char *) new (strlen(fid)+1);
+                       strcpy(lfp->f_idp, fid);
+                       lfp->f_type = F_REL;
+               } else {
+                       fprintf(stderr, "Invalid input");
+                       lkexit(1);
+               }
+       }
+       return(0);
+}
+
+/*)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 hte
+ *     basep structure, evaluates the arguments, and sets beginning
+ *     address of the specified areas.
+ *
+ *     local variables:
+ *             int     v               expression value
+ *             char    id[]            base id string
+ *
+ *     global variables:
+ *             area    *ap             Pointer to the current
+ *                                     area structure
+ *             area    *areap          The pointer to the first
+ *                                     area structure of a linked list
+ *             base    *basep          The pointer to the first
+ *                                     base structure
+ *             base    *bsp            Pointer to the current
+ *                                     base structure
+ *             char    *ip             pointer into the REL file
+ *                                     text line in ib[]
+ *             int     lkerr           error flag
+ *
+ *      functions called:
+ *             Addr_T  expr()          lkeval.c
+ *             int     fprintf()       c_library
+ *             VOID    getid()         lklex.c
+ *             char    getnb()         lklex.c
+ *             int     symeq()         lksym.c
+ *
+ *     side effects:
+ *             The base address of an area is set.
+ */
+
+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) {
+#ifndef SDK
+                               fprintf(stderr,
+                               "No definition of area %s\n", id);
+                               lkerr++;
+#endif /* SDK */
+                       } else {
+                               ap->a_addr = v;
+                       }
+               } else {
+                       fprintf(stderr, "No '=' in base expression");
+                       lkerr++;
+               }
+               bsp = bsp->b_base;
+       }
+}
+
+/*)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 hte
+ *     globlp structure, evaluates the arguments, and sets a variable
+ *     to this value.
+ *
+ *     local variables:
+ *             int     v               expression value
+ *             char    id[]            base id string
+ *             sym *   sp              pointer to a symbol structure
+ *
+ *     global variables:
+ *             char    *ip             pointer into the REL file
+ *                                     text line in ib[]
+ *             globl   *globlp         The pointer to the first
+ *                                     globl structure
+ *             globl   *gsp            Pointer to the current
+ *                                     globl structure
+ *             FILE *  stderr          c_library
+ *             int     lkerr           error flag
+ *
+ *      functions called:
+ *             Addr_T  expr()          lkeval.c
+ *             int     fprintf()       c_library
+ *             VOID    getid()         lklex.c
+ *             char    getnb()         lklex.c
+ *             sym *   lkpsym()        lksym.c
+ *
+ *     side effects:
+ *             The value of a variable is set.
+ */
+
+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) {
+#ifndef SDK
+                               fprintf(stderr,
+                               "No definition of symbol %s\n", id);
+                               lkerr++;
+#endif /* SDK */
+                       } else {
+#ifndef SDK
+                               if (sp->s_flag & S_DEF) {
+                                       fprintf(stderr,
+                                       "Redefinition of symbol %s\n", id);
+                                       lkerr++;
+                                       sp->s_axp = NULL;
+                               }
+#endif /* SDK */
+                               sp->s_addr = v;
+                               sp->s_type |= S_DEF;
+                       }
+               } else {
+                       fprintf(stderr, "No '=' in global expression");
+                       lkerr++;
+               }
+               gsp = gsp->g_globl;
+       }
+}
+
+/*)Function    FILE *  afile(fn,, ft, wf)
+ *
+ *             char *  fn              file specification string
+ *             char *  ft              file type string
+ *             int     wf              read(0)/write(1) flag
+ *
+ *     The function afile() opens a file for reading or writing.
+ *             (1)     If the file type specification string ft
+ *                     is not NULL then a file specification is
+ *                     constructed with the file path\name in fn
+ *                     and the extension in ft.
+ *             (2)     If the file type specification string ft
+ *                     is NULL then the file specification is
+ *                     constructed from fn.  If fn does not have
+ *                     a file type then the default .rel file
+ *                     type is appended to the file specification.
+ *
+ *     afile() returns a file handle for the opened file or aborts
+ *     the assembler on an open error.
+ *
+ *     local variables:
+ *             int     c               character value
+ *             char    fb[]            constructed file specification string
+ *             FILE *  fp              filehandle for opened file
+ *             char *  p1              pointer to filespec string fn
+ *             char *  p2              pointer to filespec string fb
+ *             char *  p3              pointer to filetype string ft
+ *
+ *     global variables:
+ *             int     lkerr           error flag
+ *
+ *     functions called:
+ *             FILE *  fopen()         c_library
+ *             int     fprintf()       c_library
+ *
+ *     side effects:
+ *             File is opened for read or write.
+ */
+
+FILE *
+afile(fn, ft, wf)
+char *fn;
+char *ft;
+{
+#if 0
+       register char *p1, *p2, *p3;
+       register int c;
+#else
+       int i;
+#endif 
+       FILE *fp;
+       char fb[FILSPC];
+
+#if 0  
+       p1 = fn;
+       p2 = fb;
+       p3 = ft;
+       while ((c = *p1++) != 0 && c != FSEPX) {
+               if (p2 < &fb[FILSPC-4])
+                       *p2++ = c;
+       }
+       *p2++ = FSEPX;
+       if (*p3 == 0) {
+               if (c == FSEPX) {
+                       p3 = p1;
+               } else {
+#ifdef SDK
+                       p3 = "rel";
+#else /* SDK */
+                       p3 = "REL";
+#endif /* SDK */
+               }
+       }
+       while ((c = *p3++) != 0) {
+               if (p2 < &fb[FILSPC-1])
+                       *p2++ = c;
+       }
+       *p2++ = 0;
+#else
+       /*Look backward the name path and get rid of the extension, if any*/
+       i=strlen(fn);
+       for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--);
+       if( (fn[i]=='.') && *ft && strcmp(ft, "lnk") )
+       {
+               strncpy(fb, fn, i);
+               fb[i]=0;
+       }
+       else
+       {
+               strcpy(fb, fn);
+       }
+
+       /*Add the extension*/
+       if (fb[i] != '.')
+       {
+               strcat(fb, ".");
+#ifdef SDK
+               strcat(fb, strlen(ft)?ft:"rel");
+#else
+               strcat(fb, strlen(ft)?ft:"REL");
+#endif
+       }
+#endif
+
+#ifdef SDK
+       if ((fp = fopen(fb, wf?(binary?"wb":"w"):(binary?"rb":"r"))) == NULL) {
+#else /* SDK */
+       if ((fp = fopen(fb, wf?"w":"r")) == NULL) {
+#endif /* SDK */
+               fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
+               lkerr++;
+       }
+       return (fp);
+}
+
+char *usetxt[] = {
+#ifdef SDK
+       "Distributed with SDK " SDK_VERSION_STRING ", built on " __DATE__ " " __TIME__,
+       "Compile options: SDK Target " TARGET_STRING
+#ifdef INDEXLIB
+       " INDEXLIB"
+#endif
+       "\n",
+#endif
+       "Startup:",
+#ifdef SDK
+       "  --   [Commands]              Non-interactive command line input",
+#endif /* SDK */
+       "  -c                           Command line input",
+       "  -f   file[LNK]               File input",
+       "  -p   Prompt and echo of file[LNK] to stdout (default)",
+       "  -n   No echo of file[LNK] to stdout",
+#ifdef SDK
+       "Usage: [-Options] outfile file [file ...]",
+#else /* SDK */
+       "Usage: [-Options] file [file ...]",
+#endif /* SDK */
+       "Librarys:",
+       "  -k   Library path specification, one per -k",
+       "  -l   Library file specification, one per -l",
+       "Relocation:",
+       "  -b   area base address = expression",
+       "  -g   global symbol = expression",
+#ifdef GAMEBOY
+       "  -yo  Number of rom banks (default: 2)",
+       "  -ya  Number of ram banks (default: 0)",
+       "  -yt  MBC type (default: no MBC)",
+       "  -yn  Name of program (default: name of output file)",
+       "  -yp# Patch one byte in the output GB file (# is: addr=byte)",
+#endif /* GAMEBOY */
+       "Map format:",
+       "  -m   Map output generated as file[MAP]",
+#ifdef SDK
+       "  -j   no$gmb symbol file generated as file[SYM]",
+#endif /* SDK */
+       "  -x   Hexidecimal (default)",
+       "  -d   Decimal",
+       "  -q   Octal",
+       "Output:",
+       "  -i   Intel Hex as file[IHX]",
+       "  -s   Motorola S19 as file[S19]",
+#ifdef SDK
+#ifdef GAMEGEAR
+       "  -z   Gamegear image as file[GG]",
+#else
+       "  -z   Gameboy image as file[GB]",
+#endif /* GAMEGEAR */
+#endif /* SDK */
+       "List:",
+       "  -u   Update listing file(s) with link data as file(s)[.RST]",
+       "End:",
+       "  -e   or null line terminates input",
+       "",
+       0
+};
+
+/*)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);
+}
diff --git a/as/link/z80/lkrloc.c b/as/link/z80/lkrloc.c
new file mode 100644 (file)
index 0000000..e5bdd05
--- /dev/null
@@ -0,0 +1,1171 @@
+/* lkrloc.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+/*
+ * Extensions: P. Felber
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+//#include <alloc.h>
+#include <ctype.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[].
+ *
+ */
+
+/*)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(c)
+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()
+{
+       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()
+{
+       register int mode;
+       register Addr_T reli, relv;
+       int aindex, rindex, rtp, error;
+       Addr_T r, rtbase, rtofst, paga = 0, pags = 0, pc;
+       struct areax **a;
+       struct sym **s;
+
+       /*
+        * Get area and symbol lists
+        */
+       a = hp->a_list;
+       s = hp->s_list;
+
+       /*
+        * Verify Area Mode
+        */
+       if (eval() != (R_WORD | R_AREA) || eval()) {
+               fprintf(stderr, "R input error\n");
+               lkerr++;
+       }
+
+       /*
+        * Get area pointer
+        */
+       aindex = evword();
+       if (aindex >= hp->h_narea) {
+               fprintf(stderr, "R area error\n");
+               lkerr++;
+               return;
+       }
+
+       /*
+        * Base values
+        */
+       rtbase = adw_w(0, 0);
+       rtofst = 2;
+
+       /*
+        * Relocate address
+        */
+       pc = adw_w(a[aindex]->a_addr, 0);
+
+#ifdef GAMEBOY
+       {
+               char *s = strrchr(a[aindex]->a_bap->a_id, '_');
+               if(s != NULL && isdigit((unsigned char)s[1]))
+                       current_rom_bank = atoi(s+1);
+               else
+                       current_rom_bank = 0;
+       }
+#endif /* GAMEBOY */
+       /*
+        * Do remaining relocations
+        */
+       while (more()) {
+               error = 0;
+               mode = eval();
+               rtp = eval();
+               rindex = evword();
+
+               /*
+                * R_SYM or R_AREA references
+                */
+               if (mode & R_SYM) {
+                       if (rindex >= hp->h_nglob) {
+                               fprintf(stderr, "R symbol error\n");
+                               lkerr++;
+                               return;
+                       }
+                       reli = symval(s[rindex]);
+               } else {
+                       if (rindex >= hp->h_narea) {
+                               fprintf(stderr, "R area error\n");
+                               lkerr++;
+                               return;
+                       }
+                       reli = a[rindex]->a_addr;
+               }
+
+               /*
+                * R_PCR addressing
+                */
+               if (mode & R_PCR) {
+                       if (mode & R_BYTE) {
+                               reli -= (pc + (rtp-rtofst) + 1);
+                       } else {
+                               reli -= (pc + (rtp-rtofst) + 2);
+                       }
+               }
+
+               /*
+                * R_PAG0 or R_PAG addressing
+                */
+               if (mode & (R_PAG0|R_PAG)) {
+                       paga  = sdp.s_area->a_addr;
+                       pags  = sdp.s_addr;
+                       reli -= paga + pags;
+               }
+
+               /*
+                * R_BYTE or R_WORD operation
+                */
+               if (mode & R_BYTE) {
+                       if (mode & R_BYT2) {
+                               if (mode & R_MSB) {
+                                       relv = adb_hi(reli, rtp);
+                               } else {
+                                       relv = adb_lo(reli, rtp);
+                               }
+                       } else {
+                               relv = adb_b(reli, rtp);
+                       }
+               } else {
+                       /*
+                        * R_WORD with the R_BYT2 mode is flagged
+                        * as an 'r' error by the assembler,
+                        * but it is processed here anyway.
+                        */
+                       if (mode & R_BYT2) {
+                               if (mode & R_MSB) {
+                                       relv = adw_hi(reli, rtp);
+                               } else {
+                                       relv = adw_lo(reli, rtp);
+                               }
+                       } else {
+                               relv = adw_w(reli, rtp);
+                       }
+               }
+
+               /*
+                * R_BYTE with R_BYT2 offset adjust
+                */
+               if (mode & R_BYTE) {
+                       if (mode & R_BYT2) {
+                               rtofst += 1;
+                       }
+               }
+
+               /*
+                * Unsigned Byte Checking
+                */
+               if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
+                       error = 1;
+
+               /*
+                * PCR Relocation Error Checking
+                */
+               if (mode & R_PCR && mode & R_BYTE) {
+                       r = relv & ~0x7F;
+                       if (r != (Addr_T) ~0x7F && r != 0)
+                               error = 2;
+               }
+
+               /*
+                * Page Relocation Error Checking
+                */
+               if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
+                       error = 3;
+               if (mode & R_PAG  && (relv & ~0xFF))
+                       error = 4;
+
+               /*
+                * Error Processing
+                */
+               if (error) {
+                       rerr.aindex = aindex;
+                       rerr.mode = mode;
+                       rerr.rtbase = rtbase + rtp - rtofst - 1;
+                       rerr.rindex = rindex;
+                       rerr.rval = relv - reli;
+                       relerr(errmsg[error-1]);
+               }
+       }
+       if (uflag != 0) {
+               lkulist(1);
+       }
+       if (oflag == 1) {
+               ihx(1);
+       } else
+       if (oflag == 2) {
+               s19(1);
+#ifdef SDK
+       } else
+       if (oflag == 3) {
+#ifdef GAMEGEAR
+               gg(1);
+#endif /* GAMEGEAR */
+#ifdef GAMEBOY
+               gb(1);
+#endif /* GAMEBOY */
+#endif /* SDK */
+       }
+}
+
+char *errmsg[] = {
+       "Unsigned Byte error",
+       "Byte PCR relocation error",
+       "Page0 relocation error",
+       "Page Mode relocation error"
+};
+
+
+/*)Function    VOID    relp()
+ *
+ *     The function relp() evaluates a P line read by
+ *     the linker.  The P line data is combined with the
+ *     previous T line data to set the base page address
+ *     and test the paging boundary and length.
+ *
+ *             P Line 
+ *
+ *             P 0 0 nn nn n1 n2 xx xx 
+ *
+ *     The  P  line provides the paging information to the linker as
+ *     specified by a .setdp directive.  The format of  the  relocation
+ *     information is identical to that of the R line.  The correspond-
+ *     ing T line has the following information:  
+ *             T xx xx aa aa bb bb 
+ *
+ *     Where  aa aa is the area reference number which specifies the
+ *     selected page area and bb bb is the base address  of  the  page.
+ *     bb bb will require relocation processing if the 'n1 n2 xx xx' is
+ *     specified in the P line.  The linker will verify that  the  base
+ *     address is on a 256 byte boundary and that the page length of an
+ *     area defined with the PAG type is not larger than 256 bytes.  
+ *
+ *     local variable:
+ *             areax   **a             pointer to array of area pointers
+ *             int     aindex          area index
+ *             int     mode            relocation mode
+ *             Addr_T  relv            relocation value
+ *             int     rindex          symbol / area index
+ *             int     rtp             index into T data
+ *             sym     **s             pointer to array of symbol pointers
+ *
+ *     global variables:
+ *             head    *hp             pointer to the head structure
+ *             int     lkerr           error flag
+ *             sdp     sdp             base page structure
+ *             FILE    *stderr         standard error device
+ *
+ *     called functions:
+ *             Addr_T  adw_w()         lkrloc.c
+ *             Addr_T  evword()        lkrloc.c
+ *             int     eval()          lkeval.c
+ *             int     fprintf()       c_library
+ *             int     more()          lklex.c
+ *             int     symval()        lksym.c
+ *
+ *     side effects:
+ *             The P and T lines are combined to set
+ *             the base page address and report any
+ *             paging errors.
+ *
+ */
+
+VOID
+relp()
+{
+       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()
+{
+       if (uflag != 0) {
+               lkulist(0);
+       }
+       if (oflag == 1) {
+               ihx(0);
+       } else
+       if (oflag == 2) {
+               s19(0);
+#ifdef SDK
+       } else
+       if (oflag == 3) {
+#ifdef GAMEGEAR
+               gg(0);
+#endif /* GAMEGEAR */
+#ifdef GAMEBOY
+               gb(0);
+#endif /* GAMEBOY */
+#endif /* SDK */
+       }
+}
+
+/*)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()
+{
+       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(v, i)
+register Addr_T v;
+register int i;
+{
+       return(rtval[i] += v);
+}
+
+/*)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(v, i)
+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(v, i)
+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  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(v, i)
+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_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(v, i)
+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(v, i)
+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(str)
+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(fptr, str)
+FILE *fptr;
+char *str;
+{
+       int mode, aindex, rindex;
+       struct sym **s;
+       struct areax **a;
+       struct areax *raxp;
+
+       a = hp->a_list;
+       s = hp->s_list;
+
+       mode = rerr.mode;
+       aindex = rerr.aindex;
+       rindex = rerr.rindex;
+
+       /*
+        * Print Error
+        */
+       fprintf(fptr, "\n?ASlink-Warning-%s", str);
+       lkerr++;
+
+       /*
+        * Print symbol if symbol based
+        */
+       if (mode & R_SYM) {
+               fprintf(fptr, " for symbol  %.*s\n",
+                       NCPS, &s[rindex]->s_id[0]);
+       } else {
+               fprintf(fptr, "\n");
+       }
+
+       /*
+        * Print Ref Info
+        */
+       fprintf(fptr,
+               "         file        module      area        offset\n");
+       fprintf(fptr,
+               "  Refby  %-8.8s    %-8.8s    %-8.8s    ",
+                       hp->h_lfile->f_idp,
+                       &hp->m_id[0],
+                       &a[aindex]->a_bap->a_id[0]);
+       prntval(fptr, rerr.rtbase);
+
+       /*
+        * Print Def Info
+        */
+       if (mode & R_SYM) {
+               raxp = s[rindex]->s_axp;
+       } else {
+               raxp = a[rindex];
+       }
+       fprintf(fptr,
+               "  Defin  %-8.8s    %-8.8s    %-8.8s    ",
+                       raxp->a_bhp->h_lfile->f_idp,
+                       &raxp->a_bhp->m_id[0],
+                       &raxp->a_bap->a_id[0]);
+       if (mode & R_SYM) {
+               prntval(fptr, s[rindex]->s_addr);
+       } else {
+               prntval(fptr, rerr.rval);
+       }
+}
+
+/*)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(fptr, v)
+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(str)
+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(fptr, str)
+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/z80/lks19.c b/as/link/z80/lks19.c
new file mode 100644 (file)
index 0000000..bbca753
--- /dev/null
@@ -0,0 +1,123 @@
+/* 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 <alloc.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/z80/lksym.c b/as/link/z80/lksym.c
new file mode 100644 (file)
index 0000000..33cc6ff
--- /dev/null
@@ -0,0 +1,498 @@
+/* lksym.c */
+
+/*
+ * (C) Copyright 1989-1995
+ * All Rights Reserved
+ *
+ * Alan R. Baldwin
+ * 721 Berkeley St.
+ * Kent, Ohio  44240
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "aslink.h"
+
+/*)Module      lksym.c
+ *
+ *     The module lksym.c contains the functions that operate
+ *     on the symbol structures.
+ *
+ *     lksym.c contains the following functions:
+ *             int     hash()
+ *             sym *   lkpsym()
+ *             VOID *  new()
+ *             sym *   newsym()
+ *             VOID    symdef()
+ *             int     symeq()
+ *             VOID    syminit()
+ *             VOID    symmod()
+ *             Addr_T  symval()
+ *
+ *     lksym.c contains no local/static variables.
+ */
+
+/*)Function    VOID    syminit()
+ *
+ *     The function syminit() is called to clear the hashtable.
+ *
+ *     local variables:
+ *             int     h               computed hash value
+ *             sym **  spp             pointer to an array of
+ *                                     sym structure pointers
+ *
+ *     global variables:
+ *             sym * symhash[]         array of pointers to NHASH
+ *                                     linked symbol lists
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             (1)     The symbol hash tables are cleared
+ */
+
+VOID
+syminit()
+{
+       struct sym **spp;
+
+       spp = &symhash[0];
+       while (spp < &symhash[NHASH])
+               *spp++ = NULL;
+}
+
+/*)Function    sym *   newsym()
+ *
+ *     The function newsym() is called to evaluate the symbol
+ *     definition/reference directive from the .rel file(s).
+ *     If the symbol is not found in the symbol table a new
+ *     symbol structure is created.  Evaluation of the
+ *     directive determines if this is a reference or a definition.
+ *     Multiple definitions of the same variable will be flagged
+ *     as an error if the values are not identical.  A symbol
+ *     definition places the symbol value and area extension
+ *     into the symbols data structure.  And finally, a pointer
+ *     to the symbol structure is placed into the head structure
+ *     symbol list.  Refer to the description of the header, symbol,
+ *     area, and areax structures in lkdata.c for structure and
+ *     linkage details.
+ *
+ *     local variables:
+ *             int     c               character from input text
+ *             int     i               evaluation value
+ *             char    id[]            symbol name
+ *             int     nglob           number of symbols in this header
+ *             sym *   tsp             pointer to symbol structure
+ *             sym **  s               list of pointers to symbol structures
+ *
+ *     global variables:
+ *             areax   *axp            Pointer to the current
+ *                                     areax structure
+ *             head    *headp          The pointer to the first
+ *                                     head structure of a linked list
+ *             int     lkerr           error flag
+ *
+ *     functions called:
+ *             Addr_T  eval()          lkeval.c
+ *             VOID    exit()          c_library
+ *             int     fprintf()       c_library
+ *             char    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];
+
+       getid(id, -1);
+       tsp = lkpsym(id, 1);
+       c = getnb();get();get();
+       if (c == 'R') {
+               tsp->s_type |= S_REF;
+               if (eval()) {
+                       fprintf(stderr, "Non zero S_REF\n");
+                       lkerr++;
+               }
+       } else
+       if (c == 'D') {
+               i = eval();
+               if (tsp->s_type & S_DEF && tsp->s_addr != i) {
+#ifdef SDK
+                       fprintf(stderr, "Multiple definition of %s\n", id);
+#else
+                       fprintf(stderr, "Multiple definition of %.8s\n", id);
+#endif
+                       lkerr++;
+               }
+               tsp->s_type |= S_DEF;
+               /*
+                * Set value and area extension link.
+                */
+               tsp->s_addr = i;
+               tsp->s_axp = axp;
+       } else {
+               fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id);
+               lkexit(1);
+       }
+       /*
+        * Place pointer in header symbol list
+        */
+       if (headp == NULL) {
+               fprintf(stderr, "No header defined\n");
+               lkexit(1);
+       }
+       nglob = hp->h_nglob;
+       s = hp->s_list;
+       for (i=0; i < nglob ;++i) {
+               if (s[i] == NULL) {
+                       s[i] = tsp;
+                       return(tsp);
+               }
+       }
+       fprintf(stderr, "Header symbol list overflow\n");
+       lkexit(1);
+
+       /* Never reached */
+        return 0;
+}
+
+/*)Function    sym *   lkpsym(id,f)
+ *
+ *             char *  id              symbol name string
+ *             int     f               f == 0, lookup only
+ *                                     f != 0, create if not found
+ *
+ *     The function lookup() searches the symbol hash tables for
+ *     a symbol name match returning a pointer to the sym structure.
+ *     If the symbol is not found then a sym structure is created,
+ *     initialized, and linked to the appropriate hash table if f != 0.
+ *     A pointer to this new sym structure is returned or a NULL
+ *     pointer is returned if f == 0.
+ *
+ *     local variables:
+ *             int     h               computed hash value
+ *             sym *   sp              pointer to a sym structure
+ *
+ *     global varaibles:
+ *             sym * symhash[]         array of pointers to NHASH
+ *                                     linked symbol lists
+ *
+ *     functions called:
+ *             int     hash()          lksym.c
+ *             VOID *  new()           lksym.c
+ *             int     symeq()         lksym.c
+ *
+ *     side effects:
+ *             If the function new() fails to allocate space
+ *             for the new sym structure the linker terminates.
+ */
+
+struct sym *
+lkpsym(id, f)
+char *id;
+{
+       register struct sym *sp;
+       register int h;
+
+       h = hash(id);
+       sp = symhash[h];
+       while (sp != NULL) {
+               if (symeq(id, sp->s_id))
+                       return (sp);
+               sp = sp->s_sp;
+       }
+       if (f == 0)
+               return (NULL);
+       sp = (struct sym *) new (sizeof(struct sym));
+       sp->s_sp = symhash[h];
+       symhash[h] = sp;
+       strncpy(sp->s_id, id, NCPS);
+       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;
+{
+       register int n;
+
+       n = NCPS;
+       do {
+
+#if    CASE_SENSITIVE
+               if (*p1++ != *p2++)
+                       return (0);
+#else
+               if (ccase[(unsigned char)(*p1++)] != ccase[(unsigned char)(*p2++)])
+                       return (0);
+#endif
+
+       } while (--n);
+       return (1);
+}
+
+/*)Function    int     hash(p)
+ *
+ *             char *  p               pointer to string to hash
+ *
+ *     The function hash() computes a hash code using the sum
+ *     of all characters mod table size algorithm.
+ *
+ *     local variables:
+ *             int     h               accumulated character sum
+ *             int     n               loop counter
+ *
+ *     global variables:
+ *             char    ccase[]         an array of characters which
+ *                                     perform the case translation function
+ *
+ *     functions called:
+ *             none
+ *
+ *     side effects:
+ *             none
+ *
+ */
+int
+hash(p)
+register char *p;
+{
+       register int h, n;
+
+       h = 0;
+       n = NCPS;
+       do {
+
+#if    CASE_SENSITIVE
+               h += *p++;
+#else
+               h += ccase[(unsigned char)(*p++)];
+#endif
+
+       } while (--n);
+       return (h&HMASK);
+}
+
+/*)Function    VOID *  new(n)
+ *
+ *             unsigned int    n       allocation size in bytes
+ *
+ *     The function new() allocates n bytes of space and returns
+ *     a pointer to this memory.  If no space is available the
+ *     linker is terminated.
+ *
+ *     local variables:
+ *             char *  p               a general pointer
+ *             char *  q               a general pointer
+ *
+ *     global variables:
+ *             none
+ *
+ *     functions called:
+ *             int     fprintf()       c_library
+ *             VOID *  malloc()        c_library
+ *
+ *     side effects:
+ *             Memory is allocated, if allocation fails
+ *             the linker is terminated.
+ */
+
+VOID *
+new(n)
+unsigned int n;
+{
+       register char *p,*q;
+       register unsigned int i;
+
+       if ((p = (char *) malloc(n)) == NULL) {
+               fprintf(stderr, "Out of space!\n");
+               lkexit(1);
+       }
+       for (i=0,q=p; i<n; i++) {
+               *q++ = 0;
+       }
+       return (p);
+}
index c0224a65e77581123251313bd718ec0b5b510457..5c3bf82379fd19a4b165d95cc432a354b41cecd0 100755 (executable)
--- a/configure
+++ b/configure
@@ -8162,7 +8162,7 @@ test $OPT_DISABLE_XA51 = 0 &&           ac_config_files="$ac_config_files src/xa
 
 
 if test $OPT_DISABLE_Z80 = 0; then
-                                                    ac_config_files="$ac_config_files src/z80/Makefile as/Makefile as/z80/Makefile link/Makefile link/z80/Makefile"
+                                                    ac_config_files="$ac_config_files src/z80/Makefile as/Makefile as/z80/Makefile as/link/Makefile as/link/z80/Makefile"
 
   test $OPT_DISABLE_DEVICE_LIB = 0 &&                     ac_config_files="$ac_config_files device/lib/z80/Makefile device/lib/gbz80/Makefile"
 
diff --git a/link/Makefile.in b/link/Makefile.in
deleted file mode 100644 (file)
index 54cf61a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-VPATH        = @srcdir@
-srcdir       = @srcdir@
-top_builddir = @top_builddir@
-
-include $(top_builddir)Makefile.common
-
-PORTS = z80 gbz80
-
-all: 
-       $(MAKE) -C z80 _link-z80 _link-gbz80 E=$(E) BUILDDIR=../../bin/
-
-install: all
-       $(INSTALL) $(top_builddir)bin/link-z80$(EXEEXT) `echo $(DESTDIR)$(bindir)/link-z80$(EXEEXT)|sed '$(transform)'`
-       $(STRIP) `echo $(DESTDIR)$(bindir)/link-z80$(EXEEXT)|sed '$(transform)'`
-       $(INSTALL) $(top_builddir)bin/link-gbz80$(EXEEXT) `echo $(DESTDIR)$(bindir)/link-gbz80$(EXEEXT)|sed '$(transform)'`
-       $(STRIP) `echo $(DESTDIR)$(bindir)/link-gbz80$(EXEEXT)|sed '$(transform)'`
-
-uninstall:
-       cd $(DESTDIR)$(bindir); rm -f link-z80$(EXEEXT) link-gbz80$(EXEEXT)
-
-include $(srcdir)/clean.mk
diff --git a/link/README b/link/README
deleted file mode 100644 (file)
index 5aba86d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-sdcc/link
----------
-
-In gbdk the linker and assembler were split into seperate packages.
-
-For now I'm keeping that split, and leaving the mcs51 version as is.
-
--- Michael
diff --git a/link/clean.mk b/link/clean.mk
deleted file mode 100644 (file)
index e843581..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-clean:
-       $(MAKE) -C z80 clean
-
-distclean: clean
-       $(MAKE) -C z80 distclean
-       rm -f Makefile
diff --git a/link/z80/Makefile.in b/link/z80/Makefile.in
deleted file mode 100644 (file)
index 1f67a7f..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-VPATH        = @srcdir@
-srcdir       = @srcdir@
-top_builddir = @top_builddir@
-top_srcdir   = @top_srcdir@
-
-include $(top_builddir)Makefile.common
-
-OBJDIR = obj/$(EXT)
-
-SLIBSRC        = NewAlloc.c
-
-SRC    = lkarea.c lkdata.c lkeval.c lkhead.c lkihx.c lklex.c \
-         lklibr.c lklist.c lkmain.c lkrloc.c lks19.c lksym.c \
-         lkgb.c lkgg.c
-
-OBJS   = $(SRC:%.c=$(OBJDIR)/%.o) 
-SLIBOBJS       = $(SLIBSRC:%.c=$(OBJDIR)/%.o) 
-
-BINS   = $(BUILDDIR)link$(EXT)$(EXEEXT)
-
-CFLAGS += $(CPPFLAGS) $(OPTS) -DINDEXLIB -DMLH_MAP -DUNIX -DSDK
-CFLAGS += -funsigned-char -DUNIX
-CFLAGS += -I$(top_builddir)as/$(PORT) -I$(SLIB) 
-
-LDFLAGS += -lm $(EXTRALIBS)
-
-all:   $(BINS)
-
-$(BINS): $(OBJDIR) $(OBJS) $(SLIBOBJS)
-       $(CC) -g -o $(BINS) $(OBJS) $(SLIBOBJS) $(LDFLAGS)
-
-$(OBJDIR):
-       mkdir -p $(OBJDIR)
-
-$(OBJDIR)/%.o: %.c
-       $(CC) -c $(CFLAGS) -o $@ $<
-
-$(OBJDIR)/%.o: $(SLIB)/%.c
-       $(CC) -c $(CFLAGS) -o $@ $<
-
-_link-z80:
-       $(MAKE) EXT=-z80$(E) PORT=z80
-
-_link-gbz80:
-       $(MAKE) EXT=-gbz80$(E) OPTS=-DGAMEBOY PORT=z80
-
-include $(srcdir)/clean.mk
diff --git a/link/z80/aslink.h b/link/z80/aslink.h
deleted file mode 100644 (file)
index e18cd02..0000000
+++ /dev/null
@@ -1,737 +0,0 @@
-/* aslink.h */
-
-/*
- * (C) Copyright 1989-1996
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-/*
- * Extensions: P. Felber
- */
-#define        VERSION "V01.75"
-
-/*
- * Case Sensitivity Flag
- */
-#define        CASE_SENSITIVE  1
-
-/*)Module      asmlnk.h
- *
- *     The module asmlnk.h contains the definitions for constants,
- *     structures, global variables, and LKxxxx functions
- *     contained in the LKxxxx.c files.
- */
-
-/*)BUILD
-       $(PROGRAM) =    ASLINK
-       $(INCLUDE) =    ASLINK.H
-       $(FILES) = {
-               LKMAIN.C
-               LKLEX.C
-               LKAREA.C
-               LKHEAD.C
-               LKSYM.C
-               LKEVAL.C
-               LKDATA.C
-               LKLIST.C
-               LKRLOC.C
-               LKLIBR.C
-               LKS19.C
-               LKIHX.C
-       }
-       $(STACK) = 2000
-*/
-
-/* DECUS C void definition */
-/* File/extension seperator */
-
-#ifdef decus
-#define        VOID    char
-#define        FSEPX   '.'
-#endif
-
-/* PDOS C void definition */
-/* File/extension seperator */
-
-#ifdef PDOS
-#define        VOID    char
-#define        FSEPX   ':'
-#endif
-
-/* Default void definition */
-/* File/extension seperator */
-
-#ifndef        VOID
-#define        VOID    void
-#define        FSEPX   '.'
-#define        OTHERSYSTEM
-#endif
-
-/*
- * PATH_MAX
- */
-#include <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.
- */
-
-#ifdef SDK
-#define        NCPS    80              /* characters per symbol.  Used to be 32... */
-#else /* SDK */
-#define        NCPS    8               /* characters per symbol */
-#endif /* SDK */
-/* #define     NCPS    32 */   /* characters per symbol */
-#define        NDATA   16              /* actual data */
-#define        NINPUT  PATH_MAX        /* Input buffer size */
-#define        NHASH   64              /* Buckets in hash table */
-#define        HMASK   077             /* Hash mask */
-#define        NLPP    60              /* Lines per page */
-#define        NTXT    16              /* T values */
-#define        FILSPC  PATH_MAX        /* File spec length */
-
-/*
- *     The "R_" relocation constants define values used in
- *     generating the assembler relocation output data for
- *     areas, symbols, and code.
- *
- *
- *     Relocation types.
- *
- *            7     6     5     4     3     2     1     0
- *         +-----+-----+-----+-----+-----+-----+-----+-----+
- *         | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT |
- *         +-----+-----+-----+-----+-----+-----+-----+-----+
- */
-
-#define        R_WORD  0x00            /* 16 bit */
-#define        R_BYTE  0x01            /*  8 bit */
-
-#define        R_AREA  0x00            /* Base type */
-#define        R_SYM   0x02
-
-#define        R_NORM  0x00            /* PC adjust */
-#define        R_PCR   0x04
-
-#define        R_BYT1  0x00            /* Byte count for R_BYTE = 1 */
-#define        R_BYT2  0x08            /* Byte count for R_BYTE = 2 */
-
-#define        R_SGND  0x00            /* Signed value */
-#define        R_USGN  0x10            /* Unsigned value */
-
-#define        R_NOPAG 0x00            /* Page Mode */
-#define        R_PAG0  0x20            /* Page '0' */
-#define        R_PAG   0x40            /* Page 'nnn' */
-
-/*
- * Valid for R_BYT2:
- */
-#define        R_LSB   0x00            /* output low byte */
-#define        R_MSB   0x80            /* output high byte */
-
-/*
- * Global symbol types.
- */
-#define        S_REF   1               /* referenced */
-#define        S_DEF   2               /* defined */
-
-/*
- * Area types
- */
-#define        A_CON   0000            /* concatenate */
-#define        A_OVR   0004            /* overlay */
-#define        A_REL   0000            /* relocatable */
-#define        A_ABS   0010            /* absolute */
-#define        A_NOPAG 0000            /* non-paged */
-#define        A_PAG   0020            /* paged */
-
-/*
- * File types
- */
-#define F_INV  0               /* invalid */
-#define        F_STD   1               /* stdin */
-#define        F_LNK   2               /* File.lnk */
-#define        F_REL   3               /* File.rel */
-#ifdef SDK
-#define        F_CMD   4               /* Command line */
-#endif /* SDK */
-
-#ifdef GAMEBOY
-/*
- * Multiple banks support
- */
-extern int nb_rom_banks;
-extern int nb_ram_banks;
-extern int current_rom_bank;
-extern int mbc_type;
-extern char cart_name[];
-/*
- * ROM patching support
- */
-typedef struct _patch {
-  unsigned int addr;
-  unsigned char value;
-  struct _patch *next;
-} patch;
-extern patch* patches;
-#endif /* GAMEBOY */
-/*
- *     General assembler address type
- */
-typedef unsigned int Addr_T;
-
-/*
- *     The structures of head, area, areax, and sym are created
- *     as the REL files are read during the first pass of the
- *     linker.  The struct head is created upon encountering a
- *     H directive in the REL file.  The structure contains a
- *     link to a link file structure (struct lfile) which describes
- *     the file containing the H directive, the number of data/code
- *     areas contained in this header segment, the number of
- *     symbols referenced/defined in this header segment, a pointer
- *     to an array of pointers to areax structures (struct areax)
- *     created as each A directive is read, and a pointer to an
- *     array of pointers to symbol structures (struct sym) for
- *     all referenced/defined symbols.  As H directives are read
- *     from the REL files a linked list of head structures is
- *     created by placing a link to the new head structure
- *     in the previous head structure.
- */
-struct head
-{
-       struct  head   *h_hp;   /* Header link */
-       struct  lfile  *h_lfile;/* Associated file */
-       int     h_narea;        /* # of areas */
-       struct  areax **a_list; /* Area list */
-       int     h_nglob;        /* # of global symbols */
-       struct  sym   **s_list; /* Globle symbol list */
-       char    m_id[NCPS];     /* Module name */
-};
-
-/*
- *     A structure area is created for each 'unique' data/code
- *     area definition found as the REL files are read.  The
- *     struct area contains the name of the area, a flag byte
- *     which contains the area attributes (REL/CON/OVR/ABS),
- *     an area subtype (not used in this assembler), and the
- *     area base address and total size which will be filled
- *     in at the end of the first pass through the REL files.
- *     As A directives are read from the REL files a linked
- *     list of unique area structures is created by placing a
- *     link to the new area structure in the previous area structure.
- */
-struct area
-{
-       struct  area    *a_ap;  /* Area link */
-       struct  areax   *a_axp; /* Area extension link */
-       Addr_T  a_addr;         /* Beginning address of area */
-       Addr_T  a_size;         /* Total size of the area */
-       char    a_type;         /* Area subtype */
-       char    a_flag;         /* Flag byte */
-       char    a_id[NCPS];     /* Name */
-};
-
-/*
- *     An areax structure is created for every A directive found
- *     while reading the REL files.  The struct areax contains a
- *     link to the 'unique' area structure referenced by the A
- *     directive and to the head structure this area segment is
- *     a part of.  The size of this area segment as read from the
- *     A directive is placed in the areax structure.  The beginning
- *     address of this segment will be filled in at the end of the
- *     first pass through the REL files.  As A directives are read
- *     from the REL files a linked list of areax structures is
- *     created for each unique area.  The final areax linked
- *     list has at its head the 'unique' area structure linked
- *     to the linked areax structures (one areax structure for
- *     each A directive for this area).
- */
-struct areax
-{
-       struct  areax   *a_axp; /* Area extension link */
-       struct  area    *a_bap; /* Base area link */
-       struct  head    *a_bhp; /* Base header link */
-       Addr_T  a_addr;         /* Beginning address of section */
-       Addr_T  a_size;         /* Size of the area in section */
-};
-
-/*
- *     A sym structure is created for every unique symbol
- *     referenced/defined while reading the REL files.  The
- *     struct sym contains the symbol's name, a flag value
- *     (not used in this linker), a symbol type denoting
- *     referenced/defined, and an address which is loaded
- *     with the relative address within the area in which
- *     the symbol was defined.  The sym structure also
- *     contains a link to the area where the symbol was defined.
- *     The sym structures are linked into linked lists using
- *     the symbol link element.
- */
-struct sym
-{
-       struct  sym     *s_sp;  /* Symbol link */
-       struct  areax   *s_axp; /* Symbol area link */
-       char    s_type;         /* Symbol subtype */
-       char    s_flag;         /* Flag byte */
-       Addr_T  s_addr;         /* Address */
-       char    s_id[NCPS];     /* Name */
-};
-
-/*
- *     The structure lfile contains a pointer to a
- *     file specification string, the file type, and
- *     a link to the next lfile structure.
- */
-struct lfile
-{
-       struct  lfile   *f_flp; /* lfile link */
-       int     f_type;         /* File type */
-       char    *f_idp;         /* Pointer to file spec */
-};
-
-/*
- *     The struct base contains a pointer to a
- *     base definition string and a link to the next
- *     base structure.
- */
-struct base
-{
-       struct  base  *b_base;  /* Base link */
-       char          *b_strp;  /* String pointer */
-};
-
-/*
- *     The struct globl contains a pointer to a
- *     global definition string and a link to the next
- *     global structure.
- */
-struct globl
-{
-       struct  globl *g_globl; /* Global link */
-       char          *g_strp;  /* String pointer */
-};
-
-/*
- *     A structure sdp is created for each 'unique' paged
- *     area definition found as the REL files are read.
- *     As P directives are read from the REL files a linked
- *     list of unique sdp structures is created by placing a
- *     link to the new sdp structure in the previous area structure.
- */
-struct sdp
-{
-       struct  area  *s_area;  /* Paged Area link */
-       struct  areax *s_areax; /* Paged Area Extension Link */
-       Addr_T  s_addr;         /* Page address offset */
-};
-
-/*
- *     The structure rerr is loaded with the information
- *     required to report an error during the linking
- *     process.  The structure contains an index value
- *     which selects the areax structure from the header
- *     areax structure list, a mode value which selects
- *     symbol or area relocation, the base address in the
- *     area section, an area/symbol list index value, and
- *     an area/symbol offset value.
- */
-struct rerr
-{
-       int     aindex;         /* Linking area */
-       int     mode;           /* Relocation mode */
-       Addr_T  rtbase;         /* Base address in section */
-       int     rindex;         /* Area/Symbol reloaction index */
-       Addr_T  rval;           /* Area/Symbol offset value */
-};
-
-/*
- *     The structure lbpath is created for each library
- *     path specification input by the -k option.  The
- *     lbpath structures are linked into a list using
- *     the next link element.
- */
-struct lbpath {
-       struct  lbpath  *next;
-       char            *path;
-};
-
-/*
- *     The structure lbname is created for all combinations of the
- *     library path specifications (input by the -k option) and the
- *     library file specifications (input by the -l option) that
- *     lead to an existing file.  The element path points to
- *     the path string, element libfil points to the library
- *     file string, and the element libspc is the concatenation
- *     of the valid path and libfil strings.
- *
- *     The lbpath structures are linked into a list
- *     using the next link element.
- *
- *     Each library file contains a list of object files
- *     that are contained in the particular library. e.g.:
- *
- *             \iolib\termio
- *             \inilib\termio
- *
- *     Only one specification per line is allowed.
- */
-struct lbname {
-       struct  lbname  *next;
-       char            *path;
-       char            *libfil;
-       char            *libspc;
-};
-
-/*
- *     The function fndsym() searches through all combinations of the
- *     library path specifications (input by the -k option) and the
- *     library file specifications (input by the -l option) that
- *     lead to an existing file for a symbol definition.
- *
- *     The structure lbfile is created for the first library
- *     object file which contains the definition for the
- *     specified undefined symbol.
- *
- *     The element libspc points to the library file path specification
- *     and element relfil points to the object file specification string.
- *     The element filspc is the complete path/file specification for
- *     the library file to be imported into the linker.  The
- *     file specicifation may be formed in one of two ways:
- *
- *     (1)     If the library file contained an absolute
- *             path/file specification then this becomes filspc.
- *             (i.e. C:\...)
- *
- *     (2)     If the library file contains a relative path/file
- *             specification then the concatenation of the path
- *             and this file specification becomes filspc.
- *             (i.e. \...)
- *
- *     The lbpath structures are linked into a list
- *     using the next link element.
- */
-struct lbfile {
-       struct  lbfile  *next;
-       char            *libspc;
-       char            *relfil;
-       char            *filspc;
-    long               offset; /*>=0 if rel file is embedded in a lib file at this offset*/
-};
-
-/*
- *     External Definitions for all Global Variables
- */
-
-extern char    *_abs_;         /*      = { ".  .ABS." };
-                                */
-extern int     lkerr;          /*      ASLink error flag
-                                */
-extern char    *ip;            /*      pointer into the REL file
-                                *      text line in ib[]
-                                */
-extern char    ib[NINPUT];     /*      REL file text line
-                                */
-extern char    *rp;            /*      pointer into the LST file
-                                *      text line in rb[]
-                                */
-extern char    rb[NINPUT];     /*      LST file text line being
-                                *      address relocated
-                                */
-extern unsigned char   ctype[];        /*      array of character types, one per
-                                *      ASCII character
-                                */
-
-extern char sdccopt[NINPUT];
-extern char sdccopt_module[NINPUT];
-extern char curr_module[NINPUT];
-
-/*
- *     Character Type Definitions
- */
-#define        SPACE   0000
-#define ETC    0000
-#define        LETTER  0001
-#define        DIGIT   0002
-#define        BINOP   0004
-#define        RAD2    0010
-#define        RAD8    0020
-#define        RAD10   0040
-#define        RAD16   0100
-#define        ILL     0200
-
-#define        DGT2    DIGIT|RAD16|RAD10|RAD8|RAD2
-#define        DGT8    DIGIT|RAD16|RAD10|RAD8
-#define        DGT10   DIGIT|RAD16|RAD10
-#define        LTR16   LETTER|RAD16
-
-#if    CASE_SENSITIVE
-#else
-extern char    ccase[];        /*      an array of characters which
-                                *      perform the case translation function
-                                */
-#endif
-
-extern struct  lfile   *filep; /*      The pointers (lfile *) filep,
-                                *      (lfile *) cfp, and (FILE *) sfp
-                                *      are used in conjunction with
-                                *      the routine lk_getline() to read
-                                *      asmlnk commands from
-                                *      (1) the standard input or
-                                *      (2) or a command file
-                                *      and to read the REL files
-                                *      sequentially as defined by the
-                                *      asmlnk input commands.
-                                *
-                                *      The pointer *filep points to the
-                                *      beginning of a linked list of
-                                *      lfile structures.
-                                */
-extern struct  lfile   *cfp;   /*      The pointer *cfp points to the
-                                *      current lfile structure
-                                */
-extern struct  lfile   *startp;/*      asmlnk startup file structure
-                                */
-extern struct  lfile   *linkp; /*      pointer to first lfile structure
-                                *      containing an input REL file
-                                *      specification
-                                */
-extern struct  lfile   *lfp;   /*      pointer to current lfile structure
-                                *      being processed by parse()
-                                */
-extern struct  head    *headp; /*      The pointer to the first
-                                *      head structure of a linked list
-                                */
-extern struct  head    *hp;    /*      Pointer to the current
-                                *      head structure
-                                */
-extern struct  area    *areap; /*      The pointer to the first
-                                *      area structure of a linked list
-                                */
-extern struct  area    *ap;    /*      Pointer to the current
-                                *      area structure
-                                */
-extern struct  areax   *axp;   /*      Pointer to the current
-                                *      areax structure
-                                */
-extern struct  sym *symhash[NHASH]; /* array of pointers to NHASH
-                                     * linked symbol lists
-                                     */
-extern struct  base    *basep; /*      The pointer to the first
-                                *      base structure
-                                */
-extern struct  base    *bsp;   /*      Pointer to the current
-                                *      base structure
-                                */
-extern struct  globl   *globlp;/*      The pointer to the first
-                                *      globl structure
-                                */
-extern struct  globl   *gsp;   /*      Pointer to the current
-                                *      globl structure
-                                */
-extern struct  sdp     sdp;    /*      Base Paged structure
-                                */
-extern struct  rerr    rerr;   /*      Structure containing the
-                                *      linker error information
-                                */
-extern FILE    *ofp;           /*      Linker Output file handle
-                                */
-extern FILE    *mfp;           /*      Map output file handle
-                                */
-extern FILE    *rfp;           /*      File handle for output
-                                *      address relocated ASxxxx
-                                *      listing file
-                                */
-extern FILE    *sfp;           /*      The file handle sfp points to the
-                                *      currently open file
-                                */
-extern FILE    *tfp;           /*      File handle for input
-                                *      ASxxxx listing file
-                                */
-extern int     oflag;          /*      Output file type flag
-                                */
-extern int     mflag;          /*      Map output flag
-                                */
-#ifdef SDK
-extern int     symflag;        /*      no$gmb .sym output flag
-                                */
-#endif
-extern int     xflag;          /*      Map file radix type flag
-                                */
-extern int     pflag;          /*      print linker command file flag
-                                */
-extern int     uflag;          /*      Listing relocation flag
-                                */
-extern int     radix;          /*      current number conversion radix:
-                                *      2 (binary), 8 (octal), 10 (decimal),
-                                *      16 (hexadecimal)
-                                */
-extern int     line;           /*      current line number
-                                */
-extern int     page;           /*      current page number
-                                */
-extern int     lop;            /*      current line number on page
-                                */
-extern int     pass;           /*      linker pass number
-                                */
-extern int     rtcnt;          /*      count of elements in the
-                                *      rtval[] and rtflg[] arrays
-                                */
-extern Addr_T  rtval[];        /*      data associated with relocation
-                                */
-extern int     rtflg[];        /*      indicates if rtval[] value is
-                                *      to be sent to the output file.
-                                *      (always set in this linker)
-                                */
-extern int     hilo;           /*      REL file byte ordering
-                                */
-extern int     gline;          /*      LST file relocation active
-                                *      for current line
-                                */
-extern int     gcntr;          /*      LST file relocation active
-                                *      counter
-                                */
-extern struct lbpath *lbphead; /*      pointer to the first
-                                *      library path structure
-                                */
-extern struct lbname *lbnhead; /*      pointer to the first
-                                *      library name structure
-                                */
-extern struct lbfile *lbfhead; /*      pointer to the first
-                                *      library file structure
-                                */
-
-/* C Library function definitions */
-/* for reference only
-extern VOID            exit();
-extern int             fclose();
-extern char *          fgets();
-extern FILE *          fopen();
-extern int             fprintf();
-extern VOID            free();
-extern VOID *          malloc();
-extern char            putc();
-extern char *          strcpy();
-extern int             strlen();
-extern char *          strncpy();
-*/
-
-/* Program function definitions */
-
-/* lkmain.c */
-extern FILE *          afile();
-extern VOID            bassav();
-extern VOID            gblsav();
-extern VOID            link();
-extern VOID            lkexit();
-extern int             main();
-extern VOID            map();
-#ifdef SDK
-extern VOID            sym();
-#endif
-extern int             parse();
-extern VOID            setbas();
-extern VOID            setgbl();
-extern VOID            usage();
-
-/* lklex.c */
-extern char            endline();
-extern char            get();
-extern VOID            getfid();
-extern VOID            getid();
-extern int             lk_getline();
-extern int             getmap();
-extern char            getnb();
-extern int             more();
-extern VOID            skip();
-extern VOID            unget();
-extern VOID            chop_crlf();
-
-/* lkarea.c */
-extern VOID            lkparea();
-extern VOID            lnkarea();
-extern VOID            lnksect();
-extern VOID            newarea();
-
-/* lkhead.c */
-extern VOID            module();
-extern VOID            newhead();
-
-/* lksym.c */
-extern int             hash();
-extern struct  sym *   lkpsym();
-extern VOID *          new();
-extern struct  sym *   newsym();
-extern VOID            symdef();
-extern int             symeq();
-extern VOID            syminit();
-extern VOID            symmod();
-extern Addr_T          symval();
-
-/* lkeval.c */
-extern int             digit();
-extern Addr_T          eval();
-extern Addr_T          expr();
-extern int             oprio();
-extern Addr_T          term();
-
-/* lklist.c */
-extern int             dgt();
-extern VOID            lkulist();
-extern VOID            lkalist();
-extern VOID            lkglist();
-extern VOID            lstarea();
-extern VOID            newpag();
-extern VOID            slew();
-
-/* lkrloc.c */
-extern Addr_T          adb_b();
-extern Addr_T          adb_hi();
-extern Addr_T          adb_lo();
-extern Addr_T          adw_w();
-extern Addr_T          adw_hi();
-extern Addr_T          adw_lo();
-extern Addr_T          evword();
-extern VOID            rele();
-extern VOID            reloc();
-extern VOID            relt();
-extern VOID            relr();
-extern VOID            relp();
-extern VOID            relerr();
-extern char *          errmsg[];
-extern VOID            errdmp();
-extern VOID            relerp();
-extern VOID            erpdmp();
-extern VOID            prntval();
-
-/* lklibr.c */
-extern int             addfile();
-extern VOID            addlib();
-extern VOID            addpath();
-extern int             fndsym();
-extern VOID            library();
-extern VOID            loadfile();
-extern VOID            search();
-
-/* lks19.c */
-extern VOID            s19();
-
-/* lkihx.c */
-extern VOID            ihx();
-
-/* lkgb.h */
-VOID gb(int in);
-VOID gg(int in);
-
diff --git a/link/z80/clean.mk b/link/z80/clean.mk
deleted file mode 100644 (file)
index 4e13a89..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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/link-z80$(EXEEXT) link-z80$(EXEEXT) \
-             $(top_builddir)bin/link-gbz80$(EXEEXT) link-gbz80$(EXEEXT)
-       rm -f *.dep
-       rm -rf obj
-
-# Deleting all files created by configuring or building the program
-# -----------------------------------------------------------------
-distclean: clean
-       rm -f Makefile
-
-# 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/link/z80/conf.mk b/link/z80/conf.mk
deleted file mode 100644 (file)
index 3fa379d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Deleting all files created by building the program
-# --------------------------------------------------
-clean:
-       rm -f *core *[%~] *.[oa]
-       rm -f .[a-z]*~
-       rm -f $(top_builddir)bin/link-z80 link-z80
-
-
-# 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/link/z80/linkgbz80.dsp b/link/z80/linkgbz80.dsp
deleted file mode 100644 (file)
index 80e1d50..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-# Microsoft Developer Studio Project File - Name="linkgbz80" - 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=linkgbz80 - Win32 Debug\r
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "linkgbz80.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 "linkgbz80.mak" CFG="linkgbz80 - Win32 Debug"\r
-!MESSAGE \r
-!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
-!MESSAGE "linkgbz80 - Win32 Release" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "linkgbz80 - Win32 Debug" (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)" == "linkgbz80 - Win32 Release"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 0\r
-# PROP BASE Output_Dir "Release_gbz80"\r
-# PROP BASE Intermediate_Dir "Release_gbz80"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 0\r
-# PROP Output_Dir "Release_gbz80"\r
-# PROP Intermediate_Dir "Release_gbz80"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
-# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\bin_vc\link-gbz80.exe"\r
-# SUBTRACT LINK32 /pdb:none\r
-\r
-!ELSEIF  "$(CFG)" == "linkgbz80 - Win32 Debug"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "Debug_gbz80"\r
-# PROP BASE Intermediate_Dir "Debug_gbz80"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "Debug_gbz80"\r
-# PROP Intermediate_Dir "Debug_gbz80"\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" /YX /FD /GZ /c\r
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\bin_vc\link-gbz80.exe" /pdbtype:sept\r
-# SUBTRACT LINK32 /pdb:none\r
-\r
-!ENDIF \r
-\r
-# Begin Target\r
-\r
-# Name "linkgbz80 - Win32 Release"\r
-# Name "linkgbz80 - Win32 Debug"\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=.\lkarea.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkdata.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkeval.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkgb.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkgg.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkhead.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkihx.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lklex.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lklibr.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lklist.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkmain.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkrloc.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lks19.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lksym.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB" /D "GAMEBOY"\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=.\aslink.h\r
-# End Source File\r
-# End Group\r
-# Begin Group "Resource Files"\r
-\r
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
-# End Group\r
-# End Target\r
-# End Project\r
diff --git a/link/z80/linkz80.dsp b/link/z80/linkz80.dsp
deleted file mode 100644 (file)
index eb63e0c..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-# Microsoft Developer Studio Project File - Name="linkz80" - 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=linkz80 - Win32 Debug\r
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
-!MESSAGE use the Export Makefile command and run\r
-!MESSAGE \r
-!MESSAGE NMAKE /f "linkz80.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 "linkz80.mak" CFG="linkz80 - Win32 Debug"\r
-!MESSAGE \r
-!MESSAGE Possible choices for configuration are:\r
-!MESSAGE \r
-!MESSAGE "linkz80 - Win32 Release" (based on "Win32 (x86) Console Application")\r
-!MESSAGE "linkz80 - Win32 Debug" (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)" == "linkz80 - Win32 Release"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 0\r
-# PROP BASE Output_Dir "Release_z80"\r
-# PROP BASE Intermediate_Dir "Release_z80"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 0\r
-# PROP Output_Dir "Release_z80"\r
-# PROP Intermediate_Dir "Release_z80"\r
-# PROP Ignore_Export_Lib 0\r
-# PROP Target_Dir ""\r
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
-# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"..\..\bin_vc\link-z80.exe"\r
-# SUBTRACT LINK32 /pdb:none\r
-\r
-!ELSEIF  "$(CFG)" == "linkz80 - Win32 Debug"\r
-\r
-# PROP BASE Use_MFC 0\r
-# PROP BASE Use_Debug_Libraries 1\r
-# PROP BASE Output_Dir "Debug_z80"\r
-# PROP BASE Intermediate_Dir "Debug_z80"\r
-# PROP BASE Target_Dir ""\r
-# PROP Use_MFC 0\r
-# PROP Use_Debug_Libraries 1\r
-# PROP Output_Dir "Debug_z80"\r
-# PROP Intermediate_Dir "Debug_z80"\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" /YX /FD /GZ /c\r
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
-# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"..\..\bin_vc\link-z80.exe" /pdbtype:sept\r
-# SUBTRACT LINK32 /pdb:none\r
-\r
-!ENDIF \r
-\r
-# Begin Target\r
-\r
-# Name "linkz80 - Win32 Release"\r
-# Name "linkz80 - Win32 Debug"\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=.\lkarea.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkdata.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkeval.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkgb.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkgg.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkhead.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkihx.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lklex.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lklibr.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lklist.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkmain.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lkrloc.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lks19.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\lksym.c\r
-# ADD CPP /D "SDK" /D "INDEXLIB"\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=.\aslink.h\r
-# End Source File\r
-# End Group\r
-# Begin Group "Resource Files"\r
-\r
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
-# End Group\r
-# End Target\r
-# End Project\r
diff --git a/link/z80/lkarea.c b/link/z80/lkarea.c
deleted file mode 100644 (file)
index deb61c9..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/* lkarea.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      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 tha 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++;
-               }
-       }
-       /*
-        * 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(id)
-char *id;
-{
-       register struct area *tap;
-       register struct areax *taxp;
-
-       ap = areap;
-       axp = (struct areax *) new (sizeof(struct areax));
-       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);
-}
-
-/*)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 ae 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()        lksysm.c
- *             char *  strncpy()       c_library
- *             int     symeq()         lksysm.c
- *
- *     side effects:
- *             All area and areax addresses and sizes are
- *             determined and saved in their respective
- *             structures.
- */
-
-/*
- * Resolve all area addresses.
- */
-VOID
-lnkarea()
-{
-       register int rloc;
-       char temp[NCPS];
-       struct sym *sp;
-
-       rloc = 0;
-       ap = areap;
-       while (ap) {
-               if (ap->a_flag&A_ABS) {
-                       /*
-                        * Absolute sections
-                        */
-                       lnksect(ap);
-               } else {
-                       /*
-                        * Relocatable sections
-                        */
-                       if (ap->a_addr == 0)
-                               ap->a_addr = rloc;
-                       lnksect(ap);
-                       rloc = 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 = 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;
-               }
-               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(tap)
-register struct area *tap;
-{
-       register Addr_T size, addr;
-       register struct areax *taxp;
-
-       size = 0;
-       addr = tap->a_addr;
-       if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
-           fprintf(stderr,
-           "\n?ASlink-Warning-Paged Area %.8s Boundary Error\n", tap->a_id);
-           lkerr++;
-       }
-       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++;
-       }
-}
diff --git a/link/z80/lkdata.c b/link/z80/lkdata.c
deleted file mode 100644 (file)
index 3d075b7..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-/* lkdata.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-//#include <alloc.h>
-#include "aslink.h"
-
-/*)Module      lkdata.c
- *
- *     The module lkdata contains the global variables
- *     and structures used in the linker aslink.
- */
-
-/*
- *     Definitions for all Global Variables
- */
-
-char   *_abs_  = { ".  .ABS." };
-
-int    lkerr;          /*      Linker error flag
-                        */
-char   *ip;            /*      Pointer into the REL file text line in ib[]
-                        */
-char   ib[NINPUT];     /*      REL file text line
-                        */
-char   *rp;            /*      pointer into the LST file
-                        *      text line in rb[]
-                        */
-char   rb[NINPUT];     /*      LST file text line being
-                        *      address relocated
-                        */
-
-char sdccopt[NINPUT]="";
-char sdccopt_module[NINPUT]="";
-char curr_module[NINPUT]="";
-
-int    oflag;          /*      Output file type flag
-                        */
-int    mflag;          /*      Map output flag
-                        */
-#ifdef SDK
-int    symflag;        /*      no$gmb .sym output flag
-                        */
-#endif
-int    xflag;          /*      Map file radix type flag
-                        */
-int    pflag;          /*      print linker command file flag
-                        */
-int    uflag;          /*      Listing relocation flag
-                        */
-int    radix;          /*      current number conversion radix:
-                        *      2 (binary), 8 (octal), 10 (decimal),
-                        *      16 (hexadecimal)
-                        */
-int    line;           /*      current line number
-                        */
-int    page;           /*      current page number
-                        */
-int    lop;            /*      current line number on page
-                        */
-int    pass;           /*      linker pass number
-                        */
-int    rtcnt;          /*      count of elements in the
-                        *      rtval[] and rtflg[] arrays
-                        */
-Addr_T rtval[NTXT];    /*      data associated with relocation
-                        */
-int    rtflg[NTXT];    /*      indicates if rtval[] value is
-                        *      to be sent to the output file.
-                        *      (always set in this linker)
-                        */
-int    hilo;           /*      REL file byte ordering
-                        */
-int    gline;          /*      LST file relocation active
-                        *      for current line
-                        */
-int    gcntr;          /*      LST file relocation active
-                        *      counter
-                        */
-
-/*
- *     The structure lfile contains a pointer to a
- *     file specification string, the file type, and
- *     a link to the next lfile structure.
- *
- *     struct  lfile
- *     {
- *             struct  lfile   *f_flp;         lfile link
- *             int     f_type;                 File type
- *             char    *f_idp;                 Pointer to file spec
- *     };
- */
-struct lfile   *filep; /*      The pointers (lfile *) filep,
-                        *      (lfile *) cfp, and (FILE *) sfp
-                        *      are used in conjunction with
-                        *      the routine lk_getline() to read
-                        *      asmlnk commands from
-                        *      (1) the standard input or
-                        *      (2) or a command file
-                        *      and to read the REL files
-                        *      sequentially as defined by the
-                        *      asmlnk input commands.
-                        *
-                        *      The pointer *filep points to the
-                        *      beginning of a linked list of
-                        *      lfile structures.
-                        */
-struct lfile   *cfp;   /*      The pointer *cfp points to the
-                        *      current lfile structure
-                        */
-struct lfile   *startp;/*      asmlnk startup file structure
-                        */
-struct lfile   *linkp; /*      pointer to first lfile structure
-                        *      containing an input REL file
-                        *      specification
-                        */
-struct lfile   *lfp;   /*      pointer to current lfile structure
-                        *      being processed by parse()
-                        */
-FILE   *ofp;           /*      Output file handle
-                        *      for word formats
-                        */
-FILE   *mfp;           /*      Map output file handle
-                        */
-FILE   *rfp;           /*      File handle for output
-                        *      address relocated ASxxxx
-                        *      listing file
-                        */
-FILE   *sfp;           /*      The file handle sfp points to the
-                        *      currently open file
-                        */
-FILE   *tfp;           /*      File handle for input
-                        *      ASxxxx listing file
-                        */
-
-/*
- *     The structures of head, area, areax, and sym are created
- *     as the REL files are read during the first pass of the
- *     linker.  The struct head is created upon encountering a
- *     H directive in the REL file.  The structure contains a
- *     link to a link file structure (struct lfile) which describes
- *     the file containing the H directive, the number of data/code
- *     areas contained in this header segment, the number of
- *     symbols referenced/defined in this header segment, a pointer
- *     to an array of pointers to areax structures (struct areax)
- *     created as each A directive is read, and a pointer to an
- *     array of pointers to symbol structures (struct sym) for
- *     all referenced/defined symbols.  As H directives are read
- *     from the REL files a linked list of head structures is
- *     created by placing a link to the new head structure
- *     in the previous head structure.
- *
- *     struct  head
- *     {
- *             struct  head   *h_hp;           Header link
- *             struct  lfile  *h_lfile;        Associated file
- *             int     h_narea;                # of areas
- *             struct  areax **a_list;         Area list
- *             int     h_nglob;                # of global symbols
- *             struct  sym   **s_list;         Global symbol list
- *             char    m_id[NCPS];             Module name
- *     };
- */
-struct head    *headp; /*      The pointer to the first
-                        *      head structure of a linked list
-                        */
-struct head    *hp;    /*      Pointer to the current
-                        *      head structure
-                        */
-
-/*
- *     A structure area is created for each 'unique' data/code
- *     area definition found as the REL files are read.  The
- *     struct area contains the name of the area, a flag byte
- *     which contains the area attributes (REL/CON/OVR/ABS),
- *     an area subtype (not used in this assembler), and the
- *     area base address and total size which will be filled
- *     in at the end of the first pass through the REL files.
- *     As A directives are read from the REL files a linked
- *     list of unique area structures is created by placing a
- *     link to the new area structure in the previous area structure.
- *
- *     struct  area
- *     {
- *             struct  area    *a_ap;          Area link
- *             struct  areax   *a_axp;         Area extension link
- *             Addr_T  a_addr;                 Beginning address of area
- *             Addr_T  a_size;                 Total size of the area
- *             char    a_type;                 Area subtype
- *             char    a_flag;                 Flag byte
- *             char    a_id[NCPS];             Name
- *     };
- */
-struct area    *areap; /*      The pointer to the first
-                        *      area structure of a linked list
-                        */
-struct area    *ap;    /*      Pointer to the current
-                        *      area structure
-                        */
-
-/*
- *     An areax structure is created for every A directive found
- *     while reading the REL files.  The struct areax contains a
- *     link to the 'unique' area structure referenced by the A
- *     directive and to the head structure this area segment is
- *     a part of.  The size of this area segment as read from the
- *     A directive is placed in the areax structure.  The beginning
- *     address of this segment will be filled in at the end of the
- *     first pass through the REL files.  As A directives are read
- *     from the REL files a linked list of areax structures is
- *     created for each unique area.  The final areax linked
- *     list has at its head the 'unique' area structure linked
- *     to the linked areax structures (one areax structure for
- *     each A directive for this area).
- *
- *     struct  areax
- *     {
- *             struct  areax   *a_axp;         Area extension link
- *             struct  area    *a_bap;         Base area link
- *             struct  head    *a_bhp;         Base header link
- *             Addr_T  a_addr;                 Beginning address of section
- *             Addr_T  a_size;                 Size of the area in section
- *     };
- */
-struct areax   *axp;   /*      Pointer to the current
-                        *      areax structure
-                        */
-
-/*
- *     A sym structure is created for every unique symbol
- *     referenced/defined while reading the REL files.  The
- *     struct sym contains the symbol's name, a flag value
- *     (not used in this linker), a symbol type denoting
- *     referenced/defined, and an address which is loaded
- *     with the relative address within the area in which
- *     the symbol was defined.  The sym structure also
- *     contains a link to the area where the symbol was defined.
- *     The sym structures are linked into linked lists using
- *     the symbol link element.
- *
- *     struct  sym
- *     {
- *             struct  sym     *s_sp;          Symbol link
- *             struct  areax   *s_axp;         Symbol area link
- *             char    s_type;                 Symbol subtype
- *             char    s_flag;                 Flag byte
- *             Addr_T  s_addr;                 Address
- *             char    s_id[NCPS];             Name
- *     };
- */
-struct sym *symhash[NHASH]; /* array of pointers to NHASH
-                             * linked symbol lists
-                             */
-/*
- *     The struct base contains a pointer to a
- *     base definition string and a link to the next
- *     base structure.
- *
- *     struct  base
- *     {
- *             struct  base  *b_base;          Base link
- *             char          *b_strp;          String pointer
- *     };
- */
-struct base    *basep; /*      The pointer to the first
-                        *      base structure
-                        */
-struct base    *bsp;   /*      Pointer to the current
-                        *      base structure
-                        */
-
-/*
- *     The struct globl contains a pointer to a
- *     global definition string and a link to the next
- *     global structure.
- *
- *     struct  globl
- *     {
- *             struct  globl *g_globl;         Global link
- *             char          *g_strp;          String pointer
- *     };
- */
-struct globl   *globlp;/*      The pointer to the first
-                        *      globl structure
-                        */
-struct globl   *gsp;   /*      Pointer to the current
-                        *      globl structure
-                        */
-
-/*
- *     A structure sdp is created for each 'unique' paged
- *     area definition found as the REL files are read.
- *     As P directives are read from the REL files a linked
- *     list of unique sdp structures is created by placing a
- *     link to the new sdp structure in the previous area structure.
- *
- *     struct  sdp
- *     {
- *             struct  area  *s_area;  Paged Area link
- *             struct  areax *s_areax; Paged Area Extension Link
- *             Addr_T  s_addr;         Page address offset
- *     };
- */
-struct sdp     sdp;    /* Base Page Structure */
-
-/*
- *     The structure rerr is loaded with the information
- *     required to report an error during the linking
- *     process.  The structure contains an index value
- *     which selects the areax structure from the header
- *     areax structure list, a mode value which selects
- *     symbol or area relocation, the base address in the
- *     area section, an area/symbol list index value, and
- *     an area/symbol offset value.
- *
- *     struct  rerr
- *     {
- *             int     aindex;         Linking area
- *             int     mode;           Relocation mode
- *             Addr_T  rtbase;         Base address in section
- *             int     rindex;         Area/Symbol reloaction index
- *             Addr_T  rval;           Area/Symbol offset value
- *     };
- */
-struct rerr    rerr;   /*      Structure containing the
-                        *      linker error information
-                        */
-
-/*
- *     The structure lbpath is created for each library
- *     path specification input by the -k option.  The
- *     lbpath structures are linked into a list using
- *     the next link element.
- *
- *     struct lbpath {
- *             struct  lbpath  *next;
- *             char            *path;
- *     };
- */
-struct lbpath  *lbphead;       /*      pointer to the first
-                                *      library path structure
-                                */
-
-/*
- *     The structure lbname is created for all combinations of the
- *     library path specifications (input by the -k option) and the
- *     library file specifications (input by the -l option) that
- *     lead to an existing file.  The element path points to
- *     the path string, element libfil points to the library
- *     file string, and the element libspc is the concatenation
- *     of the valid path and libfil strings.
- *
- *     The lbpath structures are linked into a list
- *     using the next link element.
- *
- *     Each library file contains a list of object files
- *     that are contained in the particular library. e.g.:
- *
- *             \iolib\termio
- *             \inilib\termio
- *
- *     Only one specification per line is allowed.
- *
- *     struct lbname {
- *             struct  lbname  *next;
- *             char            *path;
- *             char            *libfil;
- *             char            *libspc;
- *     };
- */
-struct lbname  *lbnhead;       /*      pointer to the first
-                                *      library name structure
-                                */
-
-/*
- *     The function fndsym() searches through all combinations of the
- *     library path specifications (input by the -k option) and the
- *     library file specifications (input by the -l option) that
- *     lead to an existing file for a symbol definition.
- *
- *     The structure lbfile is created for the first library
- *     object file which contains the definition for the
- *     specified undefined symbol.
- *
- *     The element libspc points to the library file path specification
- *     and element relfil points to the object file specification string.
- *     The element filspc is the complete path/file specification for
- *     the library file to be imported into the linker.  The
- *     file specicifation may be formed in one of two ways:
- *
- *     (1)     If the library file contained an absolute
- *             path/file specification then this becomes filspc.
- *             (i.e. C:\...)
- *
- *     (2)     If the library file contains a relative path/file
- *             specification then the concatenation of the path
- *             and this file specification becomes filspc.
- *             (i.e. \...)
- *
- *     The lbpath structures are linked into a list
- *     using the next link element.
- *
- *     struct lbfile {
- *             struct  lbfile  *next;
- *             char            *libspc;
- *             char            *relfil;
- *             char            *filspc;
- *     };
- */
-struct lbfile  *lbfhead;       /*      pointer to the first
-                                *      library file structure
-                                */
-
-/*
- *     array of character types, one per
- *     ASCII character
- */
-unsigned char  ctype[128] = {
-/*NUL*/        ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
-/*BS*/ ILL,    SPACE,  ILL,    ILL,    SPACE,  ILL,    ILL,    ILL,
-/*DLE*/        ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
-/*CAN*/        ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,    ILL,
-/*SPC*/        SPACE,  ETC,    ETC,    ETC,    LETTER, BINOP,  BINOP,  ETC,
-/*(*/  ETC,    ETC,    BINOP,  BINOP,  ETC,    BINOP,  LETTER, BINOP,
-/*0*/  DGT2,   DGT2,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,   DGT8,
-/*8*/  DGT10,  DGT10,  ETC,    ETC,    BINOP,  ETC,    BINOP,  ETC,
-/*@*/  ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
-/*H*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*P*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*X*/  LETTER, LETTER, LETTER, ETC,    ETC,    ETC,    BINOP,  LETTER,
-/*`*/  ETC,    LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LTR16,  LETTER,
-/*h*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*p*/  LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
-/*x*/  LETTER, LETTER, LETTER, ETC,    BINOP,  ETC,    ETC,    ETC
-};
-
-/*
- *     an array of characters which
- *     perform the case translation function
- */
-#if    CASE_SENSITIVE
-#else
-char   ccase[128] = {
-/*NUL*/        '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
-/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
-/*DLE*/        '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
-/*CAN*/        '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
-/*SPC*/        '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
-/*(*/  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
-/*0*/  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
-/*8*/  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
-/*@*/  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-/*H*/  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-/*P*/  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-/*X*/  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
-/*`*/  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-/*h*/  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-/*p*/  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-/*x*/  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177'
-};     
-#endif
diff --git a/link/z80/lkeval.c b/link/z80/lkeval.c
deleted file mode 100644 (file)
index e4bfe1d..0000000
+++ /dev/null
@@ -1,398 +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 <alloc.h>
-#include "aslink.h"
-
-/*)Module      lkeval.c
- *
- *     The module lkeval.c contains the routines to evaluate
- *     arithmetic/numerical expressions.  The functions in
- *     lkeval.c perform a recursive evaluation of the arithmetic
- *     expression read from the input text line.
- *     The expression may include binary/unary operators, brackets,
- *     symbols, labels, and constants in hexadecimal, decimal, octal
- *     and binary.  Arithmetic operations are prioritized and
- *     evaluated by normal arithmetic conventions.
- *
- *     lkeval.c contains the following functions:
- *             int     digit()
- *             Addr_T  eval()
- *             Addr_T  expr()
- *             int     oprio()
- *             Addr_T  term()
- *
- *     lkeval.c contains no local/static variables
- */
-
-/*)Function    Addr_T  eval()
- *
- *     The function eval() evaluates a character string to a
- *     numerical value.
- *
- *     local variables:
- *             int     c               character from input string
- *             int     v               value of character in current radix
- *             Addr_T  n               evaluation value
- *
- *     global variables:
- *             int     radix           current number conversion radix
- *
- *     functions called:
- *             int     digit()         lkeval.c
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             Input test is scanned and evaluated to a
- *             numerical value.
- */
-
-Addr_T
-eval()
-{
-       register int c, v;
-       register Addr_T n;
-
-       c = getnb();
-       n = 0;
-       while ((v = digit(c, radix)) >= 0) {
-               n = n*radix + v;
-               c = get();
-       }
-       unget(c);
-       return(n);
-}
-
-/*)Function    Addr_T  expr(n)
- *
- *             int     n               a firewall priority; all top
- *                                     level calls (from the user)
- *                                     should be made with n set to 0.
- *
- *     The function expr() evaluates an expression and
- *     returns the value.
- *
- *     local variables:
- *             int     c               current input text character
- *             int     p               current operator priority
- *             Addr_T  v               value returned by term()
- *             Addr_T  ve              value returned by a
- *                                     recursive call to expr()
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             int     lkerr           error flag
- *             FILE *  stderr          c_library
- *
- *     functions called:
- *             VOID    expr()          lkeval.c
- *             int     fprintf()       c_library
- *             int     getnb()         lklex.c
- *             int     oprio()         lkeval.c
- *             VOID    term()          lkeval.c
- *             VOID    unget()         lklex.c
- *
- *
- *     side effects:
- *             An expression is evaluated by scanning the input
- *             text string.
- */
-
-Addr_T
-expr (n)
-{
-       register int c, p;
-       register Addr_T v, ve;
-
-       v = term();
-       while (ctype[c = getnb()] & BINOP) {
-               if ((p = oprio(c)) <= n)
-                       break;
-               if ((c == '>' || c == '<') && c != get()) {
-                       fprintf(stderr, "Invalid expression");
-                       lkerr++;
-                       return(v);
-               }
-               ve = expr(p);
-               if (c == '+') {
-                       v += ve;
-               } else
-               if (c == '-') {
-                       v -= ve;
-               } else {
-                       switch (c) {
-
-                       case '*':
-                               v *= ve;
-                               break;
-
-                       case '/':
-                               v /= ve;
-                               break;
-
-                       case '&':
-                               v &= ve;
-                               break;
-
-                       case '|':
-                               v |= ve;
-                               break;
-
-                       case '%':
-                               v %= ve;
-                               break;
-
-                       case '^':
-                               v ^= ve;
-                               break;
-
-                       case '<':
-                               v <<= ve;
-                               break;
-
-                       case '>':
-                               v >>= ve;
-                               break;
-                       }
-               }
-       }
-       unget(c);
-       return(v);
-}
-
-/*)Function    Addr_T  term()
- *
- *     The function term() evaluates a single constant
- *     or symbol value prefaced by any unary operator
- *     ( +, -, ~, ', ", >, or < ).
- *
- *     local variables:
- *             int     c               current character
- *             char    id[]            symbol name
- *             int     n               value of digit in current radix
- *             int     r               current evaluation radix
- *             sym *   sp              pointer to a sym structure
- *             Addr_T  v               evaluation value
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             int     lkerr           error flag
- *
- *     functions called:
- *             int     digit()         lkeval.c
- *             VOID    expr()          lkeval.c
- *             int     fprintf()       c_library
- *             int     get()           lklex.c
- *             VOID    getid()         lklex.c
- *             int     getmap()        lklex.c
- *             int     getnb()         lklex.c
- *             sym *   lkpsym()        lksym.c
- *             Addr_T  symval()        lksym.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             An arithmetic term is evaluated by scanning input text.
- */
-
-Addr_T
-term()
-{
-       register int c, r, n;
-       register Addr_T v;
-       struct sym *sp;
-       char id[NCPS];
-
-       c = getnb();
-       if (c == '#') { c = getnb(); }
-       if (c == '(') {
-               v = expr(0);
-               if (getnb() != ')') {
-                       fprintf(stderr, "Missing delimiter");
-                       lkerr++;
-               }
-               return(v);
-       }
-       if (c == '-') {
-               return(0-expr(100));
-       }
-       if (c == '~') {
-               return(~expr(100));
-       }
-       if (c == '\'') {
-               return(getmap(-1)&0377);
-       }
-       if (c == '\"') {
-               if (hilo) {
-                       v  = (getmap(-1)&0377)<<8;
-                       v |=  getmap(-1)&0377;
-               } else {
-                       v  =  getmap(-1)&0377;
-                       v |= (getmap(-1)&0377)<<8;
-               }
-               return(v);
-       }
-       if (c == '>' || c == '<') {
-               v = expr(100);
-               if (c == '>')
-                       v >>= 8;
-               return(v&0377);
-       }
-       if (ctype[c] & DIGIT) {
-               r = 10;
-               if (c == '0') {
-                       c = get();
-                       switch (c) {
-                       case 'b':
-                       case 'B':
-                               r = 2;
-                               c = get();
-                               break;
-                       case '@':
-                       case 'o':
-                       case 'O':
-                       case 'q':
-                       case 'Q':
-                               r = 8;
-                               c = get();
-                               break;
-                       case 'd':
-                       case 'D':
-                               r = 10;
-                               c = get();
-                               break;
-                       case 'h':
-                       case 'H':
-                       case 'x':
-                       case 'X':
-                               r = 16;
-                               c = get();
-                               break;
-                       default:
-                               break;
-                       }
-               }
-               v = 0;
-               while ((n = digit(c, r)) >= 0) {
-                       v = r*v + n;
-                       c = get();
-               }
-               unget(c);
-               return(v);
-       }
-       if (ctype[c] & LETTER) {
-               getid(id, c);
-               if ((sp = lkpsym(id, 0)) == NULL) {
-                       fprintf(stderr, "Undefined symbol %8s\n", id);
-                       lkerr++;
-                       return(0);
-               } else {
-                       return(symval(sp));
-               }
-       }
-        /* Shouldn't get here. */
-        return 0;
-}
-
-/*)Function    int     digit(c, r)
- *
- *             int     c               digit character
- *             int     r               current radix
- *
- *     The function digit() returns the value of c
- *     in the current radix r.  If the c value is not
- *     a number of the current radix then a -1 is returned.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-
-int
-digit(c, r)
-register int c, r;
-{
-       if (r == 16) {
-               if (ctype[c] & RAD16) {
-                       if (c >= 'A' && c <= 'F')
-                               return (c - 'A' + 10);
-                       if (c >= 'a' && c <= 'f')
-                               return (c - 'a' + 10);
-                       return (c - '0');
-               }
-       } else
-       if (r == 10) {
-               if (ctype[c] & RAD10)
-                       return (c - '0');
-       } else
-       if (r == 8) {
-               if (ctype[c] & RAD8)
-                       return (c - '0');
-       } else
-       if (r == 2) {
-               if (ctype[c] & RAD2)
-                       return (c - '0');
-       }
-       return (-1);
-}
-
-/*)Function    int     oprio(c)
- *
- *             int     c               operator character
- *
- *     The function oprio() returns a relative priority
- *     for all valid unary and binary operators.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             none
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-int
-oprio(c)
-register int c;
-{
-       if (c == '*' || c == '/' || c == '%')
-               return (10);
-       if (c == '+' || c == '-')
-               return (7);
-       if (c == '<' || c == '>')
-               return (5);
-       if (c == '^')
-               return (4);
-       if (c == '&')
-               return (3);
-       if (c == '|')
-               return (1);
-       return (0);
-}
diff --git a/link/z80/lkgb.c b/link/z80/lkgb.c
deleted file mode 100644 (file)
index 55ae41f..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/* lkgb.c */
-
-/*
- * P. Felber
- */
-
-#ifdef GAMEBOY
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "aslink.h"
-
-/* Value used to fill the unused portions of the image */
-/* FFh puts less stress on a EPROM/Flash */
-#define FILLVALUE      0xFF
-
-#define CARTSIZE ((unsigned long)nb_rom_banks*16UL*1024UL)
-#define NBSEG 8UL
-#define SEGSIZE (CARTSIZE/NBSEG)
-
-#define ROMSIZE 0x8000UL
-#define BANKSTART 0x4000UL
-#define BANKSIZE 0x4000UL
-
-unsigned char *cart[NBSEG];
-
-int nb_rom_banks;
-int nb_ram_banks;
-int current_rom_bank;
-int mbc_type;
-char cart_name[16] = "";
-
-patch* patches = NULL;
-
-VOID gb(int in)
-{
-  static int first = 1;
-  unsigned long pos, chk;
-  int i;
-  patch *p;
-
-  if(first) {
-    for(i = 0; i < NBSEG; i++) {
-      if((cart[i] = malloc(SEGSIZE)) == NULL) {
-       fprintf(stderr, "ERROR: can't allocate %dth segment of memory (%d bytes)\n", i, (int)SEGSIZE);
-       exit(EXIT_FAILURE);
-      }
-      memset(cart[i], FILLVALUE, SEGSIZE);
-    }
-    first = 0;
-  }
-  if(in) {
-    if(rtcnt > 2) {
-      if(hilo == 0)
-       pos = rtval[0] | (rtval[1]<<8);
-      else
-       pos = rtval[1] | (rtval[0]<<8);
-
-      /* Perform some validity checks */
-      if(pos >= ROMSIZE) {
-       fprintf(stderr, "ERROR: address overflow (addr %lx >= %lx)\n", pos, ROMSIZE);
-       exit(EXIT_FAILURE);
-      }
-      if(current_rom_bank >= nb_rom_banks) {
-       fprintf(stderr, "ERROR: bank overflow (addr %x > %x)\n", current_rom_bank, nb_rom_banks);
-       exit(EXIT_FAILURE);
-      }
-      if(current_rom_bank > 0 && pos < BANKSTART) {
-       fprintf(stderr, "ERROR: address underflow (addr %lx < %lx)\n", pos, BANKSTART);
-       exit(EXIT_FAILURE);
-      }
-      if(nb_rom_banks == 2 && current_rom_bank > 0) {
-       fprintf(stderr, "ERROR: only 1 32kB segment with 2 bank\n");
-       exit(EXIT_FAILURE);
-      }
-      if(current_rom_bank > 1)
-       pos += (current_rom_bank-1)*BANKSIZE;
-      for(i = 2; i < rtcnt; i++) {
-       if(rtflg[i]) {
-         if(pos < CARTSIZE) {
-           if(cart[pos/SEGSIZE][pos%SEGSIZE] != FILLVALUE)
-             fprintf(stderr, "WARNING: possibly wrote twice at addr %lx (%02X->%02X)\n", pos, rtval[i], cart[pos/SEGSIZE][pos%SEGSIZE]);
-           cart[pos/SEGSIZE][pos%SEGSIZE] = rtval[i];
-         } else {
-           fprintf(stderr, "ERROR: cartridge size overflow (addr %lx >= %lx)\n", pos, CARTSIZE);
-           exit(EXIT_FAILURE);
-         }
-         pos++;
-       }
-      }
-    }
-  } else {
-    /* EOF */
-    if(cart_name[0] == 0 && linkp->f_idp != NULL) {
-      for(i = strlen(linkp->f_idp);
-         i > 0 && (isalnum((unsigned char)linkp->f_idp[i-1]) || linkp->f_idp[i-1] == '.');
-         i--)
-       ;
-      for(pos = 0; pos < 16 && linkp->f_idp[i] != '.'; pos++, i++)
-       cart_name[pos] = toupper((unsigned char)linkp->f_idp[i]);
-      if(pos < 16)
-       cart_name[pos] = 0;
-    }
-    for(pos = 0x0134, i = 0;
-       pos < 0x0144 && cart_name[i];
-       pos++, i++)
-      cart[pos/SEGSIZE][pos%SEGSIZE] = cart_name[i];
-    for(; pos < 0x0144; pos++)
-      cart[pos/SEGSIZE][pos%SEGSIZE] = 0;
-    cart[0x147/SEGSIZE][0x147%SEGSIZE] = mbc_type;
-    switch(nb_rom_banks) {
-    case 2:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 0;
-      break;
-    case 4:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 1;
-      break;
-    case 8:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 2;
-      break;
-    case 16:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 3;
-      break;
-    case 32:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 4;
-      break;
-    case 64:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 5;
-      break;
-    case 128:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 6;
-      break;
-    case 256:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 7;
-      break;
-    case 512:
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 8;
-      break;
-    default:
-      fprintf(stderr, "WARNING: unsupported number of ROM banks (%d)\n", nb_rom_banks);
-      cart[0x148/SEGSIZE][0x148%SEGSIZE] = 0;
-      break;
-    }
-    switch(nb_ram_banks) {
-    case 0:
-      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 0;
-      break;
-    case 1:
-      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 2;
-      break;
-    case 4:
-      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 3;
-      break;
-    case 16:
-      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 4;
-      break;
-    default:
-      fprintf(stderr, "WARNING: unsupported number of RAM banks (%d)\n", nb_ram_banks);
-      cart[0x149/SEGSIZE][0x149%SEGSIZE] = 0;
-      break;
-    }
-
-    /* Patch before calculating the checksum */
-    if(patches)
-      for(p = patches; p; p = p->next)
-       cart[p->addr/SEGSIZE][p->addr%SEGSIZE] = p->value;
-
-    /* Update complement checksum */
-    chk = 0;
-    for(pos = 0x0134; pos < 0x014D; pos++)
-      chk += cart[pos/SEGSIZE][pos%SEGSIZE];
-    cart[0x014D/SEGSIZE][0x014D%SEGSIZE] = (unsigned char)(0xE7 - (chk&0xFF));
-    /* Update checksum */
-    chk = 0;
-    cart[0x014E/SEGSIZE][0x014E%SEGSIZE] = 0;
-    cart[0x014F/SEGSIZE][0x014F%SEGSIZE] = 0;
-    for(i = 0; i < NBSEG; i++)
-      for(pos = 0; pos < SEGSIZE; pos++)
-       chk += cart[i][pos];
-    cart[0x014E/SEGSIZE][0x014E%SEGSIZE] = (unsigned char)((chk>>8)&0xFF);
-    cart[0x014F/SEGSIZE][0x014F%SEGSIZE] = (unsigned char)(chk&0xFF);
-
-    for(i = 0; i < NBSEG; i++)
-      fwrite(cart[i], 1, SEGSIZE, ofp);
-  }
-}
-
-#endif /* GAMEBOY */
diff --git a/link/z80/lkgg.c b/link/z80/lkgg.c
deleted file mode 100644 (file)
index 3e8bb37..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* lkgg.c */
-
-/*
- * P. Felber
- */
-
-#ifdef GAMEGEAR
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <string.h>
-#include "aslink.h"
-
-#define CARTSIZE ((unsigned long)4*16UL*1024UL)
-#define NBSEG 8UL
-#define SEGSIZE (CARTSIZE/NBSEG)
-
-unsigned char *cart[NBSEG];
-
-#define ROMSIZE 0x10000UL
-#define BANKSIZE 0x4000UL
-
-int current_rom_bank;
-
-VOID gg(int in)
-{
-  static int first = 1;
-  unsigned long pos;
-  int i;
-
-  if(first) {
-    for(i = 0; i < NBSEG; i++) {
-      if((cart[i] = malloc(SEGSIZE)) == NULL) {
-       fprintf(stderr, "ERROR: can't allocate %dth segment of memory (%d bytes)\n", i, (int)SEGSIZE);
-       exit(EXIT_FAILURE);
-      }
-      memset(cart[i], 0, SEGSIZE);
-    }
-    first = 0;
-  }
-  if(in) {
-    if(rtcnt > 2) {
-      if(hilo == 0)
-       pos = rtval[0] | (rtval[1]<<8);
-      else
-       pos = rtval[1] | (rtval[0]<<8);
-
-      /* Perform some validity checks */
-      if(pos >= ROMSIZE) {
-       fprintf(stderr, "ERROR: address overflow (addr %lx >= %lx)\n", pos, ROMSIZE);
-       exit(EXIT_FAILURE);
-      }
-      if(current_rom_bank > 1)
-       pos += (current_rom_bank-1)*BANKSIZE;
-      for(i = 2; i < rtcnt; i++) {
-       if(rtflg[i]) {
-         if(pos < CARTSIZE) {
-           if(cart[pos/SEGSIZE][pos%SEGSIZE] != 0)
-             fprintf(stderr, "WARNING: wrote twice at addr %lx (%02X->%02X)\n", pos, rtval[i], cart[pos/SEGSIZE][pos%SEGSIZE]);
-           cart[pos/SEGSIZE][pos%SEGSIZE] = rtval[i];
-         } else {
-           fprintf(stderr, "ERROR: cartridge size overflow (addr %lx >= %lx)\n", pos, CARTSIZE);
-           exit(EXIT_FAILURE);
-         }
-         pos++;
-       }
-      }
-    }
-  } else {
-    /* EOF */
-    /* Patch before calculating the checksum */
-    for(i = 0; i < NBSEG; i++)
-      fwrite(cart[i], 1, SEGSIZE, ofp);
-  }
-}
-
-#endif /* GAMEGEAR */
diff --git a/link/z80/lkhead.c b/link/z80/lkhead.c
deleted file mode 100644 (file)
index 3eb127d..0000000
+++ /dev/null
@@ -1,154 +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 <alloc.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|A_OVR;
-}
-
-/*)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/link/z80/lkihx.c b/link/z80/lkihx.c
deleted file mode 100644 (file)
index 082a5fc..0000000
+++ /dev/null
@@ -1,134 +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 <alloc.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 function:
- *             VOID    ihx(i)
- *
- *     lkihx.c contains no local variables.
- */
-
-/*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.  
- */
-
-/*)Function    ihx(i)
- *
- *             int     i               0 - process data
- *                                     1 - end of data
- *
- *     The function ihx() outputs the relocated data
- *     in the standard Intel Hex 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
-ihx(i)
-{
-       register Addr_T chksum;
-
-       if (i) {
-               if (hilo == 0) {
-                       chksum = rtval[0];
-                       rtval[0] = rtval[1];
-                       rtval[1] = chksum;
-               }
-               for (i = 0, chksum = -2; i < rtcnt; i++) {
-                       if (rtflg[i])
-                               chksum++;
-               }
-               fprintf(ofp, ":%02X", chksum);
-               for (i = 0; i < rtcnt ; i++) {
-                       if (rtflg[i]) {
-                               fprintf(ofp, "%02X", rtval[i]);
-                               chksum += rtval[i];
-                       }
-                       if (i == 1) {
-                               fprintf(ofp, "00");
-                       }
-               }
-               fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
-       } else {
-               fprintf(ofp, ":00000001FF\n");
-       }
-}
diff --git a/link/z80/lklex.c b/link/z80/lklex.c
deleted file mode 100644 (file)
index 1ccdeea..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-/* lklex.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-/*
- * Extensions: P. Felber, M. Hope
- */
-
-#include <stdio.h>
-#include <string.h>
-//#include <alloc.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()
- *             int     lk_getline()
- *             int     getmap()
- *             char    getnb()
- *             int     more()
- *             VOID    skip()
- *             VOID    unget()
- *
- *     lklex.c contains no local variables.
- */
-
-/*)Function    VOID    getid(id,c)
- *
- *             char *  id              a pointer to a string of
- *                                     maximum length NCPS
- *             int     c               mode flag
- *                                     >=0     this is first character to
- *                                             copy to the string buffer
- *                                     <0      skip white space
- *
- *     The function getid() scans the current input text line
- *     from the current position copying the next LETTER | DIGIT string
- *     into the external string buffer (id).  The string ends when a non
- *     LETTER or DIGIT character is found. The maximum number of
- *     characters copied is NCPS.  If the input string is larger than
- *     NCPS characters then the string is truncated, if the input string
- *     is shorter than NCPS characters then the string is NULL filled.
- *     If the mode argument (c) is >=0 then (c) is the first character
- *     copied to the string buffer, if (c) is <0 then intervening white
- *     space (SPACES and TABS) are skipped.
- *
- *     local variables:
- *             char *  p               pointer to external string buffer
- *             int     c               current character value
- *
- *     global variables:
- *             char    ctype[]         a character array which defines the
- *                                     type of character being processed.
- *                                     This index is the character
- *                                     being processed.
- *
- *     called functions:
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             use of getnb(), get(), and unget() updates the
- *             global pointer ip the position in the current
- *             input text line.
- */
-
-VOID
-getid(id, c)
-register int c;
-char *id;
-{
-       register char *p;
-
-       if (c < 0) {
-               c = getnb();
-       }
-       p = id;
-       do {
-               if (p < &id[NCPS])
-                       *p++ = c;
-       } while (ctype[c=get()] & (LETTER|DIGIT));
-       unget(c);
-       while (p < &id[NCPS])
-               *p++ = 0;
-}
-
-/*)Function    VOID    getfid(fid,c)
- *
- *             char *  str             a pointer to a string of
- *                                     maximum length FILSPC
- *             int     c               this is first character to
- *                                     copy to the string buffer
- *
- *     The function getfid() scans the current input text line
- *     from the current position copying the next string
- *     into the external string buffer (str).  The string ends when a
- *     non SPACE type character is found. The maximum number of
- *     characters copied is FILSPC. If the input string is larger than
- *     FILSPC characters then the string is truncated, if the input string
- *     is shorter than FILSPC characters then the string is NULL filled.
- *
- *     local variables:
- *             char *  p               pointer to external string buffer
- *             int     c               current character value
- *
- *     global variables:
- *             char    ctype[]         a character array which defines the
- *                                     type of character being processed.
- *                                     This index is the character
- *                                     being processed.
- *
- *     called functions:
- *             char    get()           lklex.c
- *
- *     side effects:
- *             use of get() updates the global pointer ip
- *             the position in the current input text line.
- */
-
-VOID
-getfid(str, c)
-register int c;
-char *str;
-{
-       register char *p;
-
-       p = str;
-       do {
-               if (p < &str[FILSPC-1])
-                       *p++ = c;
-               c = get();
-               if (c == ';')
-                       while (c)
-                               c = get();
-#ifdef SDK
-       } while (c);
-#else /* SDK */
-       } while (c && (ctype[c] != SPACE));
-#endif /* SDK */
-       while (p < &str[FILSPC])
-               *p++ = 0;
-}
-
-/*)Function    char    getnb()
- *
- *     The function getnb() scans the current input text
- *     line returning the first character not a SPACE or TAB.
- *
- *     local variables:
- *             int     c               current character from input
- *
- *     global variables:
- *             none
- *
- *     called functions:
- *             char    get()           lklex.c
- *
- *     side effects:
- *             use of get() updates the global pointer ip, the position
- *             in the current input text line
- */
-
-char
-getnb()
-{
-       register int c;
-
-       while ((c=get())==' ' || c=='\t')
-               ;
-       return (c);
-}
-
-/*)Function    VOID    skip()
- *
- *     The function skip() scans the input text skipping all
- *     letters and digits.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             
- *     functions called:
- *             char    get()           lklex.c
- *             char    getnb()         lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             Input letters and digits are skipped.
- */
-
-VOID
-skip(c)
-register int c;
-{
-       if (c < 0)
-               c = getnb();
-       while (ctype[c=get()] & (LETTER|DIGIT)) { ; }
-       unget(c);
-}
-
-/*)Function    char    get()
- *
- *     The function get() returns the next character in the
- *     input text line, at the end of the line a
- *     NULL character is returned.
- *
- *     local variables:
- *             int     c               current character from
- *                                     input text line
- *
- *     global variables:
- *             char *  ip              pointer into the current
- *                                     input text line
- *
- *     called functions:
- *             none
- *
- *     side effects:
- *             updates ip to the next character position in the
- *             input text line.  If ip is at the end of the
- *             line, ip is not updated.
- */
-
-char
-get()
-{
-       register int c;
-
-       if ((c = *ip) != 0)
-               ++ip;
-       return (c);
-}
-
-/*)Function    VOID    unget(c)
- *
- *             int     c               value of last character
- *                                     read from input text line
- *
- *     If (c) is not a NULL character then the global pointer ip
- *     is updated to point to the preceeding character in the
- *     input text line.
- *
- *     NOTE:   This function does not push the character (c)
- *             back into the input text line, only
- *             the pointer ip is changed.
- *
- *     local variables:
- *             int     c               last character read
- *                                     from input text line
- *
- *     global variables:
- *             char *  ip              position into the current
- *                                     input text line
- *
- *     called functions:
- *             none
- *
- *     side effects:
- *             ip decremented by 1 character position
- */
-
-VOID
-unget(c)
-{
-       if (c != 0)
-               --ip;
-}
-
-/*)Function    int     getmap(d)
- *
- *             int     d               value to compare with the
- *                                     input text line character
- *
- *     The function getmap() converts the 'C' style characters \b, \f,
- *     \n, \r, and \t to their equivalent ascii values and also
- *     converts 'C' style octal constants '\123' to their equivalent
- *     numeric values.  If the first character is equivalent to (d) then
- *     a (-1) is returned, if the end of the line is detected then
- *     a 'q' error terminates the parse for this line, or if the first
- *     character is not a \ then the character value is returned.
- *
- *     local variables:
- *             int     c               value of character
- *                                     from input text line
- *             int     n               looping counter
- *             int     v               current value of numeric conversion
- *
- *     global variables:
- *             none
- *
- *     called functions:
- *             char    get()           lklex.c
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             use of get() updates the global pointer ip the position
- *             in the current input text line
- */
-
-int
-getmap(d)
-{
-       register int c, n, v;
-
-       if ((c = get()) == '\0')
-               return (-1);
-       if (c == d)
-               return (-1);
-       if (c == '\\') {
-               c = get();
-               switch (c) {
-
-               case 'b':
-                       c = '\b';
-                       break;
-
-               case 'f':
-                       c = '\f';
-                       break;
-
-               case 'n':
-                       c = '\n';
-                       break;
-
-               case 'r':
-                       c = '\r';
-                       break;
-
-               case 't':
-                       c = '\t';
-                       break;
-
-               case '0':
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-                       n = 0;
-                       v = 0;
-                       while (++n<=3 && c>='0' && c<='7') {
-                               v = (v<<3) + c - '0';
-                               c = get();
-                       }
-                       unget(c);
-                       c = v;
-                       break;
-               }
-       }
-       return (c);
-}
-
-/*)Function    int     lk_getline()
- *
- *     The function lk_getline() reads a line of input text from a
- *     .rel source text file, a .lnk command file or from stdin.
- *     Lines of text are processed from a single .lnk file or
- *     multiple .rel files until all files have been read.
- *     The input text line is copied into the global string ib[]
- *     and converted to a NULL terminated string.  The function
- *     lk_getline() returns a (1) after succesfully reading a line
- *     or a (0) if all files have been read.
- *     This function also opens each input .lst file and output
- *     .rst file as each .rel file is processed.
- *
- *     local variables:
- *             int     i               string length
- *             int     ftype           file type
- *             char *  fid             file name
- *
- *     global variables:
- *             lfile   *cfp            The pointer *cfp points to the
- *                                     current lfile structure
- *             lfile   *filep          The pointer *filep points to the
- *                                     beginning of a linked list of
- *                                     lfile structures.
- *             int     gline           get a line from the LST file
- *                                     to translate for the RST file
- *             char    ib[NINPUT]      REL file text line
- *             int     pass            linker pass number
- *             int     pflag           print linker command file flag
- *             FILE    *rfp            The file handle to the current
- *                                     output RST file
- *             FILE    *sfp            The file handle sfp points to the
- *                                     currently open file
- *             FILE *  stdin           c_library
- *             FILE *  stdout          c_library
- *             FILE    *tfp            The file handle to the current
- *                                     LST file being scanned
- *             int     uflag           update listing flag
- *
- *     called functions:
- *             FILE *  afile()         lkmain.c
- *             int     fclose()        c_library
- *             char *  fgets()         c_library
- *             int     fprintf()       c_library
- *             VOID    lkulist()       lklist.c
- *             VOID    lkexit()        lkmain.c
- *             int     strlen()        c_library
- *
- *     side effects:
- *             The input stream is scanned.  The .rel files will be
- *             opened and closed sequentially scanning each in turn.
- */
-
-int
-lk_getline()
-{
-       register int i, ftype;
-       register char *fid;
-
-loop:  if (pflag && cfp && cfp->f_type == F_STD)
-               fprintf(stdout, "ASlink >> ");
-
-#ifdef SDK
-       if(cfp == NULL && filep != NULL && filep->f_type == F_CMD) {
-               char **argv = (char **)filep->f_idp;
-               if(argv[0] != NULL && strlen(argv[0]) < sizeof ib) {
-                       strcpy(ib, argv[0]);
-                       filep->f_idp = (char *)&argv[1];                        
-               } else {
-                       filep = NULL;
-                       return(0);
-               }
-       } else
-#endif /* SDK */
-       if (sfp == NULL || fgets(ib, sizeof ib, sfp) == NULL) {
-               if (sfp) {
-                       fclose(sfp);
-#ifdef SDK
-                       sfp = NULL;
-#endif /* SDK */
-                       lkulist(0);
-               }
-               if (cfp == NULL) {
-                       cfp = filep;
-               } else {
-                       cfp = cfp->f_flp;
-               }
-               if (cfp) {
-                       ftype = cfp->f_type;
-                       fid = cfp->f_idp;
-                       if (ftype == F_STD) {
-                               sfp = stdin;
-                       } else
-                       if (ftype == F_LNK) {
-#ifdef SDK
-                               sfp = afile(fid, "lnk", 0);
-#else /* SDK */
-                               sfp = afile(fid, "LNK", 0);
-#endif /* SDK */
-                       } else
-                       if (ftype == F_REL) {
-#ifdef SDK
-                               sfp = afile(fid, "", 0);
-                               if (uflag && pass != 0) {
-                                if ((tfp = afile(fid, "lst", 0)) != NULL) {
-                                 if ((rfp = afile(fid, "rst", 1)) == NULL) {
-#else /* SDK */
-                               sfp = afile(fid, "REL", 0);
-                               if (uflag && pass != 0) {
-                                if ((tfp = afile(fid, "LST", 0)) != NULL) {
-                                 if ((rfp = afile(fid, "RST", 1)) == NULL) {
-#endif /* SDK */
-                                       fclose(tfp);
-                                       tfp = NULL;
-                                 }
-                                }
-                               }
-                               gline = 1;
-                       } else {
-                               fprintf(stderr, "Invalid file type\n");
-                               lkexit(1);
-                       }
-                       if (sfp == NULL) {
-                               lkexit(1);
-                       }
-                       goto loop;
-               } else {
-                       filep = NULL;
-                       return(0);
-               }
-       }
-       i = strlen(ib) - 1;
-       if (ib[i] == '\n')
-               ib[i] = 0;
-       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/link/z80/lklibr.c b/link/z80/lklibr.c
deleted file mode 100644 (file)
index c3761bb..0000000
+++ /dev/null
@@ -1,1297 +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
- *
- */
-
-/*
- * Extensions: P. Felber
- */
-
-#define EQ(A,B) !strcmp((A),(B))
-#define MAXLINE 254 /*when using fgets*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "aslink.h"
-
-#ifdef OTHERSYSTEM
-#ifdef SDK
-#ifdef UNIX
-    #define LKDIRSEP '/'
-    #define LKDIRSEPSTR "/"
-#else /* UNIX */
-       #define LKDIRSEP '\\'
-       #define LKDIRSEPSTR "\\"
-#endif /* UNIX */
-#else /* SDK */
-       #define LKDIRSEP '\\'
-       #define LKDIRSEPSTR "\\"
-#endif /* SDK */
-#endif
-
-#ifdef SDK
-    #define LKOBJEXT "o"
-#else /* SDK */
-    #define LKOBJEXT "rel"
-#endif /* SDK */
-
-/*)Module      lklibr.c
- *
- *     The module lklibr.c contains the functions which
- *     (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, "\n?ASlink-Warning-Couldn't find library '%s'", 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;
-    int libfilinc=0;
-
-       if (path != NULL)
-    {
-               str = (char *) new (strlen(path) + strlen(libfil) + 6);
-               strcpy(str, path);
-
-        if (str[strlen(str)-1] != LKDIRSEP)
-        {
-                       strcat(str, LKDIRSEPSTR);
-               }
-       }
-    else
-    {
-               str = (char *) new (strlen(libfil) + 5);
-       }
-
-       if (libfil[0] == LKDIRSEP)
-    {
-        libfil++;
-        libfilinc=1;
-    }
-       
-    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*/
-        if(libfilinc) libfil--;
-        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 '.o' files associated with
-        the library.  So, get 'path' from 'str' and then chop it off and recreate 'libfil'.
-        That way putting 'path' and 'libfil' together will result into the original filepath
-        as contained in 'str'.*/
-        int j;
-        path = (char *) new (strlen(str));
-        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();
-                       break;
-               }
-       }
-}
-
-/*)Function    VOID    fndsym(name)
- *
- *             char    *name           symbol name to find
- *
- *     The function fndsym() searches through all combinations of the
- *     library path specifications (input by the -k option) and the
- *     library file specifications (input by the -l option) that
- *     lead to an existing file.
- *
- *     The file specicifation may be formed in one of two ways:
- *
- *     (1)     If the library file contained an absolute
- *             path/file specification then this becomes filspc.
- *             (i.e. C:\...)
- *
- *     (2)     If the library file contains a relative path/file
- *             specification then the concatenation of the path
- *             and this file specification becomes filspc.
- *             (i.e. \...)
- *
- *     The structure lbfile is created for the first library
- *     object file which contains the definition for the
- *     specified undefined symbol.
- *
- *     If the library file [.LIB] contains file specifications for
- *     non existant files, no errors are returned.
- *
- *     local variables:
- *             char    buf[]           [.REL] file input line
- *             char    c               [.REL] file input character
- *             FILE    *fp             file handle for object file
- *             lbfile  *lbf            temporary pointer
- *             lbfile  *lbfh           pointer to lbfile structure
- *             FILE    *libfp          file handle for library file
- *             lbname  *lbnh           pointer to lbname structure
- *             char    *path           file specification path
- *             char    relfil[]        [.REL] file specification
- *             char    *str            combined path and file specification
- *             char    symname[]       [.REL] file symbol string
- *
- *     global variables:
- *             lbname  *lbnhead        The pointer to the first
- *                                     name structure
- *             lbfile  *lbfhead        The pointer to the first
- *                                     file structure
- *
- *      functions called:
- *             int     fclose()        c_library
- *             int     fgets()         c_library
- *             FILE    *fopen()        c_library
- *             VOID    free()          c_library
- *             char    getnb()         lklex.c
- *             VOID    lkexit()        lkmain.c
- *             VOID    loadfile()      lklibr.c
- *             VOID *  new()           lksym.c
- *             char *  sprintf()       c_library
- *             int     sscanf()        c_library
- *             char *  strcat()        c_library
- *             char *  strchr()        c_library
- *             char *  strcpy()        c_library
- *             int     strlen()        c_library
- *             int     strncmp()       c_library
- *             VOID    unget()         lklex.c
- *
- *     side effects:
- *             If the symbol is found then a new lbfile structure
- *             is created and added to the linked list of lbfile
- *             structures.  The file containing the found symbol
- *             is linked.
- */
-
-#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)
-        {
-            //printf("ThisSym->name=%s\n", ThisSym->name);
-                       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*/
-                                           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%c%s", DirLib, ModName, FSEPX, LKOBJEXT);
-                    This->filename=(char *)new(strlen(buff)+1);
-                    strcpy(This->filename, buff);
-
-                    This->symbols=ThisSym=NULL; /*Start a new linked list of symbols*/
-                               }
-                else if(EQ(FLine, "</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;
-
-       /* Iterate through all library files */
-    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 (str[strlen(str)-1] != LKDIRSEP)
-                {
-                                       strcat(str, LKDIRSEPSTR);
-                }
-#endif
-                       }
-            else
-            {
-                strcpy(str, "");
-                       }
-
-            if(strcmp(relfil, "<SDCCLIB>")==0)
-                       {
-                /*Get the built in index of a library*/
-                               This=buildlibraryindex_SdccLib(lbnh->libspc, libfp, str, This);
-                               break; /*get the index for next library*/
-                       }
-            
-            /*From here down, build the index for the original library format*/
-
-            if (relfil[0] == LKDIRSEP)
-            {
-                               strcat(str, relfil+1);
-                       }
-            else
-            {
-                               strcat(str, relfil);
-                       }
-                               
-            if(strchr(relfil, FSEPX) == NULL)
-            {
-                               sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT);
-                       }
-
-            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; /*There should be a 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);
-
-                               ThisSym = This->symbols = NULL;
-
-                               /*
-                                * Read in the object file.  Look for lines that
-                                * begin with "S" and end with "D".  These are
-                                * symbol table definitions.  If we find one, see
-                                * if it is our symbol.  Make sure we only read in
-                                * our object file and don't go into the next one.
-                                */
-                       
-                               while (fgets(buf, NINPUT, fp) != NULL)
-                {
-                                       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 */
-               } /* 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 */
-
-
-/*Check for a symbol in a SDCC library.  If found, add the embedded .rel.
-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)], "%c%s", FSEPX, LKOBJEXT);
-
-                                               /*If this module has been loaded already don't load it again.*/
-                                               lbf = lbfhead;
-                                               while (lbf)
-                                               {
-                                                       if(EQ(DirLib, lbf->filspc)) return 1;/*Already loaded*/
-                                                       lbf=lbf->next;
-                                               }
-                                               
-                                               /*Add the embedded file to the list of files to be loaded in
-                                               the second pass.  That is performed latter by the function
-                                               library() below.*/
-                                               lbfh = (struct lbfile *) new (sizeof(struct lbfile));
-                                               if (lbfhead == NULL)
-                                               {
-                                                       lbfhead = lbfh;
-                                               }
-                                               else
-                                               {
-                                                       lbf = lbfhead;
-                                                       while (lbf->next)
-                                                       lbf = lbf->next;
-                                                       lbf->next = lbfh;
-                                               }
-
-                                               lbfh->libspc = PathLib;
-                                               lbfh->filspc = DirLib;
-                                               lbfh->relfil = (char *) new (strlen(ModName) + 1);
-                                               strcpy(lbfh->relfil, ModName);
-                                               /*Library embedded file, so lbfh->offset must be >=0*/
-                                               lbfh->offset = IndexOffset+FileOffset;
-                                               
-                                               /*Jump to where the .rel begins and load it.*/
-                                               fseek(libfp, lbfh->offset, SEEK_SET);
-                                               LoadRel(PathLib, libfp, ModName);
-
-                                               return 1; /*Found the symbol, so success!*/
-                                       }
-                               }
-            break;
-                       
-                       default:
-                               return 0; /*It should never reach this point, but just in case...*/
-                       break;
-        }
-    }
-
-       return 0; /*The symbol is not in this library*/
-}
-
-int
-fndsym(name)
-char *name;
-{
-       FILE *libfp, *fp;
-       struct lbname *lbnh;
-       struct lbfile *lbfh, *lbf;
-       char relfil[NINPUT+2];
-       char buf[NINPUT+2];
-       char symname[NINPUT];
-       char *path,*str;
-       char c;
-       int result;
-
-       /*
-        * Search through every library in the linked list "lbnhead".
-        */
-
-/*1*/  for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) {
-               if ((libfp = fopen(lbnh->libspc, "r")) == NULL) {
-                       fprintf(stderr, "Cannot open library file %s\n",
-                               lbnh->libspc);
-                       lkexit(1);
-               }
-               path = lbnh->path;
-
-               /*
-                * Read in a line from the library file.
-                * This is the relative file specification
-                * for a .REL file in this library.
-                */
-
-/*2*/          while (fgets(relfil, NINPUT, libfp) != NULL) {
-                   relfil[NINPUT+1] = '\0';
-                   chop_crlf(relfil);
-                   if (path != NULL) {
-                       str = (char *) new (strlen(path)+strlen(relfil)+6);
-                       strcpy(str,path);
-#ifdef OTHERSYSTEM
-#ifdef SDK
-#ifdef UNIX
-                       if (str[strlen(str)-1] != '/') {
-                               strcat(str,"/");
-#else /* UNIX */
-                       if (str[strlen(str)-1] != '\\') {
-                               strcat(str,"\\");
-#endif /* UNIX */
-#else /* SDK */
-                       if (str[strlen(str)-1] != '\\') {
-                               strcat(str,"\\");
-#endif /* SDK */
-                       }
-#endif
-                   } else {
-                       str = (char *) new (strlen(relfil) + 5);
-                   }
-
-            /*See if this is a library with embedded files*/
-                       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*/
-#ifdef SDK
-#ifdef UNIX
-                   if (relfil[0] == '/') {
-#else /* UNIX */
-                   if (relfil[0] == '\\') {
-#endif /* UNIX */
-#else /* SDK */
-                   if (relfil[0] == '\\') {
-#endif /* SDK */
-                       strcat(str,relfil+1);
-                   } else {
-                       strcat(str,relfil);
-                   }
-                   if(strchr(relfil, FSEPX) == NULL)
-            {
-                sprintf(&str[strlen(str)], "%c%s", FSEPX, LKOBJEXT);
-                   }
-
-/*3*/              if ((fp = fopen(str, "r")) != NULL) {
-
-                       /*
-                        * Read in the object file.  Look for lines that
-                        * begin with "S" and end with "D".  These are
-                        * symbol table definitions.  If we find one, see
-                        * if it is our symbol.  Make sure we only read in
-                        * our object file and don't go into the next one.
-                        */
-                       
-/*4*/                  while (fgets(buf, NINPUT, fp) != NULL) {
-
-                       buf[NINPUT+1] = '\0';
-                       buf[strlen(buf) - 1] = '\0';
-
-                       /*
-                        * Skip everything that's not a symbol record.
-                        */
-                       if (buf[0] != 'S')
-                               continue;
-
-                       /*
-                        * When a 'T line' is found terminate file scan.
-                        * All 'S line's preceed 'T line's in .REL files.
-                        */
-                       if (buf[0] == 'T')
-                               break;
-
-                       sscanf(buf, "S %s %c", symname, &c);
-
-                       /*
-                        * If we find a symbol definition for the
-                        * symbol we're looking for, load in the
-                        * file and add it to lbfhead so it gets
-                        * loaded on pass number 2.
-                        */
-/*5*/                  if (strncmp(symname, name, NCPS) == 0 && c == 'D') {
-
-                       lbfh = (struct lbfile *) new (sizeof(struct lbfile));
-                       if (lbfhead == NULL) {
-                               lbfhead = lbfh;
-                       } else {
-                               lbf = lbfhead;
-                               while (lbf->next)
-                                       lbf = lbf->next;
-                               lbf->next = lbfh;
-                       }
-                       lbfh->libspc = lbnh->libspc;
-                       lbfh->filspc = str;
-                       lbfh->relfil = (char *) new (strlen(relfil) + 1);
-                       lbfh->offset = -1; /*Stand alone rel file*/
-                       strcpy(lbfh->relfil,relfil);
-                       fclose(fp);
-                       fclose(libfp);
-                       loadfile(str);
-                       return (1);
-
-/*5*/                  }
-
-/*4*/                  }
-                   fclose(fp);
-/*3*/              }
-
-                   free(str);
-/*2*/          }
-               fclose(libfp);
-/*1*/  }
-       return(0);
-}
-#endif /* INDEXLIB */
-
-void loadfile_SdccLib(char * libspc, char * module, long offset)
-{
-       FILE *fp;
-
-#ifdef __CYGWIN__
-    char posix_path[PATH_MAX];
-    void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
-    cygwin_conv_to_full_posix_path(libspc, posix_path);
-    fp = fopen(posix_path, "r");
-#else
-    fp = fopen(libspc,"r");
-#endif
-
-       if (fp != NULL)
-       {
-               fseek(fp, offset, SEEK_SET);
-               LoadRel(libspc, fp, module);
-               fclose(fp);
-       }
-    else
-    {
-               fprintf(stderr, "?Aslink-Error-Opening library '%s'\n", libspc);
-               lkexit(1);
-    }
-}
-
-/*)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()          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];
-       int i;
-
-#ifdef __CYGWIN__
-    char posix_path[PATH_MAX];
-    void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
-    cygwin_conv_to_full_posix_path(filspc, posix_path);
-    fp = fopen(posix_path, "r");
-#else
-    fp = fopen(filspc,"r");
-#endif
-
-       if (fp != NULL)
-    {
-               while (fgets(str, NINPUT, fp) != NULL)
-        {
-                       str[NINPUT+1] = '\0';
-                       i = strlen(str) - 1;
-                       if (str[i] == '\n')
-                               str[i] = '\0';
-                       ip = str;
-                       link();
-               }
-               fclose(fp);
-       }
-    else
-    {
-               fprintf(stderr, "?Aslink-Error-Opening library '%s'\n", filspc);
-               lkexit(1);
-    }
-}
diff --git a/link/z80/lklist.c b/link/z80/lklist.c
deleted file mode 100644 (file)
index 827b44c..0000000
+++ /dev/null
@@ -1,1270 +0,0 @@
-/* lklist.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "aslink.h"
-
-/*)Module      lklist.c
- *
- *     The module lklist.c contains the functions which
- *     output the linker .map file and produce a relocated
- *     listing .rst file.
- *
- *     lklist.c contains the following functions:
- *             int     dgt()
- *             VOID    lstarea()
- *             VOID    lkulist()
- *             VOID    lkalist()
- *             VOID    lkglist()
- *             VOID    newpag()
- *             VOID    slew()
- *
- *     lklist.c contains no local variables.
- */
-
-/*)Function    VOID    slew(fp)
- *
- *             FILE *  fp              output file handle
- *
- *     The function slew() increments the page line counter.
- *     If the number of lines exceeds the maximum number of
- *     lines per page then a page skip and a page header are
- *     output.
- *
- *     local variables:
- *             int     i               loop counter
- *
- *     global variables:
- *             int     lop             current line number on page
- *             int     xflag           Map file radix type flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    newpag()        lklist.c
- *
- *     side effects:
- *             The page line and the page count may be updated.
- */
-
-VOID
-slew(fp)
-FILE *fp;
-{
-       register int i;
-
-       if (lop++ >= NLPP) {
-               newpag(fp);
-               if (xflag == 0) {
-                       fprintf(fp, "Hexidecimal\n\n");
-               } else
-               if (xflag == 1) {
-                       fprintf(fp, "Octal\n\n");
-               } else
-               if (xflag == 2) {
-                       fprintf(fp, "Decimal\n\n");
-               }
-               fprintf(fp, "Area       Addr   Size");
-               fprintf(fp, "   Decimal Bytes (Attributes)\n");
-               for(i=0;i<4;++i)
-                       fprintf(fp, "      Value--Global");
-               fprintf(fp, "\n\n");
-               lop += 6;
-       }
-}
-
-/*)Function    VOID    newpag()
- *
- *     The function newpag() outputs a page skip, writes the
- *     first page header line, sets the line count to 1, and
- *     increments the page counter.
- *
- *     local variables:
- *             none
- *
- *     global variables:
- *             int     lop             current line number on page
- *             int     page            current page number
- *
- *     functions called:
- *             int     fprintf()       c_library
- *
- *     side effects:
- *             The page and line counters are updated.
- */
-
-VOID
-newpag(fp)
-FILE *fp;
-{
-       fprintf(fp, "\fASxxxx Linker %s,  page %u.\n", VERSION, ++page);
-       lop = 1;
-}
-
-#if    NCPS-8
-
-/* NCPS != 8 */
-/*)Function    VOID    lstarea(xp)
- *
- *             area *  xp              pointer to an area structure
- *
- *     The function lstarea() creates the linker map output for
- *     the area specified by pointer xp.  The generated output
- *     area header includes the area name, starting address,
- *     size of area, number of words (in decimal), and the
- *     area attributes.  The symbols defined in this area are
- *     sorted by ascending address and output one per line
- *     in the selected radix.
- *
- *     local variables:
- *             areax * oxp             pointer to an area extension structure
- *             int     c               character value
- *             int     i               loop counter
- *             int     j               bubble sort update status
- *             char *  ptr             pointer to an id string
- *             int     nmsym           number of symbols in area
- *             Addr_T  a0              temporary
- *             Addr_T  ai              temporary
- *             Addr_T  aj              temporary
- *             sym *   sp              pointer to a symbol structure
- *             sym **  p               pointer to an array of
- *                                     pointers to symbol structures
- *
- *     global variables:
- *             FILE    *mfp            Map output file handle
- *             sym *symhash[NHASH]     array of pointers to NHASH
- *                                     linked symbol lists
- *             int     xflag           Map file radix type flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    free()          c_library
- *             char *  malloc()        c_library
- *             char    putc()          c_library
- *             VOID    slew()          lklist.c
- *
- *     side effects:
- *             Map output generated.
- */
-
-#ifndef MLH_MAP
-VOID
-lstarea(xp)
-struct area *xp;
-{
-//     register struct area *op;
-       register struct areax *oxp;
-       register c, i, j;
-       register char *ptr;
-       int nmsym;
-       Addr_T a0, ai, aj;
-       struct sym *sp;
-       struct sym **p;
-
-       putc('\n', mfp);
-       if (xflag == 0) {
-               fprintf(mfp, "Hexidecimal\n\n");
-       } else
-       if (xflag == 1) {
-               fprintf(mfp, "Octal\n\n");
-       } else
-       if (xflag == 2) {
-               fprintf(mfp, "Decimal\n\n");
-       }
-       fprintf(mfp, "Area                               ");
-       fprintf(mfp, "Addr   Size   Decimal Bytes (Attributes)\n");
-       fprintf(mfp, "--------------------------------   ");
-       fprintf(mfp, "----   ----   ------- ----- ------------\n");
-       /*
-        * Output Area Header
-        */
-       ptr = &xp->a_id[0];
-       while (ptr < &xp->a_id[NCPS]) {
-               if ((c = *ptr++) != 0) {
-                       putc(c, mfp);
-               } else {
-                       putc(' ', mfp);
-               }
-       }
-       ai = xp->a_addr;
-       aj = xp->a_size;
-       if (xflag == 0) {
-               fprintf(mfp, "   %04X   %04X", ai, aj);
-       } else
-       if (xflag == 1) {
-               fprintf(mfp, " %06o %06o", ai, aj);
-       } else
-       if (xflag == 2) {
-               fprintf(mfp, "  %05u  %05u", ai, aj);
-       }
-       fprintf(mfp, " = %6u. bytes ", aj);
-       if (xp->a_flag & A_ABS) {
-               fprintf(mfp, "(ABS");
-       } else {
-               fprintf(mfp, "(REL");
-       }
-       if (xp->a_flag & A_OVR) {
-               fprintf(mfp, ",OVR");
-       } else {
-               fprintf(mfp, ",CON");
-       }
-       if (xp->a_flag & A_PAG) {
-               fprintf(mfp, ",PAG");
-       }
-       fprintf(mfp, ")");
-       if (xp->a_flag & A_PAG) {
-               ai = (ai & 0xFF);
-               aj = (aj > 256);
-               if (ai || aj) { fprintf(mfp, "  "); }
-               if (ai)      { fprintf(mfp, " Boundary"); }
-               if (ai & aj)  { fprintf(mfp, " /"); }
-               if (aj)      { fprintf(mfp, " Length"); }
-               if (ai || aj) { fprintf(mfp, " Error"); }
-       }
-
-       /*
-        * 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;
-       }
-
-       /*
-        * 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;
-               }
-       }
-
-       /*
-        * Symbol Table Output
-        */
-       i = 0;
-       fprintf(mfp, "\n\n");
-       fprintf(mfp, "      Value  Global\n");
-       fprintf(mfp, "      -----  --------------------------------");
-       while (i < nmsym) {
-               fprintf(mfp, "\n");
-               fprintf(mfp, "     ");
-
-               sp = p[i];
-               aj = sp->s_addr + sp->s_axp->a_addr;
-               if (xflag == 0) {
-                       fprintf(mfp, "  %04X  ", aj);
-               } else
-               if (xflag == 1) {
-                       fprintf(mfp, "%06o  ", aj);
-               } else
-               if (xflag == 2) {
-                       fprintf(mfp, " %05u  ", aj);
-               }
-               ptr = &sp->s_id[0];
-               while (ptr < &sp->s_id[NCPS]) {
-                       if ((c = *ptr++) != 0) {
-                               putc(c, mfp);
-                       } else {
-                               putc(' ', mfp);
-                       }
-               }
-               i++;
-       }
-       putc('\n', mfp);
-       free(p);
-}
-#else
-VOID lstarea(struct area *xp)
-{
-       register struct areax *oxp;
-       register int i, j;
-       int nmsym;
-       Addr_T a0, ai = 0, aj = 0;
-       struct sym *sp;
-       struct sym **p;
-
-       /*
-        * Find number of symbols in area
-        */
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp)
-                                       ++nmsym;
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-
-       /*
-        * Symbol Table Output
-        */
-       if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) {
-               fprintf(mfp, "AREA %s\n", xp->a_id );
-               switch (xflag) {
-                       case 1:
-                               fprintf(mfp, "\tRADIX OCTAL\n" );
-                               break;
-                       case 2:
-                               fprintf(mfp, "\tRADIX DEC\n" );
-                               break;
-                       default:
-                               fprintf(mfp, "\tRADIX HEX\n" );
-                               break;
-               }
-               fprintf( mfp,   "\tBASE %04X\n"
-                               "\tSIZE %04X\n"
-                               "\tATTRIB "
-                       , xp->a_addr, xp->a_size );
-               if (xp->a_flag & A_ABS) {
-                       fprintf(mfp, "ABS");
-               } else {
-                       fprintf(mfp, "REL");
-               }
-               if (xp->a_flag & A_OVR) {
-                       fprintf(mfp, " OVR");
-               } else {
-                       fprintf(mfp, " CON");
-               }
-               if (xp->a_flag & A_PAG) {
-                       fprintf(mfp, " PAG");
-               }
-               if (xp->a_flag & A_PAG) {
-                       ai = (ai & 0xFF);
-                       aj = (aj > 256);
-                       if (ai || aj) { fprintf(mfp, "  "); }
-                       if (ai)      { fprintf(mfp, " Boundary"); }
-                       if (ai & aj)  { fprintf(mfp, " /"); }
-                       if (aj)      { fprintf(mfp, " Length"); }
-                       if (ai || aj) { fprintf(mfp, " Error"); }
-               }
-
-               fprintf( mfp,"\n");
-               if (nmsym>0) {
-                       /*
-                        * Allocate space for an array of pointers to symbols
-                        * and load array.
-                        */
-                       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
-                           == NULL) {
-                               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
-                               return;
-                       }
-                       nmsym = 0;
-                       oxp = xp->a_axp;
-                       while (oxp) {
-                               for (i=0; i<NHASH; i++) {
-                                       sp = symhash[i];
-                                       while (sp != NULL) {
-                                               if (oxp == sp->s_axp) {
-                                                       p[nmsym++] = sp;
-                                               }
-                                               sp = sp->s_sp;
-                                       }
-                               }
-                               oxp = oxp->a_axp;
-                       }
-
-                       /*
-                        * Bubble Sort of Addresses in Symbol Table Array
-                        */
-                       j = 1;
-                       while (j) {
-                               j = 0;
-                               sp = p[0];
-                               a0 = sp->s_addr + sp->s_axp->a_addr;
-                               for (i=1; i<nmsym; ++i) {
-                                       sp = p[i];
-                                       ai = sp->s_addr + sp->s_axp->a_addr;
-                                       if (a0 > ai) {
-                                               j = 1;
-                                               p[i] = p[i-1];
-                                               p[i-1] = sp;
-                                       }
-                                       a0 = ai;
-                               }
-                       }
-
-                       fprintf( mfp, "\tGLOBALS\n");
-                       i = 0;
-                       while (i < nmsym) {
-                               fprintf(mfp, "\t\t%s\t%04X\n", p[i]->s_id, p[i]->s_addr + p[i]->s_axp->a_addr );
-                               i++;
-                       }
-                       free(p);
-               }
-       }
-}
-#endif /* MLH_MAP */
-#else
-
-/* NCPS == 8 */
-/*)Function    VOID    lstarea(xp)
- *
- *             area *  xp              pointer to an area structure
- *
- *     The function lstarea() creates the linker map output for
- *     the area specified by pointer xp.  The generated output
- *     area header includes the area name, starting address,
- *     size of area, number of words (in decimal), and the
- *     area attributes.  The symbols defined in this area are
- *     sorted by ascending address and output four per line
- *     in the selected radix.
- *
- *     local variables:
- *             areax * oxp             pointer to an area extension structure
- *             int     c               character value
- *             int     i               loop counter
- *             int     j               bubble sort update status
- *             char *  ptr             pointer to an id string
- *             int     nmsym           number of symbols in area
- *             Addr_T  a0              temporary
- *             Addr_T  ai              temporary
- *             Addr_T  aj              temporary
- *             sym *   sp              pointer to a symbol structure
- *             sym **  p               pointer to an array of
- *                                     pointers to symbol structures
- *
- *     global variables:
- *             FILE    *mfp            Map output file handle
- *             sym *symhash[NHASH]     array of pointers to NHASH
- *                                     linked symbol lists
- *             int     xflag           Map file radix type flag
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID    free()          c_library
- *             char *  malloc()        c_library
- *             char    putc()          c_library
- *             VOID    slew()          lklist.c
- *
- *     side effects:
- *             Map output generated.
- */
-
-VOID
-lstarea(xp)
-struct area *xp;
-{
-       register struct areax *oxp;
-       register c, i, j;
-       register char *ptr;
-       int nmsym;
-       Addr_T a0, ai, aj;
-       struct sym *sp;
-       struct sym **p;
-
-       putc('\n', mfp);
-       slew(mfp);
-       /*
-        * Output Area Header
-        */
-       ptr = &xp->a_id[0];
-       while (ptr < &xp->a_id[NCPS]) {
-               if ((c = *ptr++) != 0) {
-                       putc(c, mfp);
-               } else {
-                       putc(' ', mfp);
-               }
-       }
-       ai = xp->a_addr;
-       aj = xp->a_size;
-       if (xflag == 0) {
-               fprintf(mfp, "   %04X   %04X", ai, aj);
-       } else
-       if (xflag == 1) {
-               fprintf(mfp, " %06o %06o", ai, aj);
-       } else
-       if (xflag == 2) {
-               fprintf(mfp, "  %05u  %05u", ai, aj);
-       }
-       fprintf(mfp, " = %6u. bytes ", aj);
-       if (xp->a_flag & A_ABS) {
-               fprintf(mfp, "(ABS");
-       } else {
-               fprintf(mfp, "(REL");
-       }
-       if (xp->a_flag & A_OVR) {
-               fprintf(mfp, ",OVR");
-       } else {
-               fprintf(mfp, ",CON");
-       }
-       if (xp->a_flag & A_PAG) {
-               fprintf(mfp, ",PAG");
-       }
-       fprintf(mfp, ")");
-       if (xp->a_flag & A_PAG) {
-               ai = (ai & 0xFF);
-               aj = (aj > 256);
-               if (ai || aj) { fprintf(mfp, "  "); }
-               if (ai)      { fprintf(mfp, " Boundary"); }
-               if (ai & aj)  { fprintf(mfp, " /"); }
-               if (aj)      { fprintf(mfp, " Length"); }
-               if (ai || aj) { fprintf(mfp, " Error"); }
-       }
-
-       /*
-        * Find number of symbols in area
-        */
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp)
-                                       ++nmsym;
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-       if (nmsym == 0) {
-               putc('\n', mfp);
-               slew(mfp);
-               return;
-       }
-
-       /*
-        * Allocate space for an array of pointers to symbols
-        * and load array.
-        */
-       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
-               == NULL) {
-               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
-               slew(mfp);
-               return;
-       }
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp) {
-                                       p[nmsym++] = sp;
-                               }
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-
-       /*
-        * 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;
-               }
-       }
-
-       /*
-        * Symbol Table Output
-        */
-       i = 0;
-       while (i < nmsym) {
-               if (i % 4 == 0) {
-                       fprintf(mfp, "\n");
-                       slew(mfp);
-                       fprintf(mfp, "     ");
-               }
-               sp = p[i];
-               aj = sp->s_addr + sp->s_axp->a_addr;
-               if (xflag == 0) {
-                       fprintf(mfp, "  %04X  ", aj);
-               } else
-               if (xflag == 1) {
-                       fprintf(mfp, "%06o  ", aj);
-               } else
-               if (xflag == 2) {
-                       fprintf(mfp, " %05u  ", aj);
-               }
-               ptr = &sp->s_id[0];
-               while (ptr < &sp->s_id[NCPS]) {
-                       if ((c = *ptr++) != 0) {
-                               putc(c, mfp);
-                       } else {
-                               putc(' ', mfp);
-                       }
-               }
-               if (++i < nmsym)
-                       if (i % 4 != 0)
-                               fprintf(mfp, " | ");
-       }
-       putc('\n', mfp);
-       free(p);
-       slew(mfp);
-}
-#endif
-
-#ifdef SDK
-VOID lstareatosym(struct area *xp)
-{
-       /* Output the current area symbols to a NO$GMB .sym file */
-       register struct areax *oxp;
-       register int i, j;
-       int nmsym;
-       Addr_T a0, ai;
-       struct sym *sp;
-       struct sym **p;
-
-       /*
-        * Find number of symbols in area
-        */
-       nmsym = 0;
-       oxp = xp->a_axp;
-       while (oxp) {
-               for (i=0; i<NHASH; i++) {
-                       sp = symhash[i];
-                       while (sp != NULL) {
-                               if (oxp == sp->s_axp)
-                                       ++nmsym;
-                               sp = sp->s_sp;
-                       }
-               }
-               oxp = oxp->a_axp;
-       }
-
-       /*
-        * Symbol Table Output
-        */
-       if (!((xp->a_size==0)&&(xp->a_addr==0)&&(nmsym==0))) {
-               /* Dont worry about any area information */
-               fprintf(mfp, "; Area: %s\n", xp->a_id );
-               if (nmsym>0) {
-                       /*
-                        * Allocate space for an array of pointers to symbols
-                        * and load array.
-                        */
-                       if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *)))
-                           == NULL) {
-                               fprintf(mfp, "\nInsufficient space to build Map Segment.\n");
-                               return;
-                       }
-                       nmsym = 0;
-                       oxp = xp->a_axp;
-                       while (oxp) {
-                               for (i=0; i<NHASH; i++) {
-                                       sp = symhash[i];
-                                       while (sp != NULL) {
-                                               if (oxp == sp->s_axp) {
-                                                       p[nmsym++] = sp;
-                                               }
-                                               sp = sp->s_sp;
-                                       }
-                               }
-                               oxp = oxp->a_axp;
-                       }
-
-                       /*
-                        * Bubble Sort of Addresses in Symbol Table Array
-                        */
-                       j = 1;
-                       while (j) {
-                               j = 0;
-                               sp = p[0];
-                               a0 = sp->s_addr + sp->s_axp->a_addr;
-                               for (i=1; i<nmsym; ++i) {
-                                       sp = p[i];
-                                       ai = sp->s_addr + sp->s_axp->a_addr;
-                                       if (a0 > ai) {
-                                               j = 1;
-                                               p[i] = p[i-1];
-                                               p[i-1] = sp;
-                                       }
-                                       a0 = ai;
-                               }
-                       }
-                       i = 0;
-                       while (i < nmsym) {
-                               /* no$gmb requires the symbol names to be less than 32 chars long.  Truncate. */
-                               char name[32];
-                               strncpy(name, p[i]->s_id, 31);
-                               name[31] = '\0';
-                               if ((strncmp("l__", name, 3)!=0)&&(strchr(name,' ')==NULL)) {
-                                       a0=p[i]->s_addr + p[i]->s_axp->a_addr;
-                                       if (a0>0x7FFFU) {
-                                               /* Not inside the ROM, so treat as being in bank zero */
-                                               fprintf(mfp, "00:%04X %s\n", a0, name);
-                                       }
-                                       else {
-                                               fprintf(mfp, "%02X:%04X %s\n", a0/16384, a0, name);
-                                       }
-                               }
-                               i++;
-                       }
-                       free(p);
-               }
-       }
-}
-#endif
-
-/*)Function    VOID    lkulist(i)
- *
- *             int     i       i # 0   process LST to RST file
- *                             i = 0   copy remainder of LST file
- *                                     to RST file and close files
- *
- *     The function lkulist() creates a relocated listing (.rst)
- *     output file from the ASxxxx assembler listing (.lst)
- *     files.  The .lst file's program address and code bytes
- *     are changed to reflect the changes made by ASlink as
- *     the .rel files are combined into a single relocated
- *     output file.
- *
- *     local variables:
- *             Addr_T  pc              current program counter address
- *
- *     global variables:
- *             int     hilo            byte order
- *             int     gline           get a line from the LST file
- *                                     to translate for the RST file
- *             char    rb[]            read listing file text line
- *             FILE    *rfp            The file handle to the current
- *                                     output RST file
- *             int     rtcnt           count of data words
- *             int     rtflg[]         output the data flag
- *             Addr_T  rtval[]         relocated data
- *             FILE    *tfp            The file handle to the current
- *                                     LST file being scanned
- *
- *     functions called:
- *             int     fclose()        c_library
- *             int     fgets()         c_library
- *             int     fprintf()       c_library
- *             VOID    lkalist()       lklist.c
- *             VOID    lkglist()       lklist.c
- *
- *     side effects:
- *             A .rst file is created for each available .lst
- *             file associated with a .rel file.
- */
-
-VOID
-lkulist(i)
-int i;
-{
-       Addr_T pc;
-
-       /*
-        * Exit if listing file is not open
-        */
-       if (tfp == NULL)
-               return;
-
-       /*
-        * Normal processing of LST to RST
-        */
-       if (i) {
-               /*
-                * Evaluate current code address
-                */
-               if (hilo == 0) {
-                       pc = ((rtval[1] & 0xFF) << 8) + (rtval[0] & 0xFF);
-               } else {
-                       pc = ((rtval[0] & 0xFF) << 8) + (rtval[1] & 0xFF);
-               }
-
-               /*
-                * Line with only address
-                */
-               if (rtcnt == 2) {
-                       lkalist(pc);
-
-               /*
-                * Line with address and code
-                */
-               } else {
-                       for (i=2; i < rtcnt; i++) {
-                               if (rtflg[i]) {
-                                       lkglist(pc++, rtval[i] & 0xFF);
-                               }
-                       }
-               }
-
-       /*
-        * Copy remainder of LST to RST
-        */
-       } else {
-               if (gline == 0)
-                       fprintf(rfp, rb);
-
-               while (fgets(rb, sizeof(rb), tfp) != 0) {
-                       fprintf(rfp, 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, 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, rb);
-               goto loop;
-       }
-
-       /*
-        * Must have an address in the expected radix
-        */
-       if (radix == 16) {
-               if (!dgt(RAD16, &rb[3], 4)) {
-                       fprintf(rfp, rb);
-                       goto loop;
-               }
-               sprintf(str, "%04X", pc);
-               strncpy(&rb[3], str, 4);
-       } else
-       if (radix == 10) {
-               if (!dgt(RAD10, &rb[3], 5)) {
-                       fprintf(rfp, rb);
-                       goto loop;
-               }
-               sprintf(str, "%05d", pc);
-               strncpy(&rb[3], str, 5);
-       } else
-       if (radix == 8) {
-               if (!dgt(RAD8, &rb[3], 6)) {
-                       fprintf(rfp, rb);
-                       goto loop;
-               }
-               sprintf(str, "%06o", pc);
-               strncpy(&rb[3], str, 6);
-       }
-
-       /*
-        * Copy updated LST text line to RST
-        */
-       fprintf(rfp, 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, 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, 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, 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, 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, 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, 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, rb);
-                       gline = 1;
-                       gcntr = -1;
-               }
-       }
-}
-
-/*)Function    int     dgt(rdx,str,n)
- *
- *             int     rdx             radix bit code
- *             char    *str            pointer to the test string
- *             int     n               number of characters to check
- *
- *     The function dgt() verifies that the string under test
- *     is of the specified radix.
- *
- *     local variables:
- *             int     i               loop counter
- *
- *     global variables:
- *             ctype[]                 array of character types
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- */
-
-int
-dgt(rdx, str, n)
-int rdx, n;
-char *str;
-{
-       int i;
-
-       for (i=0; i<n; i++) {
-               if ((ctype[(unsigned char)(*str++)] & rdx) == 0)
-                       return(0);
-       }
-       return(1);
-}
diff --git a/link/z80/lkmain.c b/link/z80/lkmain.c
deleted file mode 100644 (file)
index f2d071e..0000000
+++ /dev/null
@@ -1,1502 +0,0 @@
-/* lkmain.c */
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-/*
- * Extensions: P. Felber
- */
-
-#include <stdio.h>
-#include <string.h>
-//#include <alloc.h>
-#include "aslink.h"
-#include <stdlib.h>
-
-#ifndef SDK_VERSION_STRING
-#define SDK_VERSION_STRING     "3.0.0"
-#endif
-#ifndef TARGET_STRING
-#define TARGET_STRING          "gbz80"
-#endif
-
-#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()
- *             VOID    lkexit()
- *             VOID    main(argc,argv)
- *             VOID    map()
- *             int     parse()
- *             VOID    setbas()
- *             VOID    setgbl()
- *             VOID    usage()
- *
- *     lkmain.c contains the following local variables:
- *             char *  usetext[]       array of pointers to the
- *                                     command option tect lines
- *
- */
-
-/*)Function    VOID    main(argc,argv)
- *
- *             int     argc            number of command line arguments + 1
- *             char *  argv[]          array of pointers to the command line
- *                                     arguments
- *
- *     The function main() evaluates the command line arguments to
- *     determine if the linker parameters are to input through 'stdin'
- *     or read from a command file.  The functiond lk_getline() and parse()
- *     are to input and evaluate the linker parameters.  The linking process
- *     proceeds by making the first pass through each .rel file in the order
- *     presented to the linker.  At the end of the first pass the setbase(),
- *     lnkarea(), setgbl(), and symdef() functions are called to evaluate
- *     the base address terms, link all areas, define global variables,
- *     and look for undefined symbols.  Following these routines a linker
- *     map file may be produced and the linker output files may be opened.
- *     The second pass through the .rel files will output the linked data
- *     in one of the four supported formats.
- *
- *     local variables:
- *             char *  p               pointer to an argument string
- *             int     c               character from argument string
- *             int     i               loop counter
- *
- *     global variables:
- *                                     text line in ib[]
- *             lfile   *cfp            The pointer *cfp points to the
- *                                     current lfile structure
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             lfile   *filep          The pointer *filep points to the
- *                                     beginning of a linked list of
- *                                     lfile structures.
- *             head    *hp             Pointer to the current
- *                                     head structure
- *             char    ib[NINPUT]      .rel file text line
- *             char    *ip             pointer into the .rel file
- *             lfile   *linkp          pointer to first lfile structure
- *                                     containing an input .rel file
- *                                     specification
- *             int     lkerr           error flag
- *             int     mflag           Map output flag
- *             int     oflag           Output file type flag
- *             FILE    *ofp            Output file handle
- *                                     for word formats
- *             FILE    *ofph           Output file handle
- *                                     for high byte format
- *             FILE    *ofpl           Output file handle
- *                                     for low byte format
- *             int     pass            linker pass number
- *             int     pflag           print linker command file flag
- *             int     radix           current number conversion radix
- *             FILE    *sfp            The file handle sfp points to the
- *                                     currently open file
- *             lfile   *startp         asmlnk startup file structure
- *             FILE *  stdin           c_library
- *             FILE *  stdout          c_library
- *
- *     functions called:
- *             FILE *  afile()         lkmain.c
- *             int     fclose()        c_library
- *             int     fprintf()       c_library
- *             int     lk_getline()    lklex.c
- *             VOID    library()       lklibr.c
- *             VOID    link()          lkmain.c
- *             VOID    lkexit()        lkmain.c
- *             VOID    lnkarea()       lkarea.c
- *             VOID    map()           lkmain.c
- *             VOID    new()           lksym.c
- *             int     parse()         lkmain.c
- *             VOID    reloc()         lkreloc.c
- *             VOID    search()        lklibr.c
- *             VOID    setbas()        lkmain.c
- *             VOID    setgbl()        lkmain.c
- *             VOID    symdef()        lksym.c
- *             VOID    usage()         lkmain.c
- *
- *     side effects:
- *             Completion of main() completes the linking process
- *             and may produce a map file (.map) and/or a linked
- *             data files (.ihx or .s19) and/or one or more
- *             relocated listing files (.rst).
- */
-
-#ifdef SDK
-int binary = 0;
-#endif /* SDK */
-#ifdef GAMEBOY
-char *default_basep[] = {
-  "_CODE=0x0200",
-  "_DATA=0xC0A0",
-  NULL
-};
-
-char *default_globlp[] = {
-  /* DMA transfer must start at multiples of 0x100 */
-  ".OAM=0xC000",
-  ".STACK=0xE000",
-  ".refresh_OAM=0xFF80",
-
-  ".init=0x0000",
-
-  NULL
-};
-#endif /* GAMEBOY */
-
-int
-main(argc, argv)
-char *argv[];
-{
-       register char *p;
-       register int c, i;
-
-#ifdef WIN32T
-    Timer(0, "");
-#endif
-
-#ifdef GAMEBOY
-       nb_rom_banks = 2;
-       nb_ram_banks = 0;
-       mbc_type = 0;
-       symflag=0;
-
-       for(i = 0; default_basep[i] != NULL; i++) {
-               if(basep == NULL) {
-                       basep = (struct base *)new(sizeof(struct base));
-                       bsp = basep;
-               } else {
-                       bsp->b_base = (struct base *)new(sizeof(struct base));
-                       bsp = bsp->b_base;
-               }
-               bsp->b_strp = default_basep[i];
-       }
-       for(i = 0; default_globlp[i] != NULL; i++) {
-               if(globlp == NULL) {
-                       globlp = (struct globl *)new(sizeof(struct globl));
-                       gsp = globlp;
-               } else {
-                       gsp->g_globl = (struct globl *)new(sizeof(struct globl));
-                       gsp = gsp->g_globl;
-               }
-               gsp->g_strp = default_globlp[i];
-       }
-#endif /* GAMEBOY */
-#ifndef SDK
-       fprintf(stdout, "\n");
-#endif /* SDK */
-
-       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();
-                               }
-                       }
-
-#ifdef SDK                     
-                       if(c == '-') {
-                               startp->f_type = F_CMD;
-                               startp->f_idp = (char *)&argv[i+1];
-                               break;
-                       }
-#endif /* SDK */
-
-               } else {
-                       if (startp->f_type == F_LNK) {
-                               startp->f_idp = p;
-                       }
-               }
-       }
-       if (startp->f_type == F_INV)
-               usage();
-       if (startp->f_type == F_LNK && startp->f_idp == NULL)
-               usage();
-#ifdef SDK
-       if (startp->f_type == F_CMD && startp->f_idp == NULL)
-               usage();
-#endif /* SDK */
-
-       cfp = NULL;
-       sfp = NULL;
-       filep = startp;
-       while (1) {
-               ip = ib;                                        
-               if (lk_getline() == 0)
-                       break;
-               if (pflag && sfp != stdin)
-                       fprintf(stdout, "%s\n", ip);
-               if (*ip == '\0' || parse())
-                       break;
-       }
-       if (sfp)
-               fclose(sfp);
-       if (linkp == NULL)
-               usage();
-#ifdef SDK
-       if (linkp->f_flp == NULL)
-               usage();
-#endif /* SDK */
-
-#ifdef GAMEBOY
-       for(i = 1; i < nb_rom_banks; i++) {
-               bsp->b_base = (struct base *)new(sizeof(struct base));
-               bsp = bsp->b_base;
-               bsp->b_strp = (char *)malloc(18);
-               sprintf(bsp->b_strp, "_CODE_%d=0x4000", i);
-       }
-       for(i = 0; i < nb_ram_banks; i++) {
-               bsp->b_base = (struct base *)new(sizeof(struct base));
-               bsp = bsp->b_base;
-               bsp->b_strp = (char *)malloc(18);
-               sprintf(bsp->b_strp, "_DATA_%d=0xA000", i);
-       }
-#endif /* GAMEBOY */
-
-       syminit();
-       for (pass=0; pass<2; ++pass) {
-               cfp = NULL;
-               sfp = NULL;
-#ifdef SDK
-               filep = linkp->f_flp;
-#else /* SDK */
-               filep = linkp;
-#endif /* SDK */
-               hp = NULL;
-               radix = 10;
-
-               while (lk_getline()) {
-                       ip = ib;
-                       link();
-               }
-               if (pass == 0) {
-                       /*
-                        * Search libraries for global symbols
-                        */
-                       search();
-                       /*
-                        * Set area base addresses.
-                        */
-                       setbas();
-                       /*
-                        * Link all area addresses.
-                        */
-                       lnkarea();
-                       /*
-                        * Process global definitions.
-                        */
-                       setgbl();
-                       /*
-                        * Check for undefined globals.
-                        */
-                       symdef(stderr);
-#ifdef SDK
-                       if (symflag) 
-                               sym();
-#endif
-                       /*
-                        * Output Link Map.
-                        */
-                       if (mflag)
-                               map();
-                       /*
-                        * Open output file
-                        */
-                       if (oflag == 1) {
-#ifdef SDK
-                               ofp = afile(linkp->f_idp, "ihx", 1);
-#else /* SDK */
-                               ofp = afile(linkp->f_idp, "IHX", 1);
-#endif /* SDK */
-                               if (ofp == NULL) {
-                                       lkexit(1);
-                               }
-                       } else
-                       if (oflag == 2) {
-#ifdef SDK
-                               ofp = afile(linkp->f_idp, "s19", 1);
-#else /* SDK */
-                               ofp = afile(linkp->f_idp, "S19", 1);
-#endif /* SDK */
-                               if (ofp == NULL) {
-                                       lkexit(1);
-                               }
-#ifdef SDK
-                       } else
-                       if (oflag == 3) {
-                               binary = 1;
-                               ofp = afile(linkp->f_idp, "", 1);
-                               binary = 0;
-                               if (ofp == NULL) {
-                                       lkexit(1);
-                               }
-#endif /* SDK */
-                       }
-               } else {
-                       /*
-                        * Link in library files
-                        */
-                       library();
-                       reloc('E');
-               }
-       }
-#ifdef WIN32T
-    Timer(1, "Linker time");
-#endif
-       lkexit(lkerr);
-
-        /* Never get here. */
-        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(i)
-int i;
-{
-       if (mfp != NULL) fclose(mfp);
-       if (ofp != NULL) fclose(ofp);
-       if (rfp != NULL) fclose(rfp);
-       if (sfp != NULL) fclose(sfp);
-       if (tfp != NULL) fclose(tfp);
-       exit(i);
-}
-
-/*)Function    link()
- *
- *     The function link() evaluates the directives for each line of
- *     text read from the .rel file(s).  The valid directives processed
- *     are:
- *             X, D, Q, H, M, A, S, T, R, and P.
- *
- *     local variables:
- *             int     c               first non blank character of a line
- *
- *     global variables:
- *             head    *headp          The pointer to the first
- *                                     head structure of a linked list
- *             head    *hp             Pointer to the current
- *                                     head structure
- *             int     pass            linker pass number
- *             int     radix           current number conversion radix
- *
- *     functions called:
- *             char    endline()       lklex.c
- *             VOID    module()        lkhead.c
- *             VOID    newarea()       lkarea.c
- *             VOID    newhead()       lkhead.c
- *             sym *   newsym()        lksym.c
- *             VOID    reloc()         lkreloc.c
- *
- *     side effects:
- *             Head, area, and symbol structures are created and
- *             the radix is set as the .rel file(s) are read.
- */
-
-VOID
-link()
-{
-       register int 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.
- */
-
-#ifndef MLH_MAP
-VOID
-map()
-{
-       register i;
-       register struct head *hdp;
-       register struct lbfile *lbfh;
-
-       /*
-        * Open Map File
-        */
-#ifdef SDK
-       mfp = afile(linkp->f_idp, "map", 1);
-#else /* SDK */
-       mfp = afile(linkp->f_idp, "MAP", 1);
-#endif /* SDK */
-       if (mfp == NULL) {
-               lkexit(1);
-       }
-
-       /*
-        * Output Map Area Lists
-        */
-       page = 0;
-       lop  = NLPP;
-       ap = areap;
-       while (ap) {
-               lstarea(ap);
-               ap = ap->a_ap;
-       }
-       /*
-        * List Linked Files
-        */
-       newpag(mfp);
-       fprintf(mfp, "\nFiles Linked      [ module(s) ]\n\n");
-       hdp = headp;
-#ifdef SDK
-       filep = linkp->f_flp;
-#else /* SDK */
-       filep = linkp;
-#endif /* SDK */
-       while (filep) {
-               fprintf(mfp, "%-16s", filep->f_idp);
-               i = 0;
-               while ((hdp != NULL) && (hdp->h_lfile == filep)) {
-                       if (i % 5) {
-                           fprintf(mfp, ", %8.8s", hdp->m_id);
-                       } else {
-                           if (i) {
-                               fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id);
-                           } else {
-                               fprintf(mfp, "  [ %8.8s", hdp->m_id);
-                           }
-                       }
-                       hdp = hdp->h_hp;
-                       i++;
-               }
-               if (i)
-                       fprintf(mfp, " ]");
-               fprintf(mfp, "\n");
-               filep = filep->f_flp;
-       }
-       /*
-        * List Linked Libraries
-        */
-       if (lbfhead != NULL) {
-               fprintf(mfp,
-       "\nLibraries Linked                    [   object  file   ]\n\n");
-               for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) {
-                       fprintf(mfp, "%-32s    [ %16.16s ]\n",
-                               lbfh->libspc, lbfh->relfil);
-               }
-               fprintf(mfp, "\n");
-       }
-       /*
-        * List Base Address Definitions
-        */
-       if (basep) {
-               newpag(mfp);
-               fprintf(mfp, "\nUser Base Address Definitions\n\n");
-               bsp = basep;
-               while (bsp) {
-                       fprintf(mfp, "%s\n", bsp->b_strp);
-                       bsp = bsp->b_base;
-               }
-       }
-       /*
-        * List Global Definitions
-        */
-       if (globlp) {
-               newpag(mfp);
-               fprintf(mfp, "\nUser Global Definitions\n\n");
-               gsp = globlp;
-               while (gsp) {
-                       fprintf(mfp, "%s\n", gsp->g_strp);
-                       gsp = gsp->g_globl;
-               }
-       }
-       fprintf(mfp, "\n\f");
-       symdef(mfp);
-}
-#else
-VOID map()
-{
-       register struct head *hdp;
-       register struct lbfile *lbfh;
-
-       /*
-        * Open Map File
-        */
-#ifdef SDK
-       mfp = afile(linkp->f_idp, "map", 1);
-#else /* SDK */
-       mfp = afile(linkp->f_idp, "MAP", 1);
-#endif /* SDK */
-       if (mfp == NULL) {
-               lkexit(1);
-       }
-
-       /*
-        *Output Map Area Lists
-        */
-       page = 0;
-       lop  = NLPP;
-       ap = areap;
-       while (ap) {
-               lstarea(ap);
-               ap = ap->a_ap;
-       }
-       /*
-        * List Linked Files
-        */
-       hdp = headp;
-#ifdef SDK
-       filep = linkp->f_flp;
-#else /* SDK */
-       filep = linkp;
-#endif /* SDK */
-       if (filep) {
-               fprintf( mfp, "MODULES\n");
-       }
-       while (filep) {
-               fprintf(mfp, "\tFILE %s\n", filep->f_idp);
-               while ((hdp != NULL) && (hdp->h_lfile == filep)) {
-                       if (strlen(hdp->m_id)>0)
-                               fprintf(mfp, "\t\tNAME %s\n", hdp->m_id);
-                       hdp = hdp->h_hp;
-               }
-               filep = filep->f_flp;
-       }
-       /*
-        * List Linked Libraries
-        */
-       if (lbfhead != NULL) {
-               fprintf(mfp, "LIBRARIES\n");
-               for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) {
-                       fprintf(mfp,    "\tLIBRARY %s\n"
-                                       "\t\tMODULE %s\n",
-                               lbfh->libspc, lbfh->relfil);
-               }
-       }
-       /*
-        * List Base Address Definitions
-        */
-       if (basep) {
-               fprintf(mfp, "USERBASEDEF\n");
-               bsp = basep;
-               while (bsp) {
-                       fprintf(mfp, "\t%s\n", bsp->b_strp);
-                       bsp = bsp->b_base;
-               }
-       }
-       /*
-        * List Global Definitions
-        */
-       if (globlp) {
-               fprintf(mfp, "USERGLOBALDEF\n");
-               gsp = globlp;
-               while (gsp) {
-                       fprintf(mfp, "\t%s\n", gsp->g_strp);
-                       gsp = gsp->g_globl;
-               }
-       }
-       symdef(mfp);
-#ifdef SDK
-       if (mfp!=NULL) {
-               fclose(mfp);
-               mfp = NULL;
-       }
-#endif
-}
-#endif /* MLH_MAP */
-
-#ifdef SDK
-/* PENDING */
-VOID lstareatosym(struct area *xp);
-
-VOID sym()
-{
-       /*
-        * Open sym File
-        */
-       mfp = afile(linkp->f_idp, "sym", 1);
-       if (mfp == NULL) {
-               lkexit(1);
-       }
-       fprintf( mfp,   "; no$gmb format .sym file\n"
-                       "; Generated automagically by ASxxxx linker %s (SDK " SDK_VERSION_STRING ")\n"
-               , VERSION );
-       /*
-        * Output sym Area Lists
-        */
-       page = 0;
-       lop  = NLPP;
-       ap = areap;
-       while (ap) {
-               lstareatosym(ap);
-               ap = ap->a_ap;
-       }
-       if (mfp!=NULL) {
-               fclose(mfp);
-               mfp = NULL;
-       }
-}
-#endif /* SDK */
-
-/*)Function    int     parse()
- *
- *     The function parse() evaluates all command line or file input
- *     linker directives and updates the appropriate variables.
- *
- *     local variables:
- *             int     c               character value
- *             char    fid[]           file id string
- *
- *     global variables:
- *             char    ctype[]         array of character types, one per
- *                                     ASCII character
- *             lfile   *lfp            pointer to current lfile structure
- *                                     being processed by parse()
- *             lfile   *linkp          pointer to first lfile structure
- *                                     containing an input REL file
- *                                     specification
- *             int     mflag           Map output flag
- *             int     oflag           Output file type flag
- *             int     pflag           print linker command file flag
- *             FILE *  stderr          c_library
- *             int     uflag           Relocated listing flag
- *             int     xflag           Map file radix type flag
- *
- *     Functions called:
- *             VOID    addlib()        lklibr.c
- *             VOID    addpath()       lklibr.c
- *             VOID    bassav()        lkmain.c
- *             int     fprintf()       c_library
- *             VOID    gblsav()        lkmain.c
- *             VOID    getfid()        lklex.c
- *             char    getnb()         lklex.c
- *             VOID    lkexit()        lkmain.c
- *             char *  strcpy()        c_library
- *             int     strlen()        c_library
- *
- *     side effects:
- *             Various linker flags are updated and the linked
- *             structure lfile is created.
- */
-
-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;
-#ifdef GAMEBOY
-                               case 'y':
-                               case 'Y':
-                                       c = get();
-                                       if(c == 'O' || c == 'o')
-                                               nb_rom_banks = expr(0);
-                                       else if(c == 'A' || c == 'a')
-                                               nb_ram_banks = expr(0);
-                                       else if(c == 'T' || c == 't')
-                                               mbc_type = expr(0);
-                                       else if(c == 'N' || c == 'n') {
-                                               int i = 0;
-                                               if(getnb() != '=' || getnb() != '"') {
-                                                       fprintf(stderr, "Syntax error in -YN=\"name\" flag\n");
-                                                       lkexit(1);
-                                               }
-                                               while((c = get()) != '"' && i < 16) {
-                                                       cart_name[i++] = c;
-                                               }
-                                               if(i < 16)
-                                                       cart_name[i] = 0;
-                                               else
-                                                       while(get() != '"')
-                                                               ;
-                                       } else if(c == 'P' || c == 'p') {
-                                               patch *p = patches;
-
-                                               patches = (patch *)malloc(sizeof(patch));
-                                               patches->next = p;
-                                               patches->addr = expr(0);
-                                               if(getnb() != '=') {
-                                                       fprintf(stderr, "Syntax error in -YHaddr=val flag\n");
-                                                       lkexit(1);
-                                               }
-                                               patches->value = expr(0);
-                                       } else {
-                                               fprintf(stderr, "Invalid option\n");
-                                               lkexit(1);
-                                       }
-                                       break;
-
-#endif /* GAMEBOY */
-#ifdef SDK
-                               case 'j':
-                               case 'J':
-                                       ++symflag;
-                                       break;
-                               case 'z':
-                               case 'Z':
-                                       oflag = 3;
-                                       break;
-#endif /* SDK */
-                               case 'm':
-                               case 'M':
-                                       ++mflag;
-                                       break;
-
-                               case 'u':
-                               case 'U':
-                                       uflag = 1;
-                                       break;
-
-                               case 'x':
-                               case 'X':
-                                       xflag = 0;
-                                       break;
-
-                               case 'q':
-                               case 'Q':
-                                       xflag = 1;
-                                       break;
-
-                               case 'd':
-                               case 'D':
-                                       xflag = 2;
-                                       break;
-
-                               case 'e':
-                               case 'E':
-                                       return(1);
-
-                               case 'n':
-                               case 'N':
-                                       pflag = 0;
-                                       break;
-
-                               case 'p':
-                               case 'P':
-                                       pflag = 1;
-                                       break;
-
-                               case 'b':
-                               case 'B':
-                                       bassav();
-                                       return(0);
-
-                               case 'g':
-                               case 'G':
-                                       gblsav();
-                                       return(0);
-
-                               case 'k':
-                               case 'K':
-                                       addpath();
-                                       return(0);
-
-                               case 'l':
-                               case 'L':
-                                       addlib();
-                                       return(0);
-
-                               default:
-                                       fprintf(stderr, "Invalid option\n");
-                                       lkexit(1);
-                               }
-                       }
-                       if (c == ';')
-                               return(0);
-               } else
-               if (ctype[c] != ILL) {
-                       if (linkp == NULL) {
-                               linkp = (struct lfile *)
-                                       new (sizeof (struct lfile));
-                               lfp = linkp;
-                       } else {
-                               lfp->f_flp = (struct lfile *)
-                                               new (sizeof (struct lfile));
-                               lfp = lfp->f_flp;
-                       }
-                       getfid(fid, c);
-                       lfp->f_idp = (char *) new (strlen(fid)+1);
-                       strcpy(lfp->f_idp, fid);
-                       lfp->f_type = F_REL;
-               } else {
-                       fprintf(stderr, "Invalid input");
-                       lkexit(1);
-               }
-       }
-       return(0);
-}
-
-/*)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 hte
- *     basep structure, evaluates the arguments, and sets beginning
- *     address of the specified areas.
- *
- *     local variables:
- *             int     v               expression value
- *             char    id[]            base id string
- *
- *     global variables:
- *             area    *ap             Pointer to the current
- *                                     area structure
- *             area    *areap          The pointer to the first
- *                                     area structure of a linked list
- *             base    *basep          The pointer to the first
- *                                     base structure
- *             base    *bsp            Pointer to the current
- *                                     base structure
- *             char    *ip             pointer into the REL file
- *                                     text line in ib[]
- *             int     lkerr           error flag
- *
- *      functions called:
- *             Addr_T  expr()          lkeval.c
- *             int     fprintf()       c_library
- *             VOID    getid()         lklex.c
- *             char    getnb()         lklex.c
- *             int     symeq()         lksym.c
- *
- *     side effects:
- *             The base address of an area is set.
- */
-
-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) {
-#ifndef SDK
-                               fprintf(stderr,
-                               "No definition of area %s\n", id);
-                               lkerr++;
-#endif /* SDK */
-                       } else {
-                               ap->a_addr = v;
-                       }
-               } else {
-                       fprintf(stderr, "No '=' in base expression");
-                       lkerr++;
-               }
-               bsp = bsp->b_base;
-       }
-}
-
-/*)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 hte
- *     globlp structure, evaluates the arguments, and sets a variable
- *     to this value.
- *
- *     local variables:
- *             int     v               expression value
- *             char    id[]            base id string
- *             sym *   sp              pointer to a symbol structure
- *
- *     global variables:
- *             char    *ip             pointer into the REL file
- *                                     text line in ib[]
- *             globl   *globlp         The pointer to the first
- *                                     globl structure
- *             globl   *gsp            Pointer to the current
- *                                     globl structure
- *             FILE *  stderr          c_library
- *             int     lkerr           error flag
- *
- *      functions called:
- *             Addr_T  expr()          lkeval.c
- *             int     fprintf()       c_library
- *             VOID    getid()         lklex.c
- *             char    getnb()         lklex.c
- *             sym *   lkpsym()        lksym.c
- *
- *     side effects:
- *             The value of a variable is set.
- */
-
-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) {
-#ifndef SDK
-                               fprintf(stderr,
-                               "No definition of symbol %s\n", id);
-                               lkerr++;
-#endif /* SDK */
-                       } else {
-#ifndef SDK
-                               if (sp->s_flag & S_DEF) {
-                                       fprintf(stderr,
-                                       "Redefinition of symbol %s\n", id);
-                                       lkerr++;
-                                       sp->s_axp = NULL;
-                               }
-#endif /* SDK */
-                               sp->s_addr = v;
-                               sp->s_type |= S_DEF;
-                       }
-               } else {
-                       fprintf(stderr, "No '=' in global expression");
-                       lkerr++;
-               }
-               gsp = gsp->g_globl;
-       }
-}
-
-/*)Function    FILE *  afile(fn,, ft, wf)
- *
- *             char *  fn              file specification string
- *             char *  ft              file type string
- *             int     wf              read(0)/write(1) flag
- *
- *     The function afile() opens a file for reading or writing.
- *             (1)     If the file type specification string ft
- *                     is not NULL then a file specification is
- *                     constructed with the file path\name in fn
- *                     and the extension in ft.
- *             (2)     If the file type specification string ft
- *                     is NULL then the file specification is
- *                     constructed from fn.  If fn does not have
- *                     a file type then the default .rel file
- *                     type is appended to the file specification.
- *
- *     afile() returns a file handle for the opened file or aborts
- *     the assembler on an open error.
- *
- *     local variables:
- *             int     c               character value
- *             char    fb[]            constructed file specification string
- *             FILE *  fp              filehandle for opened file
- *             char *  p1              pointer to filespec string fn
- *             char *  p2              pointer to filespec string fb
- *             char *  p3              pointer to filetype string ft
- *
- *     global variables:
- *             int     lkerr           error flag
- *
- *     functions called:
- *             FILE *  fopen()         c_library
- *             int     fprintf()       c_library
- *
- *     side effects:
- *             File is opened for read or write.
- */
-
-FILE *
-afile(fn, ft, wf)
-char *fn;
-char *ft;
-{
-#if 0
-       register char *p1, *p2, *p3;
-       register int c;
-#else
-       int i;
-#endif 
-       FILE *fp;
-       char fb[FILSPC];
-
-#if 0  
-       p1 = fn;
-       p2 = fb;
-       p3 = ft;
-       while ((c = *p1++) != 0 && c != FSEPX) {
-               if (p2 < &fb[FILSPC-4])
-                       *p2++ = c;
-       }
-       *p2++ = FSEPX;
-       if (*p3 == 0) {
-               if (c == FSEPX) {
-                       p3 = p1;
-               } else {
-#ifdef SDK
-                       p3 = "rel";
-#else /* SDK */
-                       p3 = "REL";
-#endif /* SDK */
-               }
-       }
-       while ((c = *p3++) != 0) {
-               if (p2 < &fb[FILSPC-1])
-                       *p2++ = c;
-       }
-       *p2++ = 0;
-#else
-       /*Look backward the name path and get rid of the extension, if any*/
-       i=strlen(fn);
-       for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--);
-       if( (fn[i]=='.') && *ft && strcmp(ft, "lnk") )
-       {
-               strncpy(fb, fn, i);
-               fb[i]=0;
-       }
-       else
-       {
-               strcpy(fb, fn);
-       }
-
-       /*Add the extension*/
-       if (fb[i] != '.')
-       {
-               strcat(fb, ".");
-#ifdef SDK
-               strcat(fb, strlen(ft)?ft:"rel");
-#else
-               strcat(fb, strlen(ft)?ft:"REL");
-#endif
-       }
-#endif
-
-#ifdef SDK
-       if ((fp = fopen(fb, wf?(binary?"wb":"w"):(binary?"rb":"r"))) == NULL) {
-#else /* SDK */
-       if ((fp = fopen(fb, wf?"w":"r")) == NULL) {
-#endif /* SDK */
-               fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
-               lkerr++;
-       }
-       return (fp);
-}
-
-char *usetxt[] = {
-#ifdef SDK
-       "Distributed with SDK " SDK_VERSION_STRING ", built on " __DATE__ " " __TIME__,
-       "Compile options: SDK Target " TARGET_STRING
-#ifdef INDEXLIB
-       " INDEXLIB"
-#endif
-       "\n",
-#endif
-       "Startup:",
-#ifdef SDK
-       "  --   [Commands]              Non-interactive command line input",
-#endif /* SDK */
-       "  -c                           Command line input",
-       "  -f   file[LNK]               File input",
-       "  -p   Prompt and echo of file[LNK] to stdout (default)",
-       "  -n   No echo of file[LNK] to stdout",
-#ifdef SDK
-       "Usage: [-Options] outfile file [file ...]",
-#else /* SDK */
-       "Usage: [-Options] file [file ...]",
-#endif /* SDK */
-       "Librarys:",
-       "  -k   Library path specification, one per -k",
-       "  -l   Library file specification, one per -l",
-       "Relocation:",
-       "  -b   area base address = expression",
-       "  -g   global symbol = expression",
-#ifdef GAMEBOY
-       "  -yo  Number of rom banks (default: 2)",
-       "  -ya  Number of ram banks (default: 0)",
-       "  -yt  MBC type (default: no MBC)",
-       "  -yn  Name of program (default: name of output file)",
-       "  -yp# Patch one byte in the output GB file (# is: addr=byte)",
-#endif /* GAMEBOY */
-       "Map format:",
-       "  -m   Map output generated as file[MAP]",
-#ifdef SDK
-       "  -j   no$gmb symbol file generated as file[SYM]",
-#endif /* SDK */
-       "  -x   Hexidecimal (default)",
-       "  -d   Decimal",
-       "  -q   Octal",
-       "Output:",
-       "  -i   Intel Hex as file[IHX]",
-       "  -s   Motorola S19 as file[S19]",
-#ifdef SDK
-#ifdef GAMEGEAR
-       "  -z   Gamegear image as file[GG]",
-#else
-       "  -z   Gameboy image as file[GB]",
-#endif /* GAMEGEAR */
-#endif /* SDK */
-       "List:",
-       "  -u   Update listing file(s) with link data as file(s)[.RST]",
-       "End:",
-       "  -e   or null line terminates input",
-       "",
-       0
-};
-
-/*)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);
-}
diff --git a/link/z80/lkrloc.c b/link/z80/lkrloc.c
deleted file mode 100644 (file)
index e5bdd05..0000000
+++ /dev/null
@@ -1,1171 +0,0 @@
-/* lkrloc.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-/*
- * Extensions: P. Felber
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-//#include <alloc.h>
-#include <ctype.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[].
- *
- */
-
-/*)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(c)
-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()
-{
-       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()
-{
-       register int mode;
-       register Addr_T reli, relv;
-       int aindex, rindex, rtp, error;
-       Addr_T r, rtbase, rtofst, paga = 0, pags = 0, pc;
-       struct areax **a;
-       struct sym **s;
-
-       /*
-        * Get area and symbol lists
-        */
-       a = hp->a_list;
-       s = hp->s_list;
-
-       /*
-        * Verify Area Mode
-        */
-       if (eval() != (R_WORD | R_AREA) || eval()) {
-               fprintf(stderr, "R input error\n");
-               lkerr++;
-       }
-
-       /*
-        * Get area pointer
-        */
-       aindex = evword();
-       if (aindex >= hp->h_narea) {
-               fprintf(stderr, "R area error\n");
-               lkerr++;
-               return;
-       }
-
-       /*
-        * Base values
-        */
-       rtbase = adw_w(0, 0);
-       rtofst = 2;
-
-       /*
-        * Relocate address
-        */
-       pc = adw_w(a[aindex]->a_addr, 0);
-
-#ifdef GAMEBOY
-       {
-               char *s = strrchr(a[aindex]->a_bap->a_id, '_');
-               if(s != NULL && isdigit((unsigned char)s[1]))
-                       current_rom_bank = atoi(s+1);
-               else
-                       current_rom_bank = 0;
-       }
-#endif /* GAMEBOY */
-       /*
-        * Do remaining relocations
-        */
-       while (more()) {
-               error = 0;
-               mode = eval();
-               rtp = eval();
-               rindex = evword();
-
-               /*
-                * R_SYM or R_AREA references
-                */
-               if (mode & R_SYM) {
-                       if (rindex >= hp->h_nglob) {
-                               fprintf(stderr, "R symbol error\n");
-                               lkerr++;
-                               return;
-                       }
-                       reli = symval(s[rindex]);
-               } else {
-                       if (rindex >= hp->h_narea) {
-                               fprintf(stderr, "R area error\n");
-                               lkerr++;
-                               return;
-                       }
-                       reli = a[rindex]->a_addr;
-               }
-
-               /*
-                * R_PCR addressing
-                */
-               if (mode & R_PCR) {
-                       if (mode & R_BYTE) {
-                               reli -= (pc + (rtp-rtofst) + 1);
-                       } else {
-                               reli -= (pc + (rtp-rtofst) + 2);
-                       }
-               }
-
-               /*
-                * R_PAG0 or R_PAG addressing
-                */
-               if (mode & (R_PAG0|R_PAG)) {
-                       paga  = sdp.s_area->a_addr;
-                       pags  = sdp.s_addr;
-                       reli -= paga + pags;
-               }
-
-               /*
-                * R_BYTE or R_WORD operation
-                */
-               if (mode & R_BYTE) {
-                       if (mode & R_BYT2) {
-                               if (mode & R_MSB) {
-                                       relv = adb_hi(reli, rtp);
-                               } else {
-                                       relv = adb_lo(reli, rtp);
-                               }
-                       } else {
-                               relv = adb_b(reli, rtp);
-                       }
-               } else {
-                       /*
-                        * R_WORD with the R_BYT2 mode is flagged
-                        * as an 'r' error by the assembler,
-                        * but it is processed here anyway.
-                        */
-                       if (mode & R_BYT2) {
-                               if (mode & R_MSB) {
-                                       relv = adw_hi(reli, rtp);
-                               } else {
-                                       relv = adw_lo(reli, rtp);
-                               }
-                       } else {
-                               relv = adw_w(reli, rtp);
-                       }
-               }
-
-               /*
-                * R_BYTE with R_BYT2 offset adjust
-                */
-               if (mode & R_BYTE) {
-                       if (mode & R_BYT2) {
-                               rtofst += 1;
-                       }
-               }
-
-               /*
-                * Unsigned Byte Checking
-                */
-               if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
-                       error = 1;
-
-               /*
-                * PCR Relocation Error Checking
-                */
-               if (mode & R_PCR && mode & R_BYTE) {
-                       r = relv & ~0x7F;
-                       if (r != (Addr_T) ~0x7F && r != 0)
-                               error = 2;
-               }
-
-               /*
-                * Page Relocation Error Checking
-                */
-               if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
-                       error = 3;
-               if (mode & R_PAG  && (relv & ~0xFF))
-                       error = 4;
-
-               /*
-                * Error Processing
-                */
-               if (error) {
-                       rerr.aindex = aindex;
-                       rerr.mode = mode;
-                       rerr.rtbase = rtbase + rtp - rtofst - 1;
-                       rerr.rindex = rindex;
-                       rerr.rval = relv - reli;
-                       relerr(errmsg[error-1]);
-               }
-       }
-       if (uflag != 0) {
-               lkulist(1);
-       }
-       if (oflag == 1) {
-               ihx(1);
-       } else
-       if (oflag == 2) {
-               s19(1);
-#ifdef SDK
-       } else
-       if (oflag == 3) {
-#ifdef GAMEGEAR
-               gg(1);
-#endif /* GAMEGEAR */
-#ifdef GAMEBOY
-               gb(1);
-#endif /* GAMEBOY */
-#endif /* SDK */
-       }
-}
-
-char *errmsg[] = {
-       "Unsigned Byte error",
-       "Byte PCR relocation error",
-       "Page0 relocation error",
-       "Page Mode relocation error"
-};
-
-
-/*)Function    VOID    relp()
- *
- *     The function relp() evaluates a P line read by
- *     the linker.  The P line data is combined with the
- *     previous T line data to set the base page address
- *     and test the paging boundary and length.
- *
- *             P Line 
- *
- *             P 0 0 nn nn n1 n2 xx xx 
- *
- *     The  P  line provides the paging information to the linker as
- *     specified by a .setdp directive.  The format of  the  relocation
- *     information is identical to that of the R line.  The correspond-
- *     ing T line has the following information:  
- *             T xx xx aa aa bb bb 
- *
- *     Where  aa aa is the area reference number which specifies the
- *     selected page area and bb bb is the base address  of  the  page.
- *     bb bb will require relocation processing if the 'n1 n2 xx xx' is
- *     specified in the P line.  The linker will verify that  the  base
- *     address is on a 256 byte boundary and that the page length of an
- *     area defined with the PAG type is not larger than 256 bytes.  
- *
- *     local variable:
- *             areax   **a             pointer to array of area pointers
- *             int     aindex          area index
- *             int     mode            relocation mode
- *             Addr_T  relv            relocation value
- *             int     rindex          symbol / area index
- *             int     rtp             index into T data
- *             sym     **s             pointer to array of symbol pointers
- *
- *     global variables:
- *             head    *hp             pointer to the head structure
- *             int     lkerr           error flag
- *             sdp     sdp             base page structure
- *             FILE    *stderr         standard error device
- *
- *     called functions:
- *             Addr_T  adw_w()         lkrloc.c
- *             Addr_T  evword()        lkrloc.c
- *             int     eval()          lkeval.c
- *             int     fprintf()       c_library
- *             int     more()          lklex.c
- *             int     symval()        lksym.c
- *
- *     side effects:
- *             The P and T lines are combined to set
- *             the base page address and report any
- *             paging errors.
- *
- */
-
-VOID
-relp()
-{
-       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()
-{
-       if (uflag != 0) {
-               lkulist(0);
-       }
-       if (oflag == 1) {
-               ihx(0);
-       } else
-       if (oflag == 2) {
-               s19(0);
-#ifdef SDK
-       } else
-       if (oflag == 3) {
-#ifdef GAMEGEAR
-               gg(0);
-#endif /* GAMEGEAR */
-#ifdef GAMEBOY
-               gb(0);
-#endif /* GAMEBOY */
-#endif /* SDK */
-       }
-}
-
-/*)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()
-{
-       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(v, i)
-register Addr_T v;
-register int i;
-{
-       return(rtval[i] += v);
-}
-
-/*)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(v, i)
-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(v, i)
-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  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(v, i)
-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_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(v, i)
-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(v, i)
-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(str)
-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(fptr, str)
-FILE *fptr;
-char *str;
-{
-       int mode, aindex, rindex;
-       struct sym **s;
-       struct areax **a;
-       struct areax *raxp;
-
-       a = hp->a_list;
-       s = hp->s_list;
-
-       mode = rerr.mode;
-       aindex = rerr.aindex;
-       rindex = rerr.rindex;
-
-       /*
-        * Print Error
-        */
-       fprintf(fptr, "\n?ASlink-Warning-%s", str);
-       lkerr++;
-
-       /*
-        * Print symbol if symbol based
-        */
-       if (mode & R_SYM) {
-               fprintf(fptr, " for symbol  %.*s\n",
-                       NCPS, &s[rindex]->s_id[0]);
-       } else {
-               fprintf(fptr, "\n");
-       }
-
-       /*
-        * Print Ref Info
-        */
-       fprintf(fptr,
-               "         file        module      area        offset\n");
-       fprintf(fptr,
-               "  Refby  %-8.8s    %-8.8s    %-8.8s    ",
-                       hp->h_lfile->f_idp,
-                       &hp->m_id[0],
-                       &a[aindex]->a_bap->a_id[0]);
-       prntval(fptr, rerr.rtbase);
-
-       /*
-        * Print Def Info
-        */
-       if (mode & R_SYM) {
-               raxp = s[rindex]->s_axp;
-       } else {
-               raxp = a[rindex];
-       }
-       fprintf(fptr,
-               "  Defin  %-8.8s    %-8.8s    %-8.8s    ",
-                       raxp->a_bhp->h_lfile->f_idp,
-                       &raxp->a_bhp->m_id[0],
-                       &raxp->a_bap->a_id[0]);
-       if (mode & R_SYM) {
-               prntval(fptr, s[rindex]->s_addr);
-       } else {
-               prntval(fptr, rerr.rval);
-       }
-}
-
-/*)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(fptr, v)
-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(str)
-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(fptr, str)
-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/link/z80/lks19.c b/link/z80/lks19.c
deleted file mode 100644 (file)
index bbca753..0000000
+++ /dev/null
@@ -1,123 +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 <alloc.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/link/z80/lksym.c b/link/z80/lksym.c
deleted file mode 100644 (file)
index 33cc6ff..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-/* lksym.c */
-
-/*
- * (C) Copyright 1989-1995
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "aslink.h"
-
-/*)Module      lksym.c
- *
- *     The module lksym.c contains the functions that operate
- *     on the symbol structures.
- *
- *     lksym.c contains the following functions:
- *             int     hash()
- *             sym *   lkpsym()
- *             VOID *  new()
- *             sym *   newsym()
- *             VOID    symdef()
- *             int     symeq()
- *             VOID    syminit()
- *             VOID    symmod()
- *             Addr_T  symval()
- *
- *     lksym.c contains no local/static variables.
- */
-
-/*)Function    VOID    syminit()
- *
- *     The function syminit() is called to clear the hashtable.
- *
- *     local variables:
- *             int     h               computed hash value
- *             sym **  spp             pointer to an array of
- *                                     sym structure pointers
- *
- *     global variables:
- *             sym * symhash[]         array of pointers to NHASH
- *                                     linked symbol lists
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             (1)     The symbol hash tables are cleared
- */
-
-VOID
-syminit()
-{
-       struct sym **spp;
-
-       spp = &symhash[0];
-       while (spp < &symhash[NHASH])
-               *spp++ = NULL;
-}
-
-/*)Function    sym *   newsym()
- *
- *     The function newsym() is called to evaluate the symbol
- *     definition/reference directive from the .rel file(s).
- *     If the symbol is not found in the symbol table a new
- *     symbol structure is created.  Evaluation of the
- *     directive determines if this is a reference or a definition.
- *     Multiple definitions of the same variable will be flagged
- *     as an error if the values are not identical.  A symbol
- *     definition places the symbol value and area extension
- *     into the symbols data structure.  And finally, a pointer
- *     to the symbol structure is placed into the head structure
- *     symbol list.  Refer to the description of the header, symbol,
- *     area, and areax structures in lkdata.c for structure and
- *     linkage details.
- *
- *     local variables:
- *             int     c               character from input text
- *             int     i               evaluation value
- *             char    id[]            symbol name
- *             int     nglob           number of symbols in this header
- *             sym *   tsp             pointer to symbol structure
- *             sym **  s               list of pointers to symbol structures
- *
- *     global variables:
- *             areax   *axp            Pointer to the current
- *                                     areax structure
- *             head    *headp          The pointer to the first
- *                                     head structure of a linked list
- *             int     lkerr           error flag
- *
- *     functions called:
- *             Addr_T  eval()          lkeval.c
- *             VOID    exit()          c_library
- *             int     fprintf()       c_library
- *             char    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];
-
-       getid(id, -1);
-       tsp = lkpsym(id, 1);
-       c = getnb();get();get();
-       if (c == 'R') {
-               tsp->s_type |= S_REF;
-               if (eval()) {
-                       fprintf(stderr, "Non zero S_REF\n");
-                       lkerr++;
-               }
-       } else
-       if (c == 'D') {
-               i = eval();
-               if (tsp->s_type & S_DEF && tsp->s_addr != i) {
-#ifdef SDK
-                       fprintf(stderr, "Multiple definition of %s\n", id);
-#else
-                       fprintf(stderr, "Multiple definition of %.8s\n", id);
-#endif
-                       lkerr++;
-               }
-               tsp->s_type |= S_DEF;
-               /*
-                * Set value and area extension link.
-                */
-               tsp->s_addr = i;
-               tsp->s_axp = axp;
-       } else {
-               fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id);
-               lkexit(1);
-       }
-       /*
-        * Place pointer in header symbol list
-        */
-       if (headp == NULL) {
-               fprintf(stderr, "No header defined\n");
-               lkexit(1);
-       }
-       nglob = hp->h_nglob;
-       s = hp->s_list;
-       for (i=0; i < nglob ;++i) {
-               if (s[i] == NULL) {
-                       s[i] = tsp;
-                       return(tsp);
-               }
-       }
-       fprintf(stderr, "Header symbol list overflow\n");
-       lkexit(1);
-
-       /* Never reached */
-        return 0;
-}
-
-/*)Function    sym *   lkpsym(id,f)
- *
- *             char *  id              symbol name string
- *             int     f               f == 0, lookup only
- *                                     f != 0, create if not found
- *
- *     The function lookup() searches the symbol hash tables for
- *     a symbol name match returning a pointer to the sym structure.
- *     If the symbol is not found then a sym structure is created,
- *     initialized, and linked to the appropriate hash table if f != 0.
- *     A pointer to this new sym structure is returned or a NULL
- *     pointer is returned if f == 0.
- *
- *     local variables:
- *             int     h               computed hash value
- *             sym *   sp              pointer to a sym structure
- *
- *     global varaibles:
- *             sym * symhash[]         array of pointers to NHASH
- *                                     linked symbol lists
- *
- *     functions called:
- *             int     hash()          lksym.c
- *             VOID *  new()           lksym.c
- *             int     symeq()         lksym.c
- *
- *     side effects:
- *             If the function new() fails to allocate space
- *             for the new sym structure the linker terminates.
- */
-
-struct sym *
-lkpsym(id, f)
-char *id;
-{
-       register struct sym *sp;
-       register int h;
-
-       h = hash(id);
-       sp = symhash[h];
-       while (sp != NULL) {
-               if (symeq(id, sp->s_id))
-                       return (sp);
-               sp = sp->s_sp;
-       }
-       if (f == 0)
-               return (NULL);
-       sp = (struct sym *) new (sizeof(struct sym));
-       sp->s_sp = symhash[h];
-       symhash[h] = sp;
-       strncpy(sp->s_id, id, NCPS);
-       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;
-{
-       register int n;
-
-       n = NCPS;
-       do {
-
-#if    CASE_SENSITIVE
-               if (*p1++ != *p2++)
-                       return (0);
-#else
-               if (ccase[(unsigned char)(*p1++)] != ccase[(unsigned char)(*p2++)])
-                       return (0);
-#endif
-
-       } while (--n);
-       return (1);
-}
-
-/*)Function    int     hash(p)
- *
- *             char *  p               pointer to string to hash
- *
- *     The function hash() computes a hash code using the sum
- *     of all characters mod table size algorithm.
- *
- *     local variables:
- *             int     h               accumulated character sum
- *             int     n               loop counter
- *
- *     global variables:
- *             char    ccase[]         an array of characters which
- *                                     perform the case translation function
- *
- *     functions called:
- *             none
- *
- *     side effects:
- *             none
- *
- */
-int
-hash(p)
-register char *p;
-{
-       register int h, n;
-
-       h = 0;
-       n = NCPS;
-       do {
-
-#if    CASE_SENSITIVE
-               h += *p++;
-#else
-               h += ccase[(unsigned char)(*p++)];
-#endif
-
-       } while (--n);
-       return (h&HMASK);
-}
-
-/*)Function    VOID *  new(n)
- *
- *             unsigned int    n       allocation size in bytes
- *
- *     The function new() allocates n bytes of space and returns
- *     a pointer to this memory.  If no space is available the
- *     linker is terminated.
- *
- *     local variables:
- *             char *  p               a general pointer
- *             char *  q               a general pointer
- *
- *     global variables:
- *             none
- *
- *     functions called:
- *             int     fprintf()       c_library
- *             VOID *  malloc()        c_library
- *
- *     side effects:
- *             Memory is allocated, if allocation fails
- *             the linker is terminated.
- */
-
-VOID *
-new(n)
-unsigned int n;
-{
-       register char *p,*q;
-       register unsigned int i;
-
-       if ((p = (char *) malloc(n)) == NULL) {
-               fprintf(stderr, "Out of space!\n");
-               lkexit(1);
-       }
-       for (i=0,q=p; i<n; i++) {
-               *q++ = 0;
-       }
-       return (p);
-}
index b5846652de29334c118a060848b677f40014d4ee..954f07aac3413d2bae0f7ca894ff9f24304db92b 100644 (file)
--- a/sdcc.dsw
+++ b/sdcc.dsw
@@ -240,7 +240,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "linkgbz80"=.\link\z80\linkgbz80.dsp - Package Owner=<4>
+Project: "linkgbz80"=.\as\link\z80\linkgbz80.dsp - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -252,7 +252,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "linkz80"=.\LINK\Z80\linkz80.dsp - Package Owner=<4>
+Project: "linkz80"=.\as\link\z80\linkz80.dsp - Package Owner=<4>
 
 Package=<5>
 {{{