1 /*-------------------------------------------------------------------------
3 device.c - Accomodates subtle variations in PIC devices
4 Written By - Scott Dattalo scott@dattalo.com
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
23 #include "common.h" // Include everything in the SDCC src directory
31 #if defined(__BORLANDC__) || defined(_MSC_VER)
32 #define STRCASECMP stricmp
34 #define STRCASECMP strcasecmp
38 memRange p16f627_mem[] = {
39 {0x20, 0x6f, 0x00, 0},
40 {0xa0, 0xef, 0x00, 1},
41 {0x120, 0x14f, 0x00, 2},
42 {0x70, 0x7f, 0x180, 0},
43 {-1, -1, -1, -1} /* end indicator */
45 memRange p16f627_sfr[] = {
46 {0x00, 0x00, 0x180, 0},
47 {0x01, 0x01, 0x100, 0},
48 {0x02, 0x04, 0x180, 0},
49 {0x05, 0x05, 0x000, 0},
50 {0x06, 0x06, 0x100, 0},
51 {0x85, 0x85, 0x000, 1},
52 {0x86, 0x86, 0x100, 1},
53 {0x0a, 0x0b, 0x180, 0},
54 {0x0c, 0x0c, 0x000, 0},
55 {0x0e, 0x12, 0x000, 0},
56 {0x15, 0x1a, 0x000, 0},
57 {0x1f, 0x1f, 0x000, 0},
58 {0x8e, 0x8e, 0x000, 1},
59 {0x92, 0x92, 0x000, 1},
60 {0x98, 0x9d, 0x000, 1},
61 {0x9f, 0x9f, 0x000, 1},
63 {-1, -1, -1, -1} /* end indicator */
67 memRange p16f84_mem[] = {
68 {0x0c, 0x4f, 0x80, 0},
69 {-1, -1, -1, -1} /* end indicator */
71 memRange p16f84_sfr[] = {
72 {0x01, 0x01, 0x00, 0},
73 {0x02, 0x04, 0x80, 0},
74 {0x05, 0x06, 0x00, 0},
75 {0x85, 0x86, 0x80, 1},
76 {0x08, 0x09, 0x00, 0},
77 {0x88, 0x89, 0x00, 1},
78 {0x0a, 0x0b, 0x80, 0},
79 {-1, -1, -1, -1} /* end indicator */
83 memRange p16f877_mem[] = {
84 {0x20, 0x6f, 0x00, 0},
85 {0xa0, 0xef, 0x00, 1},
86 {0x110, 0x16f, 0x00, 2},
87 {0x190, 0x1ef, 0x00, 3},
88 {0x70, 0x7f, 0x180, 0},
89 {-1, -1, -1, -1} /* end indicator */
91 memRange p16f877_sfr[] = {
92 {0x00, 0x00, 0x180, 0},
93 {0x01, 0x01, 0x100, 0},
94 {0x02, 0x04, 0x180, 0},
95 {0x05, 0x05, 0x000, 0},
96 {0x85, 0x85, 0x000, 1},
97 {0x06, 0x06, 0x100, 0},
98 {0x86, 0x86, 0x100, 1},
99 {0x07, 0x09, 0x000, 0},
100 {0x87, 0x89, 0x000, 1},
101 {0x0a, 0x0b, 0x180, 0},
102 {0x0c, 0x1f, 0x000, 0},
103 {0x8c, 0x8e, 0x000, 1},
104 {0x91, 0x94, 0x000, 1},
105 {0x98, 0x99, 0x000, 1},
106 {0x9e, 0x9f, 0x000, 1},
107 {0x10c, 0x10f, 0x000, 2},
108 {0x18c, 0x18f, 0x000, 3},
110 {-1, -1, -1, -1} /* end indicator */
114 static PIC_device Pics[] = {
116 {"p16f627", "16f627", "pic16f627", "f627"}, /* processor name */
117 p16f627_mem, /* ram mem map */
118 p16f627_sfr, /* sfr mem map */
119 0, /* max ram address (calculated) */
123 {"p16f628", "16f628", "pic16f628", "f628"},
130 {"p16f84", "16f84", "pic16f84", "f84"},
137 {"p16f877", "16f877", "pic16f877", "f877"},
145 static int num_of_supported_PICS = sizeof(Pics)/sizeof(PIC_device);
146 static int default_pic = 0;
147 #define DEFAULT_PIC "f84"
149 static PIC_device *pic=NULL;
151 AssignedMemory *finalMapping=NULL;
152 /*-----------------------------------------------------------------*
154 * void addMem(memRange *ranges,int type)
157 *-----------------------------------------------------------------*/
159 static void addMem(memRange *ranges,int type)
161 memRange *r = ranges;
166 int alias = r->alias;
170 for(i=r->start_address; i<= r->end_address; i++) {
171 if(i <= pic->max_address) {
172 finalMapping[i | alias].isValid = 1;
173 finalMapping[i | alias].alias = r->alias;
174 finalMapping[i | alias].bank = r->bank;
177 finalMapping[i | alias].isSFR = 1;
179 finalMapping[i | alias].isSFR = 0;
183 /* Decrement alias */
185 alias -= ((alias & (alias - 1)) ^ alias);
193 } while (r->start_address >= 0);
198 static void addMaps(PIC_device *pPic)
207 /* First, find the maximum address */
210 pPic->max_address = 0;
214 if((r->end_address | r->alias) > pPic->max_address)
215 pPic->max_address = r->end_address | r->alias;
219 } while (r->start_address >= 0);
223 finalMapping = Safe_calloc(1+pPic->max_address, sizeof(AssignedMemory));
225 /* Now initialize the finalMapping array */
227 for(i=0; i<=pPic->max_address; i++) {
228 finalMapping[i].reg = NULL;
229 finalMapping[i].isValid = 0;
232 addMem(pPic->ram,0); /* add general purpose regs to the map */
233 addMem(pPic->sfr,1); /* Add SFR's to the memmap */
238 * dump_map -- debug stuff
245 for(i=0; i<=pic->max_address; i++) {
246 //fprintf(stdout , "addr 0x%02x is %s\n", i, ((finalMapping[i].isValid) ? "valid":"invalid"));
248 if(finalMapping[i].isValid) {
249 fprintf(stderr,"addr: 0x%02x",i);
250 if(finalMapping[i].isSFR)
251 fprintf(stderr," isSFR");
252 if(finalMapping[i].reg)
253 fprintf( stderr, " reg %s", finalMapping[i].reg->name);
254 fprintf(stderr, "\n");
260 void dump_cblock(FILE *of)
265 //dump_map(); /* display the register map */
269 if(finalMapping[addr].reg && !finalMapping[addr].reg->isEmitted) {
276 /* The bank number printed in the cblock comment tacitly
277 * assumes that the first register in the contiguous group
278 * of registers represents the bank for the whole group */
279 fprintf(of," cblock 0X%04X\t; Bank %d\n",start,finalMapping[start].bank);
281 for( ; start < addr; start++) {
282 if((finalMapping[start].reg) && !finalMapping[start].reg->isEmitted ) {
283 fprintf(of,"\t%s",finalMapping[start].reg->name);
285 /* If this register is aliased in multiple banks, then
286 * mangle the variable name with the alias address: */
287 if(finalMapping[start].alias & start)
288 fprintf(of,"_%x",finalMapping[start].alias);
290 if(finalMapping[start].instance)
291 fprintf(of,"_%d",finalMapping[start].instance);
296 //finalMapping[start].reg->isEmitted = 1;
300 fprintf(of," endc\n");
309 } while(addr <= pic->max_address);
314 /*-----------------------------------------------------------------*
315 * void list_valid_pics(int ncols, int list_alias)
317 * Print out a formatted list of valid PIC devices
319 * ncols - number of columns in the list.
321 * list_alias - if non-zero, print all of the supported aliases
322 * for a device (e.g. F84, 16F84, etc...)
323 *-----------------------------------------------------------------*/
324 void list_valid_pics(int ncols, int list_alias)
330 list_alias = sizeof(Pics[0].name) / sizeof(Pics[0].name[0]);
332 fprintf(stderr,"list_alias size = %d\n",list_alias);
333 /* decrement the column number if it's greater than zero */
334 ncols = (ncols > 1) ? ncols-1 : 4;
336 /* Find the device with the longest name */
337 for(i=0,longest=0; i<num_of_supported_PICS; i++) {
338 for(j=0; j<=list_alias; j++) {
339 k = strlen(Pics[i].name[j]);
347 for(i=0; i < num_of_supported_PICS; i++) {
351 fprintf(stderr,"%s", Pics[i].name[j]);
353 l = longest + 2 - strlen(Pics[i].name[j]);
364 } while(++j<list_alias);
372 /*-----------------------------------------------------------------*
374 *-----------------------------------------------------------------*/
375 PIC_device *find_device(char *name)
383 for(i = 0; i<num_of_supported_PICS; i++) {
385 for(j=0; j<PROCESSOR_NAMES; j++)
386 if(!STRCASECMP(Pics[i].name[j], name) )
394 /*-----------------------------------------------------------------*
396 *-----------------------------------------------------------------*/
399 pic = find_device(DEFAULT_PIC);
402 fprintf(stderr, "%s was not found.\nValid devices are:\n",DEFAULT_PIC);
403 list_valid_pics(4,0);
413 /*-----------------------------------------------------------------*
414 * char *processor_base_name(void) - Include file is derived from this.
415 *-----------------------------------------------------------------*/
416 char *processor_base_name(void)
425 int isSFR(int address)
428 if( (address > pic->max_address) || !finalMapping[address].isSFR)
435 int validAddress(int address, int reg_size)
439 if(address > pic->max_address)
442 for (i=0; i<reg_size; i++)
443 if(!finalMapping[address + i].isValid ||
444 finalMapping[address+i].reg ||
445 finalMapping[address+i].isSFR )
451 void mapRegister(regs *reg)
459 for(i=0; i<reg->size; i++) {
461 alias = finalMapping[reg->address].alias;
466 fprintf(stdout,"mapping %s to address 0x%02x\n",reg->name, (reg->address+alias+i));
468 finalMapping[reg->address + alias + i].reg = reg;
469 finalMapping[reg->address + alias + i].instance = i;
471 /* Decrement alias */
473 alias -= ((alias & (alias - 1)) ^ alias);
484 int assignRegister(regs *reg, int start_address)
490 if (validAddress(reg->address,reg->size)) {
496 if( isSFR(reg->address)) {
500 fprintf(stderr, "WARNING: Ignoring Out of Range register assignment at fixed address %d, %s\n",
501 reg->address, reg->name);
505 /* This register does not have a fixed address requirement
506 * so we'll search through all availble ram address and
507 * assign the first one */
509 for (i=start_address; i<=pic->max_address; i++) {
511 if (validAddress(i,reg->size)) {
518 fprintf(stderr, "WARNING: No more RAM available\n");
525 void assignFixedRegisters(set *regset)
529 for (reg = setFirstItem(regset) ; reg ;
530 reg = setNextItem(regset)) {
533 assignRegister(reg,0);
538 void assignRelocatableRegisters(set *regset)
544 for (reg = setFirstItem(regset) ; reg ;
545 reg = setNextItem(regset)) {
547 //fprintf(stdout,"assigning %s\n",reg->name);
550 address = assignRegister(reg,address);