* as/mcs51/lkarea.c: removed old K&R style,
[fw/sdcc] / src / pic16 / main.c
index df0b1a49bc53e3128c09c17f78a0699d35a0554b..f298a0ea528ed714586f6730dfb77395b2977501 100644 (file)
@@ -46,6 +46,7 @@ static char *_pic16_keywords[] =
   "bit",
   "code",
   "critical",
+  "register",
   "data",
   "far",
   "idata",
@@ -90,58 +91,22 @@ extern set *libFilesSet;
 /* for an unknowned reason. - EEP */
 void pic16_emitDebuggerSymbol (char *);
  
+extern regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop);
+extern void pic16_emitConfigRegs(FILE *of);
+extern void pic16_emitIDRegs(FILE *of);
+
+
 
 static void
 _pic16_init (void)
 {
-#if 0
-  char pic16incDir[512];
-  char pic16libDir[512];
-  set *pic16incDirsSet;
-  set *pic16libDirsSet;
-  char devlib[512];
-#endif
-
-       asm_addTree (&asm_asxxxx_mapping);
-       pic16_pCodeInitRegisters();
-       maxInterrupts = 2;
-
-       /* set pic16 port options to defaults */
-       pic16_options.no_banksel = 0;
-       pic16_options.opt_banksel = 0;
-       pic16_options.omit_configw = 0;
-       pic16_options.omit_ivt = 0;
-       pic16_options.leave_reset = 0;
-       pic16_options.stack_model = 0;                  /* 0 for 'small', 1 for 'large' */
-
-
-#if 0
-       setMainValue("mcu", pic16->name[2] );
-       addSet(&preArgvSet, Safe_strdup("-D{mcu}"));
-
-       sprintf(pic16incDir, "%s/pic16", INCLUDE_DIR_SUFFIX);
-       sprintf(pic16libDir, "%s/pic16", LIB_DIR_SUFFIX);
-
-       if(!options.nostdinc) {
-               /* setup pic16 include directory */
-               pic16incDirsSet = appendStrSet(dataDirsSet, NULL, pic16incDir);
-               mergeSets(&includeDirsSet, pic16incDirsSet);
-       }
-       
-       if(!options.nostdlib) {
-               /* setup pic16 library directory */
-               pic16libDirsSet = appendStrSet(dataDirsSet, NULL, pic16libDir);
-               mergeSets(&libDirsSet, pic16libDirsSet);
-       
-               /* now add the library for the device */
-               sprintf(devlib, "%s.lib", pic16->name[2]);
-               addSet(&libFilesSet, Safe_strdup(devlib));
-       }
-#endif
+  asm_addTree (&asm_asxxxx_mapping);
+  pic16_pCodeInitRegisters();
+  maxInterrupts = 2;
 }
 
 static void
-_pic16_reset_regparm ()
+_pic16_reset_regparm (void)
 {
   regParmFlg = 0;
 }
@@ -149,13 +114,18 @@ _pic16_reset_regparm ()
 static int
 _pic16_regparm (sym_link * l)
 {
-  /* for this processor it is simple
-     can pass only the first parameter in a register */
-  //if (regParmFlg)
-  //  return 0;
-
-  regParmFlg++;// = 1;
-  return 1;
+  /* force all parameters via SEND/RECEIVE */
+  if(0 /*pic16_options.ip_stack*/) {
+    /* for this processor it is simple
+     * can pass only the first parameter in a register */
+    if(regParmFlg)return 0;
+      regParmFlg++;
+      return 1;        //regParmFlg;
+  } else {
+    /* otherwise pass all arguments in registers via SEND/RECEIVE */
+    regParmFlg++;// = 1;
+    return regParmFlg;
+  }
 }
 
 
@@ -163,13 +133,18 @@ int initsfpnt=0;          /* set to 1 if source provides a pragma for stack
                                 * so glue() later emits code to initialize stack/frame pointers */
 set *absSymSet;
 
