* Fixed up multi bank support
[fw/sdcc] / src / z80 / main.c
1 #include "z80.h"
2
3 static char _z80_defaultRules[] =
4 {
5 #include "peeph.rul"
6 #include "peeph-z80.rul"
7 };
8
9 static char _gbz80_defaultRules[] =
10 {
11 #include "peeph.rul"
12 #include "peeph-gbz80.rul"
13 };
14
15 Z80_OPTS z80_opts;
16
17 static struct {
18     bool fsetAsmType;
19 } _G;
20
21 static char *_keywords[] = { NULL };
22
23 extern PORT gbz80_port;
24 extern PORT z80_port;
25
26 #include "mappings.i"
27
28 static void _z80_init(void)
29 {
30     z80_opts.sub = SUB_Z80;
31     asm_addTree(&_asxxxx_z80);
32 }
33
34 static void _gbz80_init(void)
35 {
36     z80_opts.sub = SUB_GBZ80;
37 }
38
39 static int regParmFlg = 0; /* determine if we can register a parameter */
40
41 static void _reset_regparm()
42 {
43     regParmFlg = 0;
44 }
45
46 static int _reg_parm(link *l)
47 {
48         /* for this processor it is simple
49        can pass only the first parameter in a register */
50     if (regParmFlg)
51         return 0;
52
53     regParmFlg = 1;
54     return 1;
55
56 }
57
58 static int _process_pragma(const char *sz)
59 {
60     printf("Got pragma \"%s\"\n", sz);
61     return 1;
62 }
63
64 static bool _parseOptions(int *pargc, char **argv, int *i)
65 {
66     if (argv[*i][0] == '-') {
67         if (argv[*i][1] == 'b' && IS_GB) {
68             int bank = atoi(argv[*i] + 3);
69             char buffer[128];
70             switch (argv[*i][2]) {
71             case 'o':
72                 /* ROM bank */
73                 sprintf(buffer, "_CODE_%u", bank);
74                 gbz80_port.mem.code_name = gc_strdup(buffer);
75                 return TRUE;
76             case 'a':
77                 /* RAM bank */
78                 sprintf(buffer, "_DATA_%u", bank);
79                 gbz80_port.mem.data_name = gc_strdup(buffer);
80                 return TRUE;
81             }
82         }
83         else if (!strncmp(argv[*i], "--asm=", 6)) {
84             if (!strcmp(argv[*i], "--asm=rgbds")) {
85                 asm_addTree(&_rgbds_gb);
86                 _G.fsetAsmType = TRUE;
87                 return TRUE;
88             }
89             else if (!strcmp(argv[*i], "--asm=asxxxx")) {
90                 asm_addTree(&_asxxxx_gb);
91                 _G.fsetAsmType = TRUE;
92                 return TRUE;
93             }
94         }
95     }
96     return FALSE;
97 }
98
99 static void _finaliseOptions(void)
100 {
101     port->mem.default_local_map = data;
102     port->mem.default_globl_map = data;
103     if (!_G.fsetAsmType && IS_GB)
104         asm_addTree(&_asxxxx_gb);
105 }
106
107 static void _setDefaultOptions(void)
108 {    
109     options.genericPtr = 1;   /* default on */
110     options.nopeep    = 0;
111     options.stackAuto = 1;
112     options.mainreturn = 1;
113     options.noregparms = 1;
114     options.nodebug = 1;
115     /* first the options part */
116     options.intlong_rent = 1;
117
118     optimize.global_cse = 1;    
119     optimize.label1 = 1;
120     optimize.label2 = 1;
121     optimize.label3 = 1;
122     optimize.label4 = 1;    
123     optimize.loopInvariant = 1;
124     optimize.loopInduction = 0;
125 }
126
127 static const char *_getRegName(struct regs *reg)
128 {
129     if (reg)
130         return reg->name;
131     assert(0);
132     return "err";
133 }
134
135 /** $1 is always the basename.
136     $2 is always the output file.
137     $3 varies
138     $l is the list of extra options that should be there somewhere...
139     MUST be terminated with a NULL.
140 */
141 static const char *_z80_linkCmd[] = {
142     "link-z80", "-nf", "$1", NULL
143 };
144
145 static const char *_z80_asmCmd[] = {
146     "as-z80", "-plosgff", "$1.o", "$1.asm", NULL
147 };
148
149 /** $1 is always the basename.
150     $2 is always the output file.
151     $3 varies
152     $l is the list of extra options that should be there somewhere...
153     MUST be terminated with a NULL.
154 */
155 static const char *_gbz80_linkCmd[] = {
156     "link-gbz80", "-nf", "$1", NULL
157 };
158
159 static const char *_gbz80_asmCmd[] = {
160     "as-gbz80", "-plosgff", "$1.o", "$1.asm", NULL
161 };
162
163 /* Globals */
164 PORT z80_port = {
165     "z80",
166     "Zilog Z80",                /* Target name */
167     {
168         FALSE,
169     },
170     {   
171         _z80_asmCmd,
172         "-plosgff",             /* Options with debug */
173         "-plosgff",             /* Options without debug */
174     },
175     {
176         _z80_linkCmd
177     },
178     {
179         _z80_defaultRules
180     },
181     {
182         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
183         1, 1, 2, 4, 2, 2, 2, 1, 4, 4
184     },
185     {
186         "_XSEG",
187         "_STACK",
188         "_CODE",
189         "_DATA",
190         "_ISEG",
191         "_XSEG",
192         "_BSEG",
193         "_RSEG",
194         "_GSINIT",
195         "_OVERLAY",
196         "_GSFINAL",
197         NULL,
198         NULL,
199         1
200     },
201     { 
202         -1, 0, 0, 8, 0
203     },
204     /* Z80 has no native mul/div commands */
205     {  
206         0
207     },
208     _z80_init,
209     _parseOptions,
210     _finaliseOptions,
211     _setDefaultOptions,
212     z80_assignRegisters,
213     _getRegName,
214     _keywords,
215     0,  /* no assembler preamble */
216     0,  /* no local IVT generation code */
217     _reset_regparm,
218     _reg_parm
219 };
220
221 /* Globals */
222 PORT gbz80_port = {
223     "gbz80",
224     "Gameboy Z80-like",         /* Target name */
225     {
226         FALSE,
227     },
228     {   
229         _gbz80_asmCmd,
230         "-plosgff",             /* Options with debug */
231         "-plosgff",             /* Options without debug */
232     },
233     {
234         _gbz80_linkCmd
235     },
236     {
237         _gbz80_defaultRules
238     },
239     {
240         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
241         1, 1, 2, 4, 2, 2, 2, 1, 4, 4
242     },
243     {
244         "_XSEG",
245         "_STACK",
246         "_CODE",
247         "_DATA",
248         "_ISEG",
249         "_XSEG",
250         "_BSEG",
251         "_RSEG",
252         "_GSINIT",
253         "_OVERLAY",
254         "_GSFINAL",
255         NULL,
256         NULL,
257         1
258     },
259     { 
260         -1, 0, 0, 4, 0
261     },
262     /* gbZ80 has no native mul/div commands */
263     {  
264         0
265     },
266     _gbz80_init,
267     _parseOptions,
268     _finaliseOptions,
269     _setDefaultOptions,
270     z80_assignRegisters,
271     _getRegName,
272     _keywords,
273     0,  /* no assembler preamble */
274     0,  /* no local IVT generation code */
275     _reset_regparm,
276     _reg_parm,
277     _process_pragma
278 };