1 /*-------------------------------------------------------------------------
3 device.c - Accomodates subtle variations in PIC16 devices
5 Written By - Scott Dattalo scott@dattalo.com
6 Ported to PIC16 By - Martin Dubuc m.dubuc@rogers.com
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 -------------------------------------------------------------------------*/
25 VR - Began writing code to make PIC16 C source files independent from
26 the header file (created by the inc2h.pl)
28 - adding maximum RAM memory into PIC_Device structure
34 #include "common.h" // Include everything in the SDCC src directory
44 static PIC16_device Pics16[] = {
46 // {"p18f242", "18f242", "pic18f242", "f242"}, // aliases
50 // { 0xf80, 0xfff }, /* PIC18F242 range of SFR's */
52 // /* PIC18F242 configuration words */
55 // { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
56 // { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
57 // { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
58 // { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
59 // { 0x40, 0, 0xff } /* d */ }
64 {"p18f242", "18f242", "pic18f242", "f242"},
69 { 0xf80, 0xfff }, /* PIC18F242 range of SFR's */
71 /* PIC18F242 configuration words */
74 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
75 { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
76 { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
77 { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
78 { 0x40, 0, 0xff } /* d */ }
82 {"p18f248", "18f248", "pic18f248", "f248"},
87 { 0xf00, 0xfff }, /* PIC18F248 range of SFR's */
89 /* PIC18F248 configuration words */
92 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
93 { -1, 0, 0xff } /* 4 */ , { -1, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
94 { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
95 { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
96 { 0x40, 0, 0xff } /* d */ }
100 {"p18f252", "18f252", "pic18f252", "f252"},
105 { 0xf80, 0xfff }, /* PIC18F252 range of SFR's */
107 /* PIC18F252 configuration words */
110 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
111 { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
112 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
113 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
114 { 0x40, 0, 0xff } /* d */ }
118 {"p18f258", "18f258", "pic18f258", "f258"},
123 { 0xf00, 0xfff }, /* PIC18F258 range of SFR's */
125 /* PIC18F258 configuration words */
128 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
129 { -1, 0, 0xff } /* 4 */ , { -1, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
130 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
131 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
132 { 0x40, 0, 0xff } /* d */ }
136 {"p18f442", "18f442", "pic18f442", "f442"},
141 { 0xf80, 0xfff }, /* PIC18F442 range of SFR's */
143 /* PIC18F442 configuration words */
146 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
147 { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
148 { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
149 { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
150 { 0x40, 0, 0xff } /* d */ }
154 {"p18f448", "18f448", "pic18f448", "f448"},
159 { 0xf00, 0xfff }, /* PIC18F448 range of SFR's */
161 /* PIC18F448 configuration words */
164 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
165 { -1, 0, 0xff } /* 4 */ , { -1, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
166 { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
167 { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
168 { 0x40, 0, 0xff } /* d */ }
172 {"p18f452", "18f452", "pic18f452", "f452"},
177 { 0xf80, 0xfff }, /* PIC18F452 range of SFR's */
179 /* PIC18F452 configuration words */
182 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
183 { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
184 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
185 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
186 { 0x40, 0, 0xff } /* d */ }
190 {"p18f458", "18f458", "pic18f458", "f458"},
195 { 0xf00, 0xfff }, /* PIC18F458 range of SFR's */
197 /* PIC18F458 configuration words */
200 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
201 { -1, 0, 0xff } /* 4 */ , { -1, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
202 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
203 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
204 { 0x40, 0, 0xff } /* d */ }
208 {"p18f1220", "18f1220", "pic18f1220", "f1220"},
213 { 0xf80, 0xfff }, /* PIC18F1220 range of SFR's */
215 /* PIC18F1220 configuration words */
218 { { 0xcf, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ ,
219 { -1, 0, 0xff } /* 4 */ , { 0x80, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
220 { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
221 { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
222 { 0x40, 0, 0xff } /* d */ }
226 {"p18f2220", "18f2220", "pic18f2220", "f2220"},
231 { 0xf80, 0xfff }, /* PIC18F2220 range of SFR's */
233 /* PIC18F2220 configuration words */
236 { { 0xcf, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ ,
237 { -1, 0, 0xff } /* 4 */ , { 0x83, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
238 { -1, 0, 0xff } /* 7 */ , { 0x03, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
239 { 0x03, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x03, 0, 0xff } /* c */ ,
240 { 0x40, 0, 0xff } /* d */ }
244 {"p18f6520", "18f6520", "pic18f6520", "f6520"},
249 { 0xf6b, 0xfff }, /* PIC18F6520 range of SFR's */
251 /* PIC18F6520 configuration words */
254 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
255 { 0x80, 0, 0xff } /* 4 */ , { 0x88, 0, 0xff } /* 5 */ , { -1, 0, 0xff } /* 6 */ ,
256 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
257 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
258 { 0x40, 0, 0xff } /* d */ }
262 {"p18f6620", "18f6620", "pic18f6620", "f6620"},
267 { 0xf6b, 0xfff }, /* PIC18F6620 range of SFR's */
269 /* PIC18F6620 configuration words */
272 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
273 { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
274 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
275 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
276 { 0x40, 0, 0xff } /* d */ }
280 {"p18f6680", "18f6680", "pic18f6680", "f6680"},
285 { 0xf00, 0xfff }, /* PIC18F6680 range of SFR's */
287 /* PIC18F6680 configuration words */
290 { { 0x2f, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ ,
291 { -1, 0, 0xff } /* 4 */ , { 0x83, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
292 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
293 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
294 { 0x40, 0, 0xff } /* d */ }
298 {"p18f6720", "18f6720", "pic18f6720", "f6720"},
303 { 0xf6b, 0xfff }, /* PIC18F6720 range of SFR's */
305 /* PIC18F6720 configuration words */
308 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
309 { -1, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
310 { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
311 { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ ,
312 { 0x40, 0, 0xff } /* d */ }
316 {"p18f8520", "18f8520", "pic18f8520", "f8520"},
321 { 0xf6b, 0xfff }, /* PIC18F8520 range of SFR's */
323 /* PIC18F8520 configuration words */
326 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
327 { 0x83, 0, 0xff } /* 4 */ , { 0x88, 0, 0xff } /* 5 */ , { -1, 0, 0xff } /* 6 */ ,
328 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
329 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
330 { 0x40, 0, 0xff } /* d */ }
334 {"p18f8620", "18f8620", "pic18f8620", "f8620"},
339 { 0xf6b, 0xfff }, /* PIC18F8620 range of SFR's */
341 /* PIC18F8620 configuration words */
344 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
345 { 0x83, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
346 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
347 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
348 { 0x40, 0, 0xff } /* d */ }
352 {"p18f8680", "18f8680", "pic18f8680", "f8680"},
357 { 0xf00, 0xfff }, /* PIC18F8680 range of SFR's */
359 /* PIC18F8680 configuration words */
362 { { 0x2f, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x1f, 0, 0xff } /* 3 */ ,
363 { 0x83, 0, 0xff } /* 4 */ , { 0x83, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
364 { -1, 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
365 { 0x0f, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ ,
366 { 0x40, 0, 0xff } /* d */ }
370 {"p18f8720", "18f8720", "pic18f8720", "f8720"},
375 { 0xf6b, 0xfff }, /* PIC18F8720 range of SFR's */
377 /* PIC18F8720 configuration words */
380 { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , { 0x0f, 0, 0xff } /* 3 */ ,
381 { 0x83, 0, 0xff } /* 4 */ , { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ ,
382 { -1, 0, 0xff } /* 7 */ , { 0xff, 0, 0xff } /* 8 */ , { 0xc0, 0, 0xff } /* 9 */ ,
383 { 0xff, 0, 0xff } /* a */ , { 0xe0, 0, 0xff } /* b */ , { 0xff, 0, 0xff } /* c */ ,
384 { 0x40, 0, 0xff } /* d */ }
390 static int num_of_supported_PICS = sizeof(Pics16)/sizeof(PIC16_device);
392 #define DEFAULT_PIC "452"
394 PIC16_device *pic16=NULL;
395 unsigned int stackPos = 0;
397 extern regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop);
399 void pic16_setMaxRAM(int size)
401 pic16->maxRAMaddress = size;
402 stackPos = pic16->RAMsize-1;
404 if (pic16->maxRAMaddress < 0) {
405 fprintf(stderr, "invalid \"#pragma maxram 0x%x\" setting\n",
406 pic16->maxRAMaddress);
411 extern char *iComments2;
413 void pic16_dump_equates(FILE *of, set *equs)
417 r = setFirstItem(equs);
420 fprintf(of, "%s", iComments2);
421 fprintf(of, ";\tEquates to used internal registers\n");
422 fprintf(of, "%s", iComments2);
424 for(; r; r = setNextItem(equs)) {
425 fprintf(of, "%s\tequ\t0x%02x\n", r->name, r->address);
430 int regCompare(const void *a, const void *b)
432 const regs *const *i = a;
433 const regs *const *j = b;
435 /* sort primarily by the address */
436 if( (*i)->address > (*j)->address)return 1;
437 if( (*i)->address < (*j)->address)return -1;
439 /* and secondarily by size */
440 /* register size sorting may have strange results use with care */
441 if( (*i)->size > (*j)->size)return 1;
442 if( (*i)->size < (*j)->size)return -1;
444 /* finally if in same address and same size sort by name */
445 return (strcmp( (*i)->name, (*j)->name));
450 int symCompare(const void *a, const void *b)
452 const symbol *const *i = a;
453 const symbol *const *j = b;
455 /* sort primarily by the address */
456 if( SPEC_ADDR((*i)->etype) > SPEC_ADDR((*j)->etype))return 1;
457 if( SPEC_ADDR((*i)->etype) < SPEC_ADDR((*j)->etype))return -1;
459 /* and secondarily by size */
460 /* register size sorting may have strange results use with care */
461 if( getSize((*i)->etype) > getSize((*j)->etype))return 1;
462 if( getSize((*i)->etype) < getSize((*j)->etype))return -1;
464 /* finally if in same address and same size sort by name */
465 return (strcmp( (*i)->rname, (*j)->rname));
470 void pic16_dump_usection(FILE *of, set *section, int fix)
472 static int abs_usection_no=0;
478 /* put all symbols in an array */
479 rlist = Safe_calloc(elementsInSet(section), sizeof(regs *));
481 for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) {
482 rlist[i] = rprev; i++;
486 if(rlist)free(rlist);
490 /* sort symbols according to their address */
491 qsort(rlist, i /*elementsInSet(section)*/, sizeof(regs *), regCompare);
494 fprintf(of, "\n\n\tudata\n");
495 for(r = setFirstItem(section); r; r = setNextItem(section)) {
496 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
503 init_addr = rlist[j]->address;
504 deb_addr = init_addr;
505 fprintf(of, "\n\nustat_%s_%02d\tudata\t0X%04X\n", moduleName, abs_usection_no++, init_addr);
509 if(j < i-1)r1 = rlist[j+1]; else r1 = NULL;
511 init_addr = r->address;
512 deb_addr = init_addr;
514 if((rprev && (init_addr > (rprev->address + rprev->size)))) {
515 fprintf(of, "\n\nustat_%s_%02d\tudata\t0X%04X\n", moduleName, abs_usection_no++, init_addr);
518 if(r1 && (init_addr == r1->address)) {
519 fprintf(of, "\n%s\tres\t0\n", r->name);
521 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
531 void pic16_dump_gsection(FILE *of, set *sections)
536 for(sname = setFirstItem(sections); sname; sname = setNextItem(sections)) {
537 fprintf(of, "\n\n%s\tudata\n", sname->name);
539 for(r=setFirstItem(sname->regsSet); r; r=setNextItem(sname->regsSet)) {
541 fprintf(stderr, "%s:%d emitting variable %s for section %s (%p)\n", __FILE__, __LINE__,
542 r->name, sname->name, sname);
544 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
550 /* forward declaration */
551 void pic16_printIval(symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
552 extern void pic16_pCodeConstString(char *name, char *value);
554 void pic16_dump_isection(FILE *of, set *section, int fix)
556 static int abs_isection_no=0;
561 /* put all symbols in an array */
562 slist = Safe_calloc(elementsInSet(section), sizeof(symbol *));
564 for(sprev = setFirstItem(section); sprev; sprev = setNextItem(section)) {
565 slist[i] = sprev; i++;
569 if(slist)free(slist);
573 /* sort symbols according to their address */
574 qsort(slist, i, sizeof(symbol *), symCompare);
579 fprintf(of, "\n\n\tidata\n");
580 for(s = setFirstItem(section); s; s = setNextItem(section)) {
583 fprintf(of, "%s", s->rname);
584 pic16_printIval(s, s->type, s->ival, 'f', (void *)of);
585 pic16_flushDB('f', (void *)of);
587 if (IS_ARRAY (s->type) && IS_CHAR (s->type->next)
588 && SPEC_CVAL (s->etype).v_char) {
590 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, s->rname);
591 pic16_pCodeConstString(s->rname , SPEC_CVAL (s->etype).v_char);
603 init_addr = SPEC_ADDR(slist[j]->etype);
604 fprintf(of, "\n\nistat_%s_%02d\tidata\t0X%04X\n", moduleName, abs_isection_no++, init_addr);
608 if(j < i-1)s1 = slist[j+1]; else s1 = NULL;
610 init_addr = SPEC_ADDR(s->etype);
612 if(sprev && (init_addr > (SPEC_ADDR(sprev->etype) + getSize(sprev->etype)))) {
613 fprintf(of, "\nistat_%s_%02d\tidata\t0X%04X\n", moduleName, abs_isection_no++, init_addr);
617 fprintf(of, "%s", s->rname);
618 pic16_printIval(s, s->type, s->ival, 'f', (void *)of);
619 pic16_flushDB('f', (void *)of);
621 if (IS_ARRAY (s->type) && IS_CHAR (s->type->next)
622 && SPEC_CVAL (s->etype).v_char) {
624 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, s->rname);
625 pic16_pCodeConstString(s->rname , SPEC_CVAL (s->etype).v_char);
639 void pic16_dump_int_registers(FILE *of, set *section)
645 /* put all symbols in an array */
646 rlist = Safe_calloc(elementsInSet(section), sizeof(regs *));
648 for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) {
649 rlist[i] = rprev; i++;
652 /* sort symbols according to their address */
653 qsort(rlist, elementsInSet(section), sizeof(regs *), regCompare);
656 if(rlist)free(rlist);
660 fprintf(of, "\n\n; Internal registers\n");
662 fprintf(of, "%s\tudata_ovr\t0x0000\n", ".registers");
663 for(r = setFirstItem(section); r; r = setNextItem(section))
664 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
670 #ifdef WORDS_BIGENDIAN
671 #define _ENDIAN(x) (3-x)
673 #define _ENDIAN(x) (x)
676 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
679 /*-----------------------------------------------------------------*
680 * void pic16_list_valid_pics(int ncols, int list_alias)
682 * Print out a formatted list of valid PIC devices
684 * ncols - number of columns in the list.
686 * list_alias - if non-zero, print all of the supported aliases
687 * for a device (e.g. F84, 16F84, etc...)
688 *-----------------------------------------------------------------*/
689 void pic16_list_valid_pics(int ncols, int list_alias)
695 list_alias = sizeof(Pics16[0].name) / sizeof(Pics16[0].name[0]);
697 /* decrement the column number if it's greater than zero */
698 ncols = (ncols > 1) ? ncols-1 : 4;
700 /* Find the device with the longest name */
701 for(i=0,longest=0; i<num_of_supported_PICS; i++) {
702 for(j=0; j<=list_alias; j++) {
703 k = strlen(Pics16[i].name[j]);
711 for(i=0; i < num_of_supported_PICS; i++) {
715 fprintf(stderr,"%s", Pics16[i].name[j]);
717 l = longest + 2 - strlen(Pics16[i].name[j]);
728 } while(++j<list_alias);
736 /*-----------------------------------------------------------------*
738 *-----------------------------------------------------------------*/
739 PIC16_device *pic16_find_device(char *name)
747 for(i = 0; i<num_of_supported_PICS; i++) {
749 for(j=0; j<PROCESSOR_NAMES; j++)
750 if(!STRCASECMP(Pics16[i].name[j], name) )
758 /*-----------------------------------------------------------------*
760 *-----------------------------------------------------------------*/
761 void pic16_init_pic(char *pic_type)
763 pic16 = pic16_find_device(pic_type);
767 fprintf(stderr, "'%s' was not found.\n", pic_type);
769 fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
771 fprintf(stderr,"Valid devices are:\n");
773 pic16_list_valid_pics(4,0);
777 // printf("PIC processor found and initialized: %s\n", pic_type);
778 pic16_setMaxRAM( 0xfff );
781 /*-----------------------------------------------------------------*
783 *-----------------------------------------------------------------*/
784 int pic16_picIsInitialized(void)
786 if(pic16 && pic16->maxRAMaddress > 0)
793 /*-----------------------------------------------------------------*
794 * char *pic16_processor_base_name(void) - Include file is derived from this.
795 *-----------------------------------------------------------------*/
796 char *pic16_processor_base_name(void)
802 return pic16->name[0];
805 #define DEBUG_CHECK 0
808 * return 1 if register wasn't found and added, 0 otherwise
810 int checkAddReg(set **set, regs *reg)
815 fprintf(stderr, "%s: about to insert REGister: %s ... ", __FUNCTION__, reg->name);
818 for(tmp = setFirstItem(*set); tmp; tmp = setNextItem(*set)) {
819 if(!strcmp(tmp->name, reg->name))break;
825 fprintf(stderr, "added\n");
831 fprintf(stderr, "already added\n");
836 int checkAddSym(set **set, symbol *sym)
841 fprintf(stderr, "%s: about to add SYMbol: %s ... ", __FUNCTION__, sym->name);
844 for(tmp = setFirstItem( *set ); tmp; tmp = setNextItem(*set)) {
845 if(!strcmp(tmp->name, sym->name))break;
851 fprintf(stderr, "added\n");
857 fprintf(stderr, "already added\n");
864 /*-----------------------------------------------------------------*
865 * void pic16_groupRegistersInSection - add each register to its *
866 * corresponding section *
867 *-----------------------------------------------------------------*/
868 void pic16_groupRegistersInSection(set *regset)
874 for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
876 // fprintf(stderr, "%s:%d group registers in section, reg: %s\n", __FILE__, __LINE__, reg->name);
879 && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
881 /* avoid grouping registers that have an initial value,
882 * they will be added later in idataSymSet */
883 if(reg->regop && (OP_SYMBOL(reg->regop)->ival && !OP_SYMBOL(reg->regop)->level))
887 fprintf(stderr, "%s:%d register %s alias:%d fix:%d ival=%i level=%i\n",
888 __FILE__, __LINE__, reg->name, reg->alias, reg->isFixed,
889 (reg->regop?(OP_SYMBOL(reg->regop)->ival?1:0):-1),
890 (reg->regop?(OP_SYMBOL(reg->regop)->level):-1) );
894 for(ssym=setFirstItem(sectSyms);ssym;ssym=setNextItem(sectSyms)) {
895 if(!strcmp(ssym->name, reg->name)) {
896 // fprintf(stderr, "%s:%d section found %s (%p) with var %s\n",
897 // __FILE__, __LINE__, ssym->section->name, ssym->section, ssym->name);
898 addSet(&ssym->section->regsSet, reg);
903 if(docontinue)continue;
905 // fprintf(stderr, "%s:%d reg: %s\n", __FILE__, __LINE__, reg->name);
907 if(reg->alias == 0x80) {
908 checkAddReg(&pic16_equ_data, reg);
911 checkAddReg(&pic16_fix_udata, reg);
914 if(reg->pc_type == PO_GPR_TEMP)
915 checkAddReg(&pic16_int_regs, reg);
917 checkAddReg(&pic16_rel_udata, reg);
927 /*-----------------------------------------------------------------*
928 * void pic16_assignConfigWordValue(int address, int value)
930 * All high performance RISC CPU PICs have seven config word starting
931 * at address 0x300000.
932 * This routine will assign a value to that address.
934 *-----------------------------------------------------------------*/
935 void pic16_assignConfigWordValue(int address, int value)
939 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart+1;i++) {
940 if((address == pic16->cwInfo.confAddrStart+i)
941 && (pic16->cwInfo.crInfo[i].mask != -1)) {
942 // fprintf(stderr, "setting location 0x%X to value 0x%x\n", /*address*/ pic16->cwInfo.confAddrStart+i, val
943 pic16->cwInfo.crInfo[i].value = value;
944 pic16->cwInfo.crInfo[i].emit = 1;