+set *sectNames=NULL;                   /* list of section listed in pragma directives */
+set *sectSyms=NULL;                    /* list of symbols set in a specific section */
+
+
 static int
 _process_pragma(const char *sz)
 {
-  static const char *WHITE = " \t";
+  static const char *WHITE = " \t\n";
   
   char *ptr = strtok((char *)sz, WHITE);
 
+       /* #pragma maxram [maxram] */
        if (startsWith (ptr, "maxram")) {
          char *maxRAM = strtok((char *)NULL, WHITE);
 
@@ -181,25 +156,58 @@ _process_pragma(const char *sz)
                        maxRAMaddress = (int)floatFromVal(maxRAMVal);
                        pic16_setMaxRAM(maxRAMaddress);
                }
+
+          return 0;
        }
        
+       /* #pragma stack [stack-position] [stack-len] */
        if(startsWith(ptr, "stack")) {
          char *stackPosS = strtok((char *)NULL, WHITE);
+         char *stackLenS = strtok((char *)NULL, WHITE);
          value *stackPosVal;
+         value *stackLenVal;
          regs *reg;
+         symbol *sym;
 
-//             fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos)));
                stackPosVal = constVal( stackPosS );
                stackPos = (unsigned int)floatFromVal( stackPosVal );
 
-               reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "stack", 1, 0, NULL);
+               
+               if(stackLenS) {
+                       stackLenVal = constVal( stackLenS );
+                       stackLen = (unsigned int)floatFromVal( stackLenVal );
+               }
+
+               if(stackLen < 1) {
+                       stackLen = 64;
+                       fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
+                                     filename, lineno-1, stackLen, stackLen);
+                        
+//                     fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen);
+               }
+
+//             fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
+                               
+               reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
                addSet(&pic16_fix_udata, reg);
                
+               reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
+               addSet(&pic16_fix_udata, reg);
+
+               sym = newSymbol("stack", 0);
+               sprintf(sym->rname, "_%s", sym->name);
+               addSet(&publics, sym);
+
+               sym = newSymbol("stack_end", 0);
+               sprintf(sym->rname, "_%s", sym->name);
+               addSet(&publics, sym);
+               
                initsfpnt = 1;          // force glue() to initialize stack/frame pointers */
 
          return 0;
        }
        
+       /* #pragma code [symbol] [location] */
        if(startsWith(ptr, "code")) {
          char *symname = strtok((char *)NULL, WHITE);
          char *location = strtok((char *)NULL, WHITE);
@@ -207,17 +215,69 @@ _process_pragma(const char *sz)
          value *addr;
 
                absS = Safe_calloc(1, sizeof(absSym));
-               absS->name = Safe_strdup( symname );
+               sprintf(absS->name, "_%s", symname);
+               
                addr = constVal( location );
                absS->address = (unsigned int)floatFromVal( addr );
 
+               if((absS->address % 2) != 0) {
+                 absS->address--;
+                 fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n",
+                                     filename, lineno-1, absS->address);
+                }
+
                addSet(&absSymSet, absS);
-               fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
-                       __FILE__, __LINE__, symname, absS->address);
+//             fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
+//                     __FILE__, __LINE__, symname, absS->address);
 
          return 0;
-       }         
+       }
+
+       /* #pragma udata [section-name] [symbol] */
+       if(startsWith(ptr, "udata")) {
+         char *sectname = strtok((char *)NULL, WHITE);
+         char *symname = strtok((char *)NULL, WHITE);
+         symbol *nsym;
+         sectSym *ssym;
+         sectName *snam;
+         int found=0;
+         
+               while(symname) {
+                       ssym = Safe_calloc(1, sizeof(sectSyms));
+                       ssym->name = Safe_calloc(1, strlen(symname)+2);
+                       sprintf(ssym->name, "_%s", symname);
+                       ssym->reg = NULL;
+
+                       addSet(&sectSyms, ssym);
+
+                        nsym = newSymbol(symname, 0);
+                        strcpy(nsym->rname, ssym->name);
+                       checkAddSym(&publics, nsym);
+
+                       found = 0;
+                       for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) {
+                               if(!strcmp(sectname, snam->name)){ found=1; break; }
+                       }
+                       
+                       if(!found) {
+                               snam = Safe_calloc(1, sizeof(sectNames));
+                               snam->name = Safe_strdup( sectname );
+                               snam->regsSet = NULL;
+                               
+                               addSet(&sectNames, snam);
+                       }
+                       
+                       ssym->section = snam;
+                               
+//                     fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__,
+//                             ssym->name, snam->name, snam);
+
+                       symname = strtok((char *)NULL, WHITE);
+               }
 
