10 bit stack mode: almost working...
[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     if (options.model) {
77         port->mem.default_local_map = xdata;
78         port->mem.default_globl_map = xdata;
79     } else {
80         port->mem.default_local_map = data;
81         port->mem.default_globl_map = data;
82     }
83     
84     if (options.stack10bit)
85     {
86         if (options.model != MODEL_FLAT24)
87         {
88             fprintf(stderr, 
89                     "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
90             fprintf(stderr, "\t10 bit stack mode disabled.\n");
91             options.stack10bit = 0;
92         }
93         else
94         {
95             /* Fixup the memory map for the stack; it is now in
96              * far space and requires a FPOINTER to access it.
97              */
98             istack->fmap = 1;
99             istack->ptrType = FPOINTER; 
100         }
101     }
102 }
103
104 static void _mcs51_setDefaultOptions(void)
105 {
106 }
107
108 static const char *_mcs51_getRegName(struct regs *reg)
109 {
110     if (reg)
111         return reg->name;
112     return "err";
113 }
114
115 static void _mcs51_genAssemblerPreamble(FILE *of)
116 {
117    if (options.model == MODEL_FLAT24)
118    {
119        fputs(".flat24 on\t\t; 24 bit flat addressing\n", of);
120        fputs("dpx = 0x93\t\t; dpx register unknown to assembler\n", of);
121        fputs("dps = 0x86\t\t; dps register unknown to assembler\n", of);
122        fputs("dpl1 = 0x84\t\t; dpl1 register unknown to assembler\n", of);
123        fputs("dph1 = 0x85\t\t; dph1 register unknown to assembler\n", of);
124        fputs("dpx1 = 0x95\t\t; dpx1 register unknown to assembler\n", of);
125    }
126 }
127
128 /* Generate interrupt vector table. */
129 static int _mcs51_genIVT(FILE *of, symbol **interrupts, int maxInterrupts)
130 {
131     int i;
132     
133     if (options.model != MODEL_FLAT24)
134     {
135         /* Let the default code handle it. */
136         return FALSE;
137     }
138     
139     fprintf (of, "\tajmp\t__sdcc_gsinit_startup\n");
140     
141     /* now for the other interrupts */
142     for (i = 0; i < maxInterrupts; i++) 
143     {
144         if (interrupts[i])
145         {
146             fprintf(of, "\tljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
147         }
148         else
149         {
150             fprintf(of, "\treti\n\t.ds\t7\n");
151         }
152     }
153     
154     return TRUE;
155 }
156
157 /** $1 is always the basename.
158     $2 is always the output file.
159     $3 varies
160     $l is the list of extra options that should be there somewhere...
161     MUST be terminated with a NULL.
162 */
163 static const char *_linkCmd[] = {
164     "aslink", "-nf", "$1", NULL
165 };
166
167 static const char *_asmCmd[] = {
168     "asx8051", "-plosgffc", "$1.asm", NULL
169 };
170
171 /* Globals */
172 PORT mcs51_port = {
173     "mcs51",
174     "MCU 8051",                 /* Target name */
175     {
176         TRUE,                   /* Emit glue around main */
177     },
178     {   
179         _asmCmd,
180         "-plosgffc",            /* Options with debug */
181         "-plosgff",             /* Options without debug */
182     },
183     {
184         _linkCmd
185     },
186     {
187         _defaultRules
188     },
189     {
190         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
191         1, 1, 2, 4, 1, 2, 3, 1, 4, 4
192     },
193     {
194         "XSEG    (XDATA)",
195         "STACK   (DATA)",
196         "CSEG    (CODE)",
197         "DSEG    (DATA)",
198         "ISEG    (DATA)",
199         "XSEG    (XDATA)",
200         "BSEG    (BIT)",
201         "RSEG    (DATA)",
202         "GSINIT  (CODE)",
203         "OSEG    (OVR,DATA)",
204         "GSFINAL (CODE)",
205         NULL,
206         NULL
207     },
208     { 
209         +1, 1, 4, 1, 1
210     },
211     /* mcs51 has an 8 bit mul */
212     {
213         1
214     },
215     NULL,
216     _mcs51_parseOptions,
217     _mcs51_finaliseOptions,
218     _mcs51_setDefaultOptions,
219     mcs51_assignRegisters,
220     _mcs51_getRegName ,
221     _mcs51_keywords,
222     _mcs51_genAssemblerPreamble,
223     _mcs51_genIVT
224 };
225