Lots.
[fw/sdcc] / src / mcs51 / main.c
1 /** @file main.c
2     mcs51 specific general functions.
3
4     Note that mlh prepended _mcs51_ on the static functions.  Makes
5     it easier to set a breakpoint using the debugger.
6 */
7 #include "common.h"
8 #include "main.h"
9 #include "ralloc.h"
10 #include "gen.h"
11
12 static char _defaultRules[] =
13 {
14 #include "peeph.rul"
15 };
16
17 /* list of key words used by msc51 */
18 static char *_mcs51_keywords[] =     {
19     "at",
20     "bit",
21     "code",
22     "critical",
23     "data",
24     "far",
25     "idata",
26     "interrupt",
27     "near",
28     "pdata",
29     "reentrant",
30     "sfr",
31     "sbit",
32     "using",
33     "xdata",
34     "_data",
35     "_code",
36     "_generic",
37     "_near",
38     "_xdata",
39     "_pdata",
40     "_idata",
41     NULL
42 };
43
44
45 void mcs51_assignRegisters (eBBlock **ebbs, int count);
46
47 static bool _mcs51_parseOptions(int *pargc, char **argv, int *i)
48 {
49     /* TODO: allow port-specific command line options to specify
50      * segment names here.
51      */
52     return FALSE;
53 }
54
55 static void _mcs51_finaliseOptions(void)
56 {
57     /* Hack-o-matic: if we are using the flat24 model,
58      * adjust pointer sizes.
59      */
60     if (options.model == MODEL_FLAT24)
61     {
62         port->s.fptr_size = 3;
63         port->s.gptr_size = 4;
64         port->stack.isr_overhead++;   /* Will save dpx on ISR entry. */
65         #if 1
66         port->stack.call_overhead++;       /* This acounts for the extra byte 
67                                             * of return addres on the stack.
68                                             * but is ugly. There must be a 
69                                             * better way.
70                                             */
71         #endif
72         fReturn = fReturn390;
73         fReturnSize = 5;
74     } 
75 }
76
77 static void _mcs51_setDefaultOptions(void)
78 {
79 }
80
81 static const char *_mcs51_getRegName(struct regs *reg)
82 {
83     if (reg)
84         return reg->name;
85     return "err";
86 }
87
88 static void _mcs51_genAssemblerPreamble(FILE *of)
89 {
90    if (options.model == MODEL_FLAT24)
91    {
92        fputs(".flat24 on\t\t; 24 bit flat addressing\n", of);
93        fputs("dpx = 0x93\t\t; dpx register unknown to assembler\n", of);
94
95    }
96 }
97
98 /* Generate interrupt vector table. */
99 static int _mcs51_genIVT(FILE *of, symbol **interrupts, int maxInterrupts)
100 {
101     int i;
102     
103     if (options.model != MODEL_FLAT24)
104     {
105         /* Let the default code handle it. */
106         return FALSE;
107     }
108     
109     fprintf (of, "\tajmp\t__sdcc_gsinit_startup\n");
110     
111     /* now for the other interrupts */
112     for (i = 0; i < maxInterrupts; i++) 
113     {
114         if (interrupts[i])
115         {
116             fprintf(of, "\tljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
117         }
118         else
119         {
120             fprintf(of, "\treti\n\t.ds\t7\n");
121         }
122     }
123     
124     return TRUE;
125 }
126
127 /** $1 is always the basename.
128     $2 is always the output file.
129     $3 varies
130     $l is the list of extra options that should be there somewhere...
131     MUST be terminated with a NULL.
132 */
133 static const char *_linkCmd[] = {
134     "aslink", "-nf", "$1", NULL
135 };
136
137 static const char *_asmCmd[] = {
138     "asx8051", "-plosgffc", "$1.asm", NULL
139 };
140
141 /* Globals */
142 PORT mcs51_port = {
143     "mcs51",
144     "MCU 8051",                 /* Target name */
145     {
146         TRUE,                   /* Emit glue around main */
147     },
148     {   
149         _asmCmd,
150         "-plosgffc",            /* Options with debug */
151         "-plosgff",             /* Options without debug */
152     },
153     {
154         _linkCmd
155     },
156     {
157         _defaultRules
158     },
159     {
160         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
161         1, 1, 2, 4, 1, 2, 3, 1, 4, 4
162     },
163     {
164         "XSEG    (XDATA)",
165         "STACK   (DATA)",
166         "CSEG    (CODE)",
167         "DSEG    (DATA)",
168         "ISEG    (DATA)",
169         "XSEG    (XDATA)",
170         "BSEG    (BIT)",
171         "RSEG    (DATA)",
172         "GSINIT  (CODE)",
173         "OSEG    (OVR,DATA)"
174     },
175     { 
176         +1, 1, 4, 1, 1
177     },
178     /* mcs51 has an 8 bit mul */
179     {
180         1
181     },
182     NULL,
183     _mcs51_parseOptions,
184     _mcs51_finaliseOptions,
185     _mcs51_setDefaultOptions,
186     mcs51_assignRegisters,
187     _mcs51_getRegName ,
188     _mcs51_keywords,
189     _mcs51_genAssemblerPreamble,
190     _mcs51_genIVT
191 };
192