]> git.sur5r.net Git - cc65/blob - src/ld65/target.c
Fix problematic code. Use more stuff from the shared modules.
[cc65] / src / ld65 / target.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                               target.c                                    */
4 /*                                                                           */
5 /*                 Target system support for the ld65 linker                 */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2000 Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@musoftware.de                                            */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40
41 #include "error.h"
42 #include "global.h"
43 #include "binfmt.h"
44 #include "scanner.h"
45 #include "config.h"
46 #include "target.h"
47
48
49
50 /*****************************************************************************/
51 /*                           Target configurations                           */
52 /*****************************************************************************/
53
54
55
56 static const char CfgNone [] =
57     "MEMORY {"
58         "RAM: start = %S, size = $10000, file = %O;"
59     "}"
60     "SEGMENTS {"
61         "CODE: load = RAM, type = rw;"
62         "RODATA: load = RAM, type = rw;"
63         "DATA: load = RAM, type = rw;"
64         "BSS: load = RAM, type = bss, define = yes;"
65     "}";
66
67 static const char CfgAtari [] =
68     "MEMORY {"
69         "HEADER: start = $0000, size = $6, file = %O;"
70         "RAM: start = $1F00, size = $6100, file = %O;"
71     "}"
72     "SEGMENTS {"
73         "EXEHDR: load = HEADER, type = wprot;"
74         "CODE: load = RAM, type = wprot, define = yes;"
75         "RODATA: load = RAM, type = wprot;"
76         "DATA: load = RAM, type = rw;"
77         "BSS: load = RAM, type = bss, define = yes;"
78         "AUTOSTRT: load = RAM, type = wprot;"
79     "}";
80
81 static const char CfgC64 [] =
82     "MEMORY {"
83         "RAM: start = $7FF, size = $c801, file = %O;"
84     "}"
85     "SEGMENTS {"
86         "CODE: load = RAM, type = wprot;"
87         "RODATA: load = RAM, type = wprot;"
88         "DATA: load = RAM, type = rw;"
89         "BSS: load = RAM, type = bss, define = yes;"
90     "}";
91
92 static const char CfgC128 [] =
93     "MEMORY {"
94         "RAM: start = $1bff, size = $a401, file = %O;"
95     "}"
96     "SEGMENTS {"
97         "CODE: load = RAM, type = wprot;"
98         "RODATA: load = RAM, type = wprot;"
99         "DATA: load = RAM, type = rw;"
100         "BSS: load = RAM, type = bss, define = yes;"
101     "}";
102
103 static const char CfgAce [] =
104     "";
105
106 static const char CfgPlus4 [] =
107     "MEMORY {"
108         "RAM: start = $0fff, size = $7001, file = %O;"
109     "}"
110     "SEGMENTS {"
111         "CODE: load = RAM, type = wprot;"
112         "RODATA: load = RAM, type = wprot;"
113         "DATA: load = RAM, type = rw;"
114         "BSS: load = RAM, type = bss, define = yes;"
115     "}";
116
117 static const char CfgCBM610 [] =
118     "MEMORY {"
119         "RAM: start = $0001, size = $FFF0, file = %O;"
120     "}"
121     "SEGMENTS {"
122         "CODE: load = RAM, type = wprot;"
123         "RODATA: load = RAM, type = wprot;"
124         "DATA: load = RAM, type = rw;"
125         "BSS: load = RAM, type = bss, define = yes;"
126     "}";
127
128 static const char CfgPET [] =
129     "MEMORY {"
130         "RAM: start = $03FF, size = $7BFF, file = %O;"
131     "}"
132     "SEGMENTS {"
133         "CODE: load = RAM, type = wprot;"
134         "RODATA: load = RAM, type = wprot;"
135         "DATA: load = RAM, type = rw;"
136         "BSS: load = RAM, type = bss, define = yes;"
137     "}";
138
139 static const char CfgNES [] =
140     "MEMORY {"
141         "RAM: start = $0200, size = $0600, file = \"\";"
142         "ROM: start = $8000, size = $8000, file = %O;"
143     "}"
144     "SEGMENTS {"
145         "CODE: load = ROM, type = ro;"
146         "RODATA: load = ROM, type = ro;"
147         "DATA: load = ROM, run = RAM, type = rw, define = yes;"
148         "BSS: load = RAM, type = bss, define = yes;"
149         "VECTORS: load = ROM, type = ro, start = $FFFA;"
150     "}";
151
152 static const char CfgLunix [] =
153     "MEMORY {"
154         "COMBINED: start = $0000, size = $FFFF, file = %O;"
155         "ZEROPAGE: start = $0000, size = $0100, file = %O;"
156     "}"
157     "SEGMENTS {"
158         "CODE: load = COMBINED, type = wprot;"
159         "RODATA: load = COMBINED, type = wprot;"
160         "DATA: load = COMBINED, type = rw, define = yes;"
161         "BSS: load = COMBINED, type = bss, define = yes;"
162         "ZEROPAGE: load = ZEROPAGE, type = zp;"
163     "}"
164     "FILES {"
165         "%O: format = o65;"
166     "}"
167     "FORMATS {"
168         "o65: os = lunix, type = small,"
169               "extsym = \"LUNIXKERNAL\", extsym = \"LIB6502\";"
170     "}";
171
172 static const char CfgOSA65 [] =
173     "MEMORY {"
174         "COMBINED: start = $0000, size = $FFFF, file = %O;"
175         "ZEROPAGE: start = $0000, size = $0100, file = %O;"
176     "}"
177     "SEGMENTS {"
178         "CODE: load = COMBINED, type = wprot;"
179         "RODATA: load = COMBINED, type = wprot;"
180         "DATA: load = COMBINED, type = rw, define = yes;"
181         "BSS: load = COMBINED, type = bss, define = yes;"
182         "ZEROPAGE: load = ZEROPAGE, type = zp;"
183     "}"
184     "FILES {"
185         "%O: format = o65;"
186     "}"
187     "FORMATS {"
188         "o65: os = osa65, type = small,"
189               "extsym = \"OSA2KERNAL\", extsym = \"LIB6502\";"
190     "}";
191
192 static const char CfgApple2 [] =
193     "MEMORY {"
194         "RAM: start = $800, size = $8E00, file = %O;"
195     "}"
196     "SEGMENTS { "
197         "CODE: load = RAM, type = ro;"
198         "RODATA: load = RAM, type = ro;"
199         "DATA: load = RAM, type = rw;"
200         "BSS: load = RAM, type = bss, define = yes;"
201     "}";
202
203 static const char CfgGeos [] =
204     "MEMORY {"
205         "HEADER: start = $204, size = 508, file = %O;"
206         "RAM: start = $400, size = $7C00, file = %O;"
207     "}"
208     "SEGMENTS { "
209         "HEADER: load = HEADER, type = ro;"
210         "CODE: load = RAM, type = ro;"
211         "RODATA: load = RAM, type = ro;"
212         "DATA: load = RAM, type = rw;"
213         "BSS: load = RAM, type = bss, define = yes;"
214     "}";
215
216
217
218 /*****************************************************************************/
219 /*                                   Data                                    */
220 /*****************************************************************************/
221
222
223
224 /* Supported systems */
225 #define TGT_NONE         0
226 #define TGT_ATARI        1              /* Atari 8 bit machines */
227 #define TGT_C64          2
228 #define TGT_C128         3
229 #define TGT_ACE          4
230 #define TGT_PLUS4        5
231 #define TGT_CBM610       6              /* CBM 600/700 family */
232 #define TGT_PET          7              /* CBM PET family */
233 #define TGT_NES          8              /* Nintendo Entertainment System */
234 #define TGT_LUNIX        9
235 #define TGT_OSA65       10
236 #define TGT_APPLE2      11
237 #define TGT_GEOS        12
238 #define TGT_COUNT       13              /* Count of supported systems */
239
240
241
242 /* Structure describing a target */
243 typedef struct TargetCfg_ TargetCfg;
244 struct TargetCfg_ {
245     const char*         Name;           /* Name of the system */
246     unsigned char       BinFmt;         /* Default binary format for the target */
247     const char*         Cfg;            /* Pointer to configuration */
248 };
249
250 static const TargetCfg Targets [TGT_COUNT] = {
251     {   "none",   BINFMT_BINARY,        CfgNone         },
252     {   "atari",  BINFMT_BINARY,        CfgAtari        },
253     {   "c64",    BINFMT_BINARY,        CfgC64          },
254     {   "c128",   BINFMT_BINARY,        CfgC128         },
255     {   "ace",    BINFMT_BINARY,        CfgAce          },
256     {   "plus4",  BINFMT_BINARY,        CfgPlus4        },
257     {   "cbm610", BINFMT_BINARY,        CfgCBM610       },
258     {   "pet",    BINFMT_BINARY,        CfgPET          },
259     {   "nes",    BINFMT_BINARY,        CfgNES          },
260     {   "lunix",  BINFMT_O65,           CfgLunix        },
261     {   "osa65",  BINFMT_O65,           CfgOSA65        },
262     {   "apple2", BINFMT_BINARY,        CfgApple2       },
263     {   "geos",   BINFMT_BINARY,        CfgGeos         },
264 };
265
266 /* Selected target system type */
267 static const TargetCfg* Target;
268
269
270
271 /*****************************************************************************/
272 /*                                   Code                                    */
273 /*****************************************************************************/
274
275
276
277 static int StrICmp (const char* S1, const char* S2)
278 /* Compare two strings case insensitive */
279 {
280     int Diff = 0;
281     while (1) {
282         Diff = tolower (*S1) - tolower (*S2);
283         if (Diff != 0 || *S1 == '\0') {
284             return Diff;
285         }
286         ++S1;
287         ++S2;
288     }
289 }
290
291
292
293 static int TgtMap (const char* Name)
294 /* Map a target name to a system code. Return -1 in case of an error */
295 {
296     unsigned I;
297
298     /* Check for a numeric target */
299     if (isdigit (*Name)) {
300         int Target = atoi (Name);
301         if (Target >= 0 && Target < TGT_COUNT) {
302             return Target;
303         }
304     }
305
306     /* Check for a target string */
307     for (I = 0; I < TGT_COUNT; ++I) {
308         if (StrICmp (Targets [I].Name, Name) == 0) {
309             return I;
310         }
311     }
312
313     /* Not found */
314     return -1;
315 }
316
317
318
319 void TgtSet (const char* T)
320 /* Set the target system, initialize internal stuff for this target */
321 {
322     /* Map the target to a number */
323     int TgtNum = TgtMap (T);
324     if (TgtNum == -1) {
325         Error ("Invalid target system: %s", T);
326     }
327     Target = &Targets [TgtNum];
328
329     /* Set the target data */
330     DefaultBinFmt = Target->BinFmt;
331     CfgSetBuf (Target->Cfg);
332 }
333
334
335
336 void TgtPrintList (FILE* F)
337 /* Print a list of the available target systems */
338 {
339     unsigned I;
340
341     /* Print a header */
342     fprintf (F, "Available targets:\n");
343
344     /* Print a list of the target systems */
345     for (I = 0; I < TGT_COUNT; ++I) {
346         fprintf (F, "  %s\n", Targets [I].Name);
347     }
348 }
349
350
351