* Added support for the gb.
[fw/sdcc] / src / mcs51 / main.c
index 6dd76d9242338d651e29f0f2ba0f3924a0779b79..3723fed344ca466c1f334e8a5474fe1a6e2c6bde 100644 (file)
+/** @file main.c
+    mcs51 specific general functions.
+
+    Note that mlh prepended _mcs51_ on the static functions.  Makes
+    it easier to set a breakpoint using the debugger.
+*/
 #include "common.h"
 #include "main.h"
+#include "ralloc.h"
+
+static char _defaultRules[] =
+{
+#include "peeph.rul"
+};
+
+/* list of key words used by msc51 */
+static char *_mcs51_keywords[] =     {
+    "at",
+    "bit",
+    "code",
+    "critical",
+    "data",
+    "far",
+    "idata",
+    "interrupt",
+    "near",
+    "pdata",
+    "reentrant",
+    "sfr",
+    "sbit",
+    "using",
+    "xdata",
+    "_data",
+    "_code",
+    "_generic",
+    "_near",
+    "_xdata",
+    "_pdata",
+    "_idata",
+    NULL
+};
+
 
 void mcs51_assignRegisters (eBBlock **ebbs, int count);
 
-static bool _mcs51_parseOptions(int *pargc, char **argv)
+static bool _mcs51_parseOptions(int *pargc, char **argv, int *i)
 {
+    /* TODO: allow port-specific command line options to specify
+     * segment names here.
+     */
     return FALSE;
 }
 
 static void _mcs51_finaliseOptions(void)
 {
+    /* Hack-o-matic: if we are using the flat24 model,
+     * adjust pointer sizes.
+     */
+    if (options.model == MODEL_FLAT24)
+    {
+        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                                      
+        
+    } 
 }
 
 static void _mcs51_setDefaultOptions(void)
-{    
+{
+}
+
+static const char *_mcs51_getRegName(struct regs *reg)
+{
+    if (reg)
+       return reg->name;
+    return "err";
 }
 
+static void _mcs51_genAssemblerPreamble(FILE *of)
+{
+   if (options.model == MODEL_FLAT24)
+   {
+       fputs(".flat24 on\t\t; 24 bit flat addressing\n", of);
+       fputs("dpx = 0x93\t\t; dpx register unknown to assembler\n", of);
+
+   }
+}
+
+/* Generate interrupt vector table. */
+static int _mcs51_genIVT(FILE *of, symbol **interrupts, int maxInterrupts)
+{
+    int i;
+    
+    if (options.model != MODEL_FLAT24)
+    {
+        /* Let the default code handle it. */
+       return FALSE;
+    }
+    
+    fprintf (of, "\tajmp\t__sdcc_gsinit_startup\n");
+    
+    /* now for the other interrupts */
+    for (i = 0; i < maxInterrupts; i++) 
+    {
+       if (interrupts[i])
+       {
+           fprintf(of, "\tljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
+       }
+       else
+       {
+           fprintf(of, "\treti\n\t.ds\t7\n");
+       }
+    }
+    
+    return TRUE;
+}
+
+/** $1 is always the basename.
+    $2 is always the output file.
+    $3 varies
+    $l is the list of extra options that should be there somewhere...
+    MUST be terminated with a NULL.
+*/
+static const char *_linkCmd[] = {
+    "aslink", "-nf", "$1", NULL
+};
+
+static const char *_asmCmd[] = {
+    "asx8051", "-plosgffc", "$1.asm", NULL
+};
+
 /* Globals */
 PORT mcs51_port = {
     "mcs51",
     "MCU 8051",                        /* Target name */
     {  
-       "asx8051",              /* Assembler executable name */
+       _asmCmd,
        "-plosgffc",            /* Options with debug */
        "-plosgff",             /* Options without debug */
-       FALSE                   /* TRUE if the assembler requires an output name */
     },
     {
-       "aslink",               /* Linker executable name */
+       _linkCmd
+    },
+    {
+       _defaultRules
     },
     {
        /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
        1, 1, 2, 4, 1, 2, 3, 1, 4, 4
     },
+    {
+       "XSEG    (XDATA)",
+       "STACK   (DATA)",
+       "CSEG    (CODE)",
+       "DSEG    (DATA)",
+       "ISEG    (DATA)",
+       "XSEG    (XDATA)",
+       "BSEG    (BIT)",
+       "RSEG    (DATA)",
+       "GSINIT  (CODE)",
+       "OSEG    (OVR,DATA)"
+    },
     { 
-       +1, 1, 4, 0, 0
+       +1, 1, 4, 1, 1
     },
     /* mcs51 has an 8 bit mul */
     {
        1
     },
+    NULL,
     _mcs51_parseOptions,
     _mcs51_finaliseOptions,
     _mcs51_setDefaultOptions,
-    mcs51_assignRegisters
+    mcs51_assignRegisters,
+    _mcs51_getRegName ,
+    _mcs51_keywords,
+    _mcs51_genAssemblerPreamble,
+    _mcs51_genIVT
 };