* src/port.h (PORT structure): added hook initPaths, now each
[fw/sdcc] / src / pic16 / device.c
1 /*-------------------------------------------------------------------------
2
3   device.c - Accomodates subtle variations in PIC16 devices
4
5    Written By -  Scott Dattalo scott@dattalo.com
6    Ported to PIC16 By -  Martin Dubuc m.dubuc@rogers.com
7
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
11    later version.
12    
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.
17    
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 -------------------------------------------------------------------------*/
22
23
24 /*
25         VR - Began writing code to make PIC16 C source files independent from
26         the header file (created by the inc2h.pl)
27
28         - adding maximum RAM memory into PIC_Device structure
29
30 */
31
32 #include <stdio.h>
33
34 #include "common.h"   // Include everything in the SDCC src directory
35 #include "newalloc.h"
36
37
38 #include "pcode.h"
39 #include "ralloc.h"
40 #include "device.h"
41
42
43 static PIC16_device Pics16[] = {
44   {
45     {"p18f242", "18f242", "pic18f242", "f242"},         // aliases
46     0,
47     0x300,                                              // bank mask
48     0x300,                                              // RAMsize
49     0
50   },
51
52   {
53     {"p18f252", "18f252", "pic18f252", "f252"},         // aliases
54     0,
55     0x600,                                              // bank mask
56     0x600,                                              // RAMsize
57     0
58   },
59
60   {
61     {"p18f442", "18f442", "pic18f442", "f442"},         // aliases
62     0,
63     0x300,                                              // bank mask
64     0x300,                                              // RAMsize
65     0
66   },
67
68   {
69     {"p18f452", "18f452", "pic18f452", "f452"},         // aliases
70     0,
71     0x600,                                              // bank mask
72     0x600,                                              // RAMsize
73     0
74   },
75
76   {
77     {"p18f248", "18f248", "pic18f248", "f248"},         // aliases
78     0,
79     0x300,                                              // bank mask
80     0x300,                                              // RAMsize
81     0
82   },
83
84   {
85     {"p18f258", "18f258", "pic18f258", "f258"},         // aliases
86     0,
87     0x600,                                              // bank mask
88     0x600,                                              // RAMsize
89     0
90   },
91
92   {
93     {"p18f448", "18f448", "pic18f448", "f448"},         // aliases
94     0,
95     0x300,                                              // bank mask
96     0x300,                                              // RAMsize
97     0
98   },
99
100   {
101     {"p18f458", "18f458", "pic18f458", "f458"},         // aliases
102     0,
103     0x600,                                              // bank mask
104     0x600,                                              // RAMsize
105     0
106   },
107
108   {
109     {"p18f6520", "18f6520", "pic18f6520", "f6520"},     // aliases
110     0,
111     0x800,                                              // bank mask
112     0x800,                                              // RAMsize
113     1
114   },
115
116   {
117     {"p18f6620", "18f6620", "pic18f6620", "f6620"},     // aliases
118     0,
119     0xf00,                                              // bank mask
120     0xf00,                                              // RAMsize
121     1
122   },
123   {
124     {"p18f6680", "18f6680", "pic18f6680", "f6680"},     // aliases
125     0,
126     0xc00,                                              // bank mask
127     0xc00,                                              // RAMsize
128     1
129   },
130   {
131     {"p18f6720", "18f6720", "pic18f6720", "f6720"},     // aliases
132     0,
133     0xf00,                                              // bank mask
134     0xf00,                                              // RAMsize
135     1
136   },
137   {
138     {"p18f8520", "18f8520", "pic18f8520", "f8520"},     // aliases
139     0,
140     0x800,                                              // bank mask
141     0x800,                                              // RAMsize
142     1
143   },
144   {
145     {"p18f8620", "18f8620", "pic18f8620", "f8620"},     // aliases
146     0,
147     0xf00,                                              // bank mask
148     0xf00,                                              // RAMsize
149     1
150   },
151   {
152     {"p18f8680", "18f8680", "pic18f8680", "f8680"},     // aliases
153     0,
154     0xc00,                                              // bank mask
155     0x800,                                              // RAMsize
156     1
157   },
158   {
159     {"p18f8720", "18f8720", "pic18f8720", "f8720"},     // aliases
160     0,
161     0xf00,                                              // bank mask
162     0xf00,                                              // RAMsize
163     1
164   },
165
166 };
167
168 static int num_of_supported_PICS = sizeof(Pics16)/sizeof(PIC16_device);
169
170 #define DEFAULT_PIC "452"
171
172 PIC16_device *pic16=NULL;
173
174 #define DEFAULT_CONFIG_BYTE 0xff
175
176 #define CONFIG1H_WORD_ADDRESS 0x300001
177 #define DEFAULT_CONFIG1H_WORD DEFAULT_CONFIG_BYTE
178
179 #define CONFIG2L_WORD_ADDRESS 0x300002
180 #define DEFAULT_CONFIG2L_WORD DEFAULT_CONFIG_BYTE
181
182 #define CONFIG2H_WORD_ADDRESS 0x300003
183 #define DEFAULT_CONFIG2H_WORD DEFAULT_CONFIG_BYTE
184
185 #define CONFIG3H_WORD_ADDRESS 0x300005
186 #define DEFAULT_CONFIG3H_WORD DEFAULT_CONFIG_BYTE
187
188 #define CONFIG4L_WORD_ADDRESS 0x300006
189 #define DEFAULT_CONFIG4L_WORD DEFAULT_CONFIG_BYTE
190
191 #define CONFIG5L_WORD_ADDRESS 0x300008
192 #define DEFAULT_CONFIG5L_WORD DEFAULT_CONFIG_BYTE
193
194 #define CONFIG5H_WORD_ADDRESS 0x300009
195 #define DEFAULT_CONFIG5H_WORD DEFAULT_CONFIG_BYTE
196
197 #define CONFIG6L_WORD_ADDRESS 0x30000a
198 #define DEFAULT_CONFIG6L_WORD DEFAULT_CONFIG_BYTE
199
200 #define CONFIG6H_WORD_ADDRESS 0x30000b
201 #define DEFAULT_CONFIG6H_WORD DEFAULT_CONFIG_BYTE
202
203 #define CONFIG7L_WORD_ADDRESS 0x30000c
204 #define DEFAULT_CONFIG7L_WORD DEFAULT_CONFIG_BYTE
205
206 #define CONFIG7H_WORD_ADDRESS 0x30000d
207 #define DEFAULT_CONFIG7H_WORD DEFAULT_CONFIG_BYTE
208
209 static unsigned int config1h_word = DEFAULT_CONFIG1H_WORD;
210 static unsigned int config2l_word = DEFAULT_CONFIG2L_WORD;
211 static unsigned int config2h_word = DEFAULT_CONFIG2H_WORD;
212 static unsigned int config3h_word = DEFAULT_CONFIG3H_WORD;
213 static unsigned int config4l_word = DEFAULT_CONFIG4L_WORD;
214 static unsigned int config5l_word = DEFAULT_CONFIG5L_WORD;
215 static unsigned int config5h_word = DEFAULT_CONFIG5H_WORD;
216 static unsigned int config6l_word = DEFAULT_CONFIG6L_WORD;
217 static unsigned int config6h_word = DEFAULT_CONFIG6H_WORD;
218 static unsigned int config7l_word = DEFAULT_CONFIG7L_WORD;
219 static unsigned int config7h_word = DEFAULT_CONFIG7H_WORD;
220
221 unsigned int stackPos = 0;
222
223 extern regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop);
224
225 void pic16_setMaxRAM(int size)
226 {
227         pic16->maxRAMaddress = size;
228         stackPos = pic16->RAMsize-1;
229
230         if (pic16->maxRAMaddress < 0) {
231                 fprintf(stderr, "invalid \"#pragma maxram 0x%x\" setting\n",
232                         pic16->maxRAMaddress);
233           return;
234         }
235 }
236
237 extern char *iComments2;
238
239 void pic16_dump_equates(FILE *of, set *equs)
240 {
241   regs *r;
242
243         r = setFirstItem(equs);
244         if(!r)return;
245         
246         fprintf(of, "%s", iComments2);
247         fprintf(of, ";\tEquates to used internal registers\n");
248         fprintf(of, "%s", iComments2);
249         
250         for(; r; r = setNextItem(equs)) {
251                 fprintf(of, "%s\tequ\t0x%02x\n", r->name, r->address);
252         }
253 }
254
255
256 int regCompare(const void *a, const void *b)
257 {
258   const regs *const *i = a;
259   const regs *const *j = b;
260
261         /* sort primarily by the address */
262         if( (*i)->address > (*j)->address)return 1;
263         if( (*i)->address < (*j)->address)return -1;
264         
265         /* and secondarily by size */
266         if( (*i)->size > (*j)->size)return 1;
267         if( (*i)->size < (*j)->size)return -1;
268         
269         /* register size sorting may have strange results use with care */
270         
271         /* finally if in same address and same size sort by name */
272         return (strcmp( (*i)->name, (*j)->name));
273
274   return 0;
275 }
276
277 void pic16_dump_section(FILE *of, set *section, int fix)
278 {
279   static int abs_section_no=0;
280   regs *r, *rprev;
281   int init_addr, i;
282   regs **rlist;
283
284         /* put all symbols in an array */
285         rlist = Safe_calloc(elementsInSet(section), sizeof(regs *));
286         r = rlist[0]; i = 0;
287         for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) {
288                 rlist[i] = rprev; i++;
289         }
290         
291         if(!i) {
292                 if(rlist)free(rlist);
293           return;
294         }
295
296         /* sort symbols according to their address */
297         qsort(rlist, i  /*elementsInSet(section)*/, sizeof(regs *), regCompare);
298         
299         if(!fix) {
300                 fprintf(of, "\n\n\tudata\n");
301                 for(r = setFirstItem(section); r; r = setNextItem(section)) {
302                         fprintf(of, "%s\tres\t%d\n", r->name, r->size);
303                 }
304         } else {
305           int j=0;
306           regs *r1;
307           
308                 rprev = NULL;
309                 init_addr = rlist[j]->address;
310                 fprintf(of, "\n\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
311         
312                 for(j=0;j<i;j++) {
313                         r = rlist[j];
314                         if(j < i-1)r1 = rlist[j+1]; else r1 = NULL;
315                         
316                         init_addr = r->address;
317
318                         if(rprev && (init_addr != (rprev->address + rprev->size))
319                                 && !(r1 && (init_addr != r1->address))) {
320                                 fprintf(of, "\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
321                         }
322
323
324                         if(r1 && (init_addr == r1->address)) {
325                                 fprintf(of, "%s\tres\t0\n\n", r->name);
326                         } else {
327                                 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
328                         }
329                         
330                         rprev = r;
331                 }
332         }
333         free(rlist);
334 }
335
336 void pic16_dump_int_registers(FILE *of, set *section)
337 {
338   regs *r, *rprev;
339   int i;
340   regs **rlist;
341
342         /* put all symbols in an array */
343         rlist = Safe_calloc(elementsInSet(section), sizeof(regs *));
344         r = rlist[0]; i = 0;
345         for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) {
346                 rlist[i] = rprev; i++;
347         }
348
349         /* sort symbols according to their address */
350         qsort(rlist, elementsInSet(section), sizeof(regs *), regCompare);
351         
352         if(!i) {
353                 if(rlist)free(rlist);
354           return;
355         }
356         
357         fprintf(of, "\n\n; Internal registers\n");
358         
359         fprintf(of, "%s\tudata_ovr\t0x0000\n", ".registers");
360         for(r = setFirstItem(section); r; r = setNextItem(section))
361                 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
362
363         free(rlist);
364 }
365
366
367 #ifdef WORDS_BIGENDIAN
368   #define _ENDIAN(x)  (3-x)
369 #else
370   #define _ENDIAN(x)  (x)
371 #endif
372
373 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
374
375 /*-----------------------------------------------------------------*/
376 /* printIvalType - generates ival for int/char                     */
377 /*-----------------------------------------------------------------*/
378 void print_idataType (FILE *of, symbol *sym, sym_link * type, initList * ilist)
379 {
380   value *val;
381   unsigned long ulval;
382
383   //fprintf(stderr, "%s\n",__FUNCTION__);
384
385   /* if initList is deep */
386   if (ilist->type == INIT_DEEP)
387     ilist = ilist->init.deep;
388
389   if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
390     werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
391   }
392
393   if (!(val = list2val (ilist))) {
394     // assuming a warning has been thrown
395     val=constVal("0");
396   }
397
398   if (val->type != type) {
399     val = valCastLiteral(type, floatFromVal(val));
400   }
401
402   if(val) 
403     ulval = (unsigned long) floatFromVal (val);
404   else
405     ulval =0;
406
407   switch (getSize (type)) {
408     case 1:
409         fprintf(of, "%s\tdata\t0x%02x\n", sym->name, (unsigned char)BYTE_IN_LONG(ulval, 0));
410 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
411         break;
412
413     case 2:
414 //      fprintf(of, "%s\tdw\t0x%04x\n", sym->name, (unsigned int)(BYTE_IN_LONG(ulval, 0)
415 //                                      + (BYTE_IN_LONG(ulval, 1) << 8)));
416         fprintf(of, "%s\tdata\t0x%02x,0x%02x\n", sym->name, (unsigned char)BYTE_IN_LONG(ulval, 0),
417                                         (unsigned char)(BYTE_IN_LONG(ulval, 1) << 8));
418 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
419 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
420         break;
421
422     case 4:
423         fprintf(of, "%s\tdw\t0x%04x,0x%04x\n", sym->name, (unsigned int)(BYTE_IN_LONG(ulval, 0)
424                                         + (BYTE_IN_LONG(ulval, 1) << 8)),
425                                         (unsigned)(BYTE_IN_LONG(ulval, 2)
426                                         + (BYTE_IN_LONG(ulval, 3) << 8)));
427 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
428 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
429 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
430 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
431         break;
432   }
433 }
434
435
436
437 /*-----------------------------------------------------------------*/
438 /* printIval - generates code for initial value                    */
439 /*-----------------------------------------------------------------*/
440 void print_idata(FILE *of, symbol * sym, sym_link * type, initList * ilist)
441 {
442   if (!ilist)
443     return;
444
445   /* if structure then    */
446   if (IS_STRUCT (type))
447     {
448       //fprintf(stderr,"%s struct\n",__FUNCTION__);
449       //printIvalStruct (sym, type, ilist, oFile);
450       return;
451     }
452
453   /* if this is a pointer */
454   if (IS_PTR (type))
455     {
456       //fprintf(stderr,"%s pointer\n",__FUNCTION__);
457       //printIvalPtr (sym, type, ilist, oFile);
458       return;
459     }
460
461   /* if this is an array   */
462   if (IS_ARRAY (type))
463     {
464       //fprintf(stderr,"%s array\n",__FUNCTION__);
465 //      printIvalArray (sym, type, ilist, pb);
466       return;
467     }
468
469   /* if type is SPECIFIER */
470   if (IS_SPEC (type))
471     {
472 //      fprintf(stderr,"%s spec\n",__FUNCTION__);
473       print_idataType(of, sym, type, ilist);
474       return;
475     }
476 }
477
478
479 void pic16_dump_idata(FILE *of, set *idataSymSet)
480 {
481   int i;
482   symbol *ids;
483   
484
485         i = elementsInSet(idataSymSet);
486         if(!i)return;
487         
488         fprintf(of, "\n\n; Initialised data (idata)\n");
489         fprintf(of, "\tidata\n");
490         for(ids = setFirstItem(idataSymSet); ids; ids = setNextItem(idataSymSet))
491               print_idata(of, ids, ids->type, ids->ival);
492
493 }
494
495
496 /*-----------------------------------------------------------------*
497  *  void pic16_list_valid_pics(int ncols, int list_alias)
498  *
499  * Print out a formatted list of valid PIC devices
500  *
501  * ncols - number of columns in the list.
502  *
503  * list_alias - if non-zero, print all of the supported aliases
504  *              for a device (e.g. F84, 16F84, etc...)
505  *-----------------------------------------------------------------*/
506 void pic16_list_valid_pics(int ncols, int list_alias)
507 {
508   int col,longest;
509   int i,j,k,l;
510
511   if(list_alias)
512     list_alias = sizeof(Pics16[0].name) / sizeof(Pics16[0].name[0]);
513
514   /* decrement the column number if it's greater than zero */
515   ncols = (ncols > 1) ? ncols-1 : 4;
516
517   /* Find the device with the longest name */
518   for(i=0,longest=0; i<num_of_supported_PICS; i++) {
519     for(j=0; j<=list_alias; j++) {
520       k = strlen(Pics16[i].name[j]);
521       if(k>longest)
522         longest = k;
523     }
524   }
525
526   col = 0;
527
528   for(i=0;  i < num_of_supported_PICS; i++) {
529     j = 0;
530     do {
531
532       fprintf(stderr,"%s", Pics16[i].name[j]);
533       if(col<ncols) {
534         l = longest + 2 - strlen(Pics16[i].name[j]);
535         for(k=0; k<l; k++)
536           fputc(' ',stderr);
537
538         col++;
539
540       } else {
541         fputc('\n',stderr);
542         col = 0;
543       }
544
545     } while(++j<list_alias);
546
547   }
548   if(col != ncols)
549     fputc('\n',stderr);
550
551 }
552
553 /*-----------------------------------------------------------------*
554  *  
555  *-----------------------------------------------------------------*/
556 PIC16_device *pic16_find_device(char *name)
557 {
558
559   int i,j;
560
561   if(!name)
562     return NULL;
563
564   for(i = 0; i<num_of_supported_PICS; i++) {
565
566     for(j=0; j<PROCESSOR_NAMES; j++)
567       if(!STRCASECMP(Pics16[i].name[j], name) )
568         return &Pics16[i];
569   }
570
571   /* not found */
572   return NULL; 
573 }
574
575 /*-----------------------------------------------------------------*
576  *  
577  *-----------------------------------------------------------------*/
578 void pic16_init_pic(char *pic_type)
579 {
580         pic16 = pic16_find_device(pic_type);
581
582         if(!pic16) {
583                 if(pic_type)
584                         fprintf(stderr, "'%s' was not found.\n", pic_type);
585                 else
586                         fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
587
588                 fprintf(stderr,"Valid devices are:\n");
589
590                 pic16_list_valid_pics(4,0);
591                 exit(1);
592         }
593
594 //      printf("PIC processor found and initialized: %s\n", pic_type);
595         pic16_setMaxRAM( 0xfff  );
596 }
597
598 /*-----------------------------------------------------------------*
599  *  
600  *-----------------------------------------------------------------*/
601 int pic16_picIsInitialized(void)
602 {
603   if(pic16 && pic16->maxRAMaddress > 0)
604     return 1;
605
606   return 0;
607
608 }
609
610 /*-----------------------------------------------------------------*
611  *  char *pic16_processor_base_name(void) - Include file is derived from this.
612  *-----------------------------------------------------------------*/
613 char *pic16_processor_base_name(void)
614 {
615
616   if(!pic16)
617     return NULL;
618
619   return pic16->name[0];
620 }
621
622 #define DEBUG_CHECK     0
623
624 /*
625  * return 1 if register wasn't found and added, 0 otherwise
626  */
627 int checkAddReg(set **set, regs *reg)
628 {
629   regs *tmp;
630
631 #if DEBUG_CHECK
632         fprintf(stderr, "%s: about to insert REGister: %s ... ", __FUNCTION__, reg->name);
633 #endif
634
635         for(tmp = setFirstItem(*set); tmp; tmp = setNextItem(*set)) {
636                 if(!strcmp(tmp->name, reg->name))break;
637         }
638         
639         if(!tmp) {
640                 addSet(set, reg);
641 #if DEBUG_CHECK
642                 fprintf(stderr, "added\n");
643 #endif
644                 return 1;
645         }
646
647 #if DEBUG_CHECK
648         fprintf(stderr, "already added\n");
649 #endif
650   return 0;
651 }
652
653 int checkAddSym(set **set, symbol *sym)
654 {
655   symbol *tmp;
656
657 #if DEBUG_CHECK
658         fprintf(stderr, "%s: about to add SYMbol: %s ... ", __FUNCTION__, sym->name);
659 #endif
660
661         for(tmp = setFirstItem( *set ); tmp; tmp = setNextItem(*set)) {
662                 if(!strcmp(tmp->name, sym->name))break;
663         }
664         
665         if(!tmp) {
666                 addSet(set, sym);
667 #if DEBUG_CHECK
668                 fprintf(stderr, "added\n");
669 #endif
670                 return 1;
671         }
672
673 #if DEBUG_CHECK
674         fprintf(stderr, "already added\n");
675 #endif
676
677   return 0;
678 }
679
680
681 /*-----------------------------------------------------------------*
682  * void pic16_groupRegistersInSection - add each register to its   *
683  *      corresponding section                                      *
684  *-----------------------------------------------------------------*/
685 void pic16_groupRegistersInSection(set *regset)
686 {
687   regs *reg;
688
689         for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
690
691 //              fprintf(stderr, "%s:%d group registers in section, reg: %s\n", __FILE__, __LINE__, reg->name);
692
693                 if(reg->wasUsed
694                         && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
695
696 //                      fprintf(stderr, "%s:%d register %s alias:%d fix:%d\n",
697 //                              __FILE__, __LINE__, reg->name, reg->alias, reg->isFixed);
698
699                         if(reg->alias) {
700                                 checkAddReg(&pic16_equ_data, reg);
701                         } else
702                         if(reg->isFixed) {
703                                 checkAddReg(&pic16_fix_udata, reg);
704                         } else
705                         if(!reg->isFixed) {
706                                 if(reg->pc_type == PO_GPR_TEMP)
707                                         checkAddReg(&pic16_int_regs, reg);
708                                 else
709                                         checkAddReg(&pic16_rel_udata, reg);
710                         }
711                 }
712         }
713 }
714
715
716
717
718
719 /*-----------------------------------------------------------------*
720  *  void pic16_assignConfigWordValue(int address, int value)
721  *
722  * All high performance RISC CPU PICs have seven config word starting
723  * at address 0x300000.
724  * This routine will assign a value to that address.
725  *
726  *-----------------------------------------------------------------*/
727
728 void pic16_assignConfigWordValue(int address, int value)
729 {
730   switch(address) {
731   case CONFIG1H_WORD_ADDRESS:
732     config1h_word = value;
733     break;
734   case CONFIG2L_WORD_ADDRESS:
735     config2l_word = value;
736     break;
737   case CONFIG2H_WORD_ADDRESS:
738     config2h_word = value;
739     break;
740   case CONFIG3H_WORD_ADDRESS:
741     config3h_word = value;
742     break;
743   case CONFIG4L_WORD_ADDRESS:
744     config4l_word = value;
745     break;
746   case CONFIG5L_WORD_ADDRESS:
747     config5l_word = value;
748     break;
749   case CONFIG5H_WORD_ADDRESS:
750     config5h_word = value;
751     break;
752   case CONFIG6L_WORD_ADDRESS:
753     config6l_word = value;
754     break;
755   case CONFIG6H_WORD_ADDRESS:
756     config6h_word = value;
757     break;
758   case CONFIG7L_WORD_ADDRESS:
759     config7l_word = value;
760     break;
761   case CONFIG7H_WORD_ADDRESS:
762     config7h_word = value;
763     break;
764   }
765
766         fprintf(stderr,"setting config word to 0x%x\n",value);
767
768 }
769 /*-----------------------------------------------------------------*
770  * int pic16_getConfigWord(int address)
771  *
772  * Get the current value of the config word.
773  *
774  *-----------------------------------------------------------------*/
775
776 int pic16_getConfigWord(int address)
777 {
778   switch(address) {
779   case CONFIG1H_WORD_ADDRESS:
780     return config1h_word;
781   case CONFIG2L_WORD_ADDRESS:
782     return config2l_word;
783   case CONFIG2H_WORD_ADDRESS:
784     return config2h_word;
785   case CONFIG3H_WORD_ADDRESS:
786     return config3h_word;
787   case CONFIG4L_WORD_ADDRESS:
788     return config4l_word;
789   case CONFIG5L_WORD_ADDRESS:
790     return config5l_word;
791   case CONFIG5H_WORD_ADDRESS:
792     return config5h_word;
793   case CONFIG6L_WORD_ADDRESS:
794     return config6l_word;
795   case CONFIG6H_WORD_ADDRESS:
796     return config6h_word;
797   case CONFIG7L_WORD_ADDRESS:
798     return config7l_word;
799   case CONFIG7H_WORD_ADDRESS:
800     return config7h_word;
801   default:
802     return 0;
803   }
804 }
805