+         return 0;
+       }
+       
   return 1;
 }
 
@@ -226,18 +286,36 @@ _process_pragma(const char *sz)
 #define STACK_MODEL    "--pstack-model="
 #define OPT_BANKSEL    "--obanksel="
 
+#define ALT_ASM                "--asm="
+#define ALT_LINK       "--link="
 
+#define IVT_LOC                "--ivt-loc"
+#define NO_DEFLIBS     "--nodefaultlibs"
+#define MPLAB_COMPAT   "--mplab-comp"
+
+#define NL_OPT         "--nl="
+#define USE_CRT                "--use-crt="
+
+char *alt_asm=NULL;
+char *alt_link=NULL;
+
+int pic16_mplab_comp=0;
 extern int pic16_debug_verbose;
 extern int pic16_ralloc_debug;
 extern int pic16_pcode_verbose;
 
+int pic16_fstack=0;
+int pic16_enable_peeps=0;
+int pic16_nl=0;                        /* 0 for LF, 1 for CRLF */
+
 OPTION pic16_optionsTable[]= {
+       { 0,    NO_DEFLIBS,             &pic16_options.nodefaultlibs,   "do not link default libraries when linking"},
        { 0,    "--pno-banksel",        &pic16_options.no_banksel,      "do not generate BANKSEL assembler directives"},
        { 0,    OPT_BANKSEL,            NULL,                           "set banksel optimization level (default=0 no)"},
        { 0,    "--pomit-config-words", &pic16_options.omit_configw,    "omit the generation of configuration words"},
        { 0,    "--pomit-ivt",          &pic16_options.omit_ivt,        "omit the generation of the Interrupt Vector Table"},
        { 0,    "--pleave-reset-vector",&pic16_options.leave_reset,     "when omitting IVT leave RESET vector"},
-       { 0,    STACK_MODEL,    NULL,   "use stack model 'small' (default) or 'large'"},
+       { 0,    STACK_MODEL,            NULL,                           "use stack model 'small' (default) or 'large'"},
 
        { 0,    "--debug-xtra",         &pic16_debug_verbose,   "show more debug info in assembly output"},
        { 0,    "--debug-ralloc",       &pic16_ralloc_debug,    "dump register allocator debug file *.d"},
@@ -245,6 +323,17 @@ OPTION pic16_optionsTable[]= {
                
        { 0,    REP_UDATA,      NULL,   "Place udata variables at another section: udata_acs, udata_ovr, udata_shr"},
 
+       { 0,    ALT_ASM,        NULL,   "Use alternative assembler"},
+       { 0,    ALT_LINK,       NULL,   "Use alternative linker"},
+
+       { 0,    "--denable-peeps",      &pic16_enable_peeps,    "explicit enable of peepholes"},
+       { 0,    IVT_LOC,        NULL,   "<nnnn> interrupt vector table location"},
+       { 0,    "--calltree",           &pic16_options.dumpcalltree,    "dump call tree in .calltree file"},
+       { 0,    MPLAB_COMPAT,           &pic16_mplab_comp,      "enable compatibility mode for MPLAB utilities (MPASM/MPLINK)"},
+       { 0,    "--fstack",             &pic16_fstack,          "enable stack optimizations"},
+       { 0,    NL_OPT,         NULL,                           "new line, \"lf\" or \"crlf\""},
+       { 0,    USE_CRT,        NULL,   "use <crt-o> run-time initialization module"},
+       { 0,    "--no-crt",     &pic16_options.no_crt,  "do not link any default run-time initialization module"},
        { 0,    NULL,           NULL,   NULL}
        };
 
@@ -275,8 +364,8 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
 
        if(ISOPT(STACK_MODEL)) {
                stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc);
-               if(STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0;
-               else if(STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1;
+               if(!STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0;
+               else if(!STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1;
                else {
                        fprintf(stderr, "Unknown stack model: %s", stkmodel);
                        exit(-1);
@@ -294,114 +383,182 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
                return TRUE;
        }
        
+       if(ISOPT(ALT_ASM)) {
+               alt_asm = Safe_strdup(getStringArg(ALT_ASM, argv, i, *pargc));
+               return TRUE;
+       }
+       
+       if(ISOPT(ALT_LINK)) {
+               alt_link = Safe_strdup(getStringArg(ALT_LINK, argv, i, *pargc));
+               return TRUE;
+       }
+
+       if(ISOPT(IVT_LOC)) {
+               pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc);
+               return TRUE;
+       }
+       
+       if(ISOPT(NL_OPT)) {
+          char *tmp;
+            
+            tmp = Safe_strdup( getStringArg(NL_OPT, argv, i, *pargc) );
+            if(!STRCASECMP(tmp, "lf"))pic16_nl = 0;
+            else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1;
+            else {
+                  fprintf(stderr, "invalid termination character id\n");
+                  exit(-1);
+            }
+            return TRUE;
+        }
+
+        if(ISOPT(USE_CRT)) {
+            pic16_options.no_crt = 0;
+            pic16_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) );
+
+            return TRUE;
+        }
+        
   return FALSE;
 }
 
+extern set *userIncDirsSet;
+
 static void _pic16_initPaths(void)
 {
-#if 1
   char pic16incDir[512];
   char pic16libDir[512];
-  set *pic16incDirsSet;
-  set *pic16libDirsSet;
+  set *pic16incDirsSet=NULL;
+  set *pic16libDirsSet=NULL;
   char devlib[512];
-#endif
 
-#if 1
-       setMainValue("mcu", pic16->name[2] );
-       addSet(&preArgvSet, Safe_strdup("-D{mcu}"));
+    setMainValue("mcu", pic16->name[2] );
+    addSet(&preArgvSet, Safe_strdup("-D{mcu}"));
 
-       sprintf(pic16incDir, "%s/pic16", INCLUDE_DIR_SUFFIX);
-       sprintf(pic16libDir, "%s/pic16", LIB_DIR_SUFFIX);
+    sprintf(pic16incDir, "%s%cpic16", INCLUDE_DIR_SUFFIX, DIR_SEPARATOR_CHAR);
+    sprintf(pic16libDir, "%s%cpic16", LIB_DIR_SUFFIX, DIR_SEPARATOR_CHAR);
 
-       if(!options.nostdinc) {
-               /* setup pic16 include directory */
-               pic16incDirsSet = appendStrSet(dataDirsSet, NULL, pic16incDir);
-               mergeSets(&includeDirsSet, pic16incDirsSet);
-       }
-       
-       if(!options.nostdlib) {
-               /* setup pic16 library directory */
-               pic16libDirsSet = appendStrSet(dataDirsSet, NULL, pic16libDir);
-               mergeSets(&libDirsSet, pic16libDirsSet);
-       
-               /* now add the library for the device */
-               sprintf(devlib, "%s.lib", pic16->name[2]);
-               addSet(&libFilesSet, Safe_strdup(devlib));
+
+    if(!options.nostdinc) {
+      /* setup pic16 include directory */
+      pic16incDirsSet = appendStrSet(dataDirsSet, NULL, pic16incDir);
+      includeDirsSet = pic16incDirsSet;
+//      mergeSets(&includeDirsSet, pic16incDirsSet);
+    }
+    /* pic16 port should not search to the SDCC standard include directories,
+     * so add here the deleted include dirs that user has issued in command line */
+    mergeSets(&pic16incDirsSet, userIncDirsSet);
+
+    if(!options.nostdlib) {
+      /* setup pic16 library directory */
+      pic16libDirsSet = appendStrSet(dataDirsSet, NULL, pic16libDir);
+      libDirsSet = pic16libDirsSet;
+//      mergeSets(&libDirsSet, pic16libDirsSet);
+    }
+
+    if(!pic16_options.nodefaultlibs) {
+      /* now add the library for the device */
+      sprintf(devlib, "%s.lib", pic16->name[2]);
+      addSet(&libFilesSet, Safe_strdup(devlib));
+
+      /* add the internal SDCC library */
+      addSet(&libFilesSet, Safe_strdup( "libsdcc.lib" ));
+    }
+}
+
+extern set *linkOptionsSet;
+char *msprintf(hTab *pvals, const char *pformat, ...);
+int my_system(const char *cmd);
+
+/* custom function to link objects */
+static void _pic16_linkEdit(void)
+{
+  hTab *linkValues=NULL;
+  char lfrm[256];
+  char *lcmd;
+  char temp[128];
+  set *tSet=NULL;
+  int ret;
+  
+       /*
+        * link command format:
+        * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs}
+        *
+        */
+        
+       sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {user_ofile} {spec_ofiles} {ofiles} {libs}");
+                
+       shash_add(&linkValues, "linker", "gplink");
+
+       mergeSets(&tSet, libDirsSet);
+       mergeSets(&tSet, libPathsSet);
+       
+       shash_add(&linkValues, "incdirs", joinStrSet( appendStrSet(tSet, "-I\"", "\"")));
+       shash_add(&linkValues, "lflags", joinStrSet(linkOptionsSet));
+  
+       shash_add(&linkValues, "outfile", dstFileName);
+
+       if(fullSrcFileName) {
+               sprintf(temp, "%s.o", dstFileName);
+//             addSetHead(&relFilesSet, Safe_strdup(temp));
+                shash_add(&linkValues, "user_ofile", temp);
        }
-#endif
+
+       if(!pic16_options.no_crt)
+          shash_add(&linkValues, "spec_ofiles", pic16_options.crt_name);
+
+       shash_add(&linkValues, "ofiles", joinStrSet(relFilesSet));
+       shash_add(&linkValues, "libs", joinStrSet(libFilesSet));
+       
+       lcmd = msprintf(linkValues, lfrm);
+        
+       ret = my_system( lcmd );
+        
+       Safe_free( lcmd );
+        
+       if(ret)
+               exit(1);
 }
 
 
+/* forward declarations */
+extern const char *pic16_linkCmd[];
+extern const char *pic16_asmCmd[];
+
 static void
 _pic16_finaliseOptions (void)
 {
-#if 0
-  char pic16incDir[512];
-  char pic16libDir[512];
-  set *pic16incDirsSet;
-  set *pic16libDirsSet;
-  char devlib[512];
-#endif
-       port->mem.default_local_map = data;
-       port->mem.default_globl_map = data;
+    port->mem.default_local_map = data;
+    port->mem.default_globl_map = data;
 
-       options.all_callee_saves = 1;           // always callee saves
-//     options.float_rent = 1;
-//     options.intlong_rent = 1;
-       
-#if 0
-       setMainValue("mcu", pic16->name[2] );
-       addSet(&preArgvSet, Safe_strdup("-D{mcu}"));
+    /* peepholes are disabled for the time being */
+    options.nopeep = 1;
 
-       sprintf(pic16incDir, "%s/pic16", INCLUDE_DIR_SUFFIX);
-       sprintf(pic16libDir, "%s/pic16", LIB_DIR_SUFFIX);
+    /* explicit enable peepholes for testing */
+    if(pic16_enable_peeps)
+      options.nopeep = 0;
 
-       if(!options.nostdinc) {
-               /* setup pic16 include directory */
-               pic16incDirsSet = appendStrSet(dataDirsSet, NULL, pic16incDir);
-               mergeSets(&includeDirsSet, pic16incDirsSet);
-       }
+    options.all_callee_saves = 1;              // always callee saves
+
+#if 0
+    options.float_rent = 1;
+    options.intlong_rent = 1;
+#endif
        
-       if(!options.nostdlib) {
-               /* setup pic16 library directory */
-               pic16libDirsSet = appendStrSet(dataDirsSet, NULL, pic16libDir);
-               mergeSets(&libDirsSet, pic16libDirsSet);
+
+    if(alt_asm && strlen(alt_asm))
+      pic16_asmCmd[0] = alt_asm;
        
-               /* now add the library for the device */
-               sprintf(devlib, "%s.lib", pic16->name[2]);
-               addSet(&libFilesSet, Safe_strdup(devlib));
-       }
-#endif
+    if(alt_link && strlen(alt_link))
+      pic16_linkCmd[0] = alt_link;
+        
+    if(!pic16_options.no_crt) {
+      pic16_options.omit_ivt = 1;
+      pic16_options.leave_reset = 0;
+    }
 }
 
 
-/* all the rest is commented ifdef'd out */
 #if 0
-  /* Hack-o-matic: if we are using the flat24 model,
-   * adjust pointer sizes.
-   */
-  if (options.model == MODEL_FLAT24)
-    {
-
-      fprintf (stderr, "*** WARNING: you should use the '-mds390' option "
-              "for DS80C390 support. This code generator is "
-              "badly out of date and probably broken.\n");
-
-      port->s.fptr_size = 3;
-      port->s.gptr_size = 4;
-      port->stack.isr_overhead++;      /* Will save dpx on ISR entry. */
-#if 1
-      port->stack.call_overhead++;     /* This acounts for the extra byte 
-                                        * of return addres on the stack.
-                                        * but is ugly. There must be a 
-                                        * better way.
-                                        */
-#endif
-      fReturn = fReturn390;
-      fReturnSize = 5;
-    }
-
   if (options.model == MODEL_LARGE)
     {
       port->mem.default_local_map = xdata;
@@ -437,37 +594,26 @@ _pic16_finaliseOptions (void)
 static void
 _pic16_setDefaultOptions (void)
 {
-       /* initialize to defaults section locations, names and addresses */
-       pic16_sectioninfo.at_udata      = "udata";
-       pic16_sectioninfo.at_udataacs   = "udata_acs";
-       pic16_sectioninfo.at_udataovr   = "udata_ovr";
-       pic16_sectioninfo.at_udatashr   = "udata_shr";
-
-       /* initialize to nothing, so let linker decide about their names */
-       pic16_sectioninfo.name_code     =
-       pic16_sectioninfo.name_idata    =
-       pic16_sectioninfo.name_udata    =
-       pic16_sectioninfo.name_udataacs =
-       pic16_sectioninfo.name_udataovr =
-       pic16_sectioninfo.name_udatashr = "";
-
-       /* initialize to -1, so let linker decide about their address */
-       pic16_sectioninfo.addr_code     =
-       pic16_sectioninfo.addr_idata    =
-       pic16_sectioninfo.addr_udata    =
-       pic16_sectioninfo.addr_udataacs =
-       pic16_sectioninfo.addr_udataovr =
-       pic16_sectioninfo.addr_udatashr = -1;
-
-
-
-       /* set pic16 port options to defaults */
-       pic16_options.no_banksel = 0;
-       pic16_options.opt_banksel = 0;
-       pic16_options.omit_configw = 0;
-       pic16_options.omit_ivt = 0;
-       pic16_options.leave_reset = 0;
-       pic16_options.stack_model = 0;                  /* 0 for 'small', 1 for 'large' */
+  options.stackAuto = 0;               /* implicit declaration */
+  /* port is not capable yet to allocate separate registers 
+   * dedicated for passing certain parameters */
+  
+  /* initialize to defaults section locations, names and addresses */
+  pic16_sectioninfo.at_udata   = "udata";
+
+  /* set pic16 port options to defaults */
+  pic16_options.no_banksel = 0;
+  pic16_options.opt_banksel = 0;
+  pic16_options.omit_configw = 0;
+  pic16_options.omit_ivt = 0;
+  pic16_options.leave_reset = 0;
+  pic16_options.stack_model = 0;                       /* 0 for 'small', 1 for 'large' */
+  pic16_options.ivt_loc = 0x000000;
+  pic16_options.nodefaultlibs = 0;
+  pic16_options.dumpcalltree = 0;
+  pic16_options.crt_name = "crt0i.o";          /* the default crt to link */
+  pic16_options.no_crt = 0;                    /* use crt by default */
+  pic16_options.ip_stack = 1;          /* set to 1 to enable ipop/ipush for stack */
 }
 
 static const char *
@@ -502,17 +648,9 @@ _pic16_genAssemblerPreamble (FILE * of)
        fprintf (of, "\tlist\tp=%s\n",&name[1]);
 
        if(!pic16_options.omit_configw) {
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300001, pic16_getConfigWord(0x300001));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300002, pic16_getConfigWord(0x300002));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300003, pic16_getConfigWord(0x300003));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300005, pic16_getConfigWord(0x300005));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300006, pic16_getConfigWord(0x300006));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300008, pic16_getConfigWord(0x300008));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x300009, pic16_getConfigWord(0x300009));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x30000a, pic16_getConfigWord(0x30000a));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x30000b, pic16_getConfigWord(0x30000b));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x30000c, pic16_getConfigWord(0x30000c));
-               fprintf (of, "\t__config 0x%x,0x%hhx\n", 0x30000d, pic16_getConfigWord(0x30000d));
+               pic16_emitConfigRegs(of);
+               fprintf(of, "\n");
+               pic16_emitIDRegs(of);
        }
        
   fprintf (of, "\tradix dec\n");
@@ -561,13 +699,18 @@ static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
 {
 //     fprintf(stderr,"checking for native mult for %c (size: %d)\n", ic->op, getSize(OP_SYMBOL(IC_RESULT(ic))->type));
 
-       /* support mul for char/int {/long} */
-       if((getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 2)
-               && (ic->op == '*'))return TRUE;
-       
+#if 1
+       /* multiplication is fixed */
+       /* support mul for char/int/long */
+       if((ic->op == '*')
+         && (getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 2))return TRUE;
+#endif
+
+#if 0
        /* support div for char/int/long */
        if((getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 0)
                && (ic->op == '/'))return TRUE;
+#endif
        
   return FALSE;
 }
@@ -638,15 +781,15 @@ oclsExpense (struct memmap *oclass)
   return 0;
 }
 
-/** $1 is always the basename.
+/** $1 is the input object file (PIC16 specific)       // >>always the basename<<.
     $2 is always the output file.
     $3 -L path and -l libraries
     $l is the list of extra options that should be there somewhere...
     MUST be terminated with a NULL.
 */
-static const char *_linkCmd[] =
+const char *pic16_linkCmd[] =
 {
-  "gplink", "$3", "\"$1.o\"", "-o $1", "$l", NULL
+  "gplink", "$l", "-o \"$2\"", "\"$1\"","$3", NULL
 };
 
 
@@ -657,9 +800,9 @@ static const char *_linkCmd[] =
     $l is the list of extra options that should be there somewhere...
     MUST be terminated with a NULL.
 */
-static const char *_asmCmd[] =
+const char *pic16_asmCmd[] =
 {
-  "gpasm", "$l", "$3", "-c", "\"$1.asm\"", NULL
+  "gpasm", "$l", "$3", "-c", "\"$1.asm\"", "-o \"$2\"", NULL
 
 };
 
@@ -677,18 +820,18 @@ PORT pic16_port =
     MODEL_SMALL
   },
   {
-    _asmCmd,                   /* assembler command and arguments */
+    pic16_asmCmd,              /* assembler command and arguments */
     NULL,                      /* alternate macro based form */
-    NULL,                      /* arguments for debug mode */
+    "-g",                      /* arguments for debug mode */
     NULL,                      /* arguments for normal mode */
     0,                         /* print externs as global */
     ".asm",                    /* assembler file extension */
     NULL                       /* no do_assemble function */
   },
   {
-    _linkCmd,                  /* linker command and arguments */
+    NULL,                      //    pic16_linkCmd,            /* linker command and arguments */
     NULL,                      /* alternate macro based form */
-    NULL,                      /* no do_link function */
+    _pic16_linkEdit,           //NULL,                 /* no do_link function */
     ".o",                      /* extension for object files */
     0                          /* no need for linker file */
   },
@@ -703,7 +846,7 @@ PORT pic16_port =
     4,         /* long */
     2,         /* ptr */
     3,         /* fptr, far pointers (see Microchip) */
-    2,         /* gptr */
+    3,         /* gptr */
     1,         /* bit */
     4,         /* float */
     4          /* max */
@@ -714,6 +857,7 @@ PORT pic16_port =
     "CSEG    (CODE)",          // code
     "DSEG    (DATA)",          // data
     "ISEG    (DATA)",          // idata
+    NULL,                                      // pdata
     "XSEG    (XDATA)",         // xdata
     "BSEG    (BIT)",           // bit
     "RSEG    (DATA)",          // reg
@@ -747,6 +891,16 @@ PORT pic16_port =
   {
     pic16_emitDebuggerSymbol
   },
+  {
+    255/3,      /* maxCount */
+    3,          /* sizeofElement */
+    /* The rest of these costs are bogus. They approximate */
+    /* the behavior of src/SDCCicode.c 1.207 and earlier.  */
+    {4,4,4},    /* sizeofMatchJump[] */
+    {0,0,0},    /* sizeofRangeCompare[] */
+    0,          /* sizeofSubtract */
+    3,          /* sizeofDispatch */
+  },
   "_",
   _pic16_init,
   _pic16_parseOptions,