* src/pic16/device.c (pic16_dump_section): corrected bug which
[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                                 fprintf(of, "\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
320                         }
321
322
323                         if(r1 && (init_addr == r1->address)) {
324                                 fprintf(of, "%s\tres\t0\n\n", r->name);
325                         } else {
326                                 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
327                         }
328                         
329                         rprev = r;
330                 }
331         }
332         free(rlist);
333 }
334
335 void pic16_dump_int_registers(FILE *of, set *section)
336 {
337   regs *r, *rprev;
338   int i;
339   regs **rlist;
340
341         /* put all symbols in an array */
342         rlist = Safe_calloc(elementsInSet(section), sizeof(regs *));
343         r = rlist[0]; i = 0;
344         for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) {
345                 rlist[i] = rprev; i++;
346         }
347
348         /* sort symbols according to their address */
349         qsort(rlist, elementsInSet(section), sizeof(regs *), regCompare);
350         
351         if(!i) {
352                 if(rlist)free(rlist);
353           return;
354         }
355         
356         fprintf(of, "\n\n; Internal registers\n");
357         
358         fprintf(of, "%s\tudata_ovr\t0x0000\n", ".registers");
359         for(r = setFirstItem(section); r; r = setNextItem(section))
360                 fprintf(of, "%s\tres\t%d\n", r->name, r->size);
361
362         free(rlist);
363 }
364
365
366 #ifdef WORDS_BIGENDIAN
367   #define _ENDIAN(x)  (3-x)
368 #else
369   #define _ENDIAN(x)  (x)
370 #endif
371
372 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
373
374 /*-----------------------------------------------------------------*/
375 /* printIvalType - generates ival for int/char                     */
376 /*-----------------------------------------------------------------*/
377 void print_idataType (FILE *of, symbol *sym, sym_link * type, initList * ilist)
378 {
379   value *val;
380   unsigned long ulval;
381
382   //fprintf(stderr, "%s\n",__FUNCTION__);
383
384   /* if initList is deep */
385   if (ilist->type == INIT_DEEP)
386     ilist = ilist->init.deep;
387
388   if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
389     werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
390   }
391
392   if (!(val = list2val (ilist))) {
393     // assuming a warning has been thrown
394     val=constVal("0");
395   }
396
397   if (val->type != type) {
398     val = valCastLiteral(type, floatFromVal(val));
399   }
400
401   if(val) 
402     ulval = (unsigned long) floatFromVal (val);
403   else
404     ulval =0;
405
406   switch (getSize (type)) {
407     case 1:
408         fprintf(of, "%s\tdata\t0x%02x\n", sym->name, (unsigned char)BYTE_IN_LONG(ulval, 0));
409 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
410         break;
411
412     case 2:
413 //      fprintf(of, "%s\tdw\t0x%04x\n", sym->name, (unsigned int)(BYTE_IN_LONG(ulval, 0)
414 //                                      + (BYTE_IN_LONG(ulval, 1) << 8)));
415         fprintf(of, "%s\tdata\t0x%02x,0x%02x\n", sym->name, (unsigned char)BYTE_IN_LONG(ulval, 0),
416                                         (unsigned char)(BYTE_IN_LONG(ulval, 1) << 8));
417 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
418 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
419         break;
420
421     case 4:
422         fprintf(of, "%s\tdw\t0x%04x,0x%04x\n", sym->name, (unsigned int)(BYTE_IN_LONG(ulval, 0)
423                                         + (BYTE_IN_LONG(ulval, 1) << 8)),
424                                         (unsigned)(BYTE_IN_LONG(ulval, 2)
425                                         + (BYTE_IN_LONG(ulval, 3) << 8)));
426 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
427 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
428 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
429 //      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
430         break;
431   }
432 }
433
434
435
436 /*-----------------------------------------------------------------*/
437 /* printIval - generates code for initial value                    */
438 /*-----------------------------------------------------------------*/
439 void print_idata(FILE *of, symbol * sym, sym_link * type, initList * ilist)
440 {
441   if (!ilist)
442     return;
443
444   /* if structure then    */
445   if (IS_STRUCT (type))
446     {
447       //fprintf(stderr,"%s struct\n",__FUNCTION__);
448       //printIvalStruct (sym, type, ilist, oFile);
449       return;
450     }
451
452   /* if this is a pointer */
453   if (IS_PTR (type))
454     {
455       //fprintf(stderr,"%s pointer\n",__FUNCTION__);
456       //printIvalPtr (sym, type, ilist, oFile);
457       return;
458     }
459
460   /* if this is an array   */
461   if (IS_ARRAY (type))
462     {
463       //fprintf(stderr,"%s array\n",__FUNCTION__);
464 //      printIvalArray (sym, type, ilist, pb);
465       return;
466     }
467
468   /* if type is SPECIFIER */
469   if (IS_SPEC (type))
470     {
471 //      fprintf(stderr,"%s spec\n",__FUNCTION__);
472       print_idataType(of, sym, type, ilist);
473       return;
474     }
475 }
476
477
478 void pic16_dump_idata(FILE *of, set *idataSymSet)
479 {
480   int i;
481   symbol *ids;
482   
483
484         i = elementsInSet(idataSymSet);
485         if(!i)return;
486         
487         fprintf(of, "\n\n; Initialised data (idata)\n");
488         fprintf(of, "\tidata\n");
489         for(ids = setFirstItem(idataSymSet); ids; ids = setNextItem(idataSymSet))
490               print_idata(of, ids, ids->type, ids->ival);
491
492 }
493
494
495 /*-----------------------------------------------------------------*
496  *  void pic16_list_valid_pics(int ncols, int list_alias)
497  *
498  * Print out a formatted list of valid PIC devices
499  *
500  * ncols - number of columns in the list.
501  *
502  * list_alias - if non-zero, print all of the supported aliases
503  *              for a device (e.g. F84, 16F84, etc...)
504  *-----------------------------------------------------------------*/
505 void pic16_list_valid_pics(int ncols, int list_alias)
506 {
507   int col,longest;
508   int i,j,k,l;
509
510   if(list_alias)
511     list_alias = sizeof(Pics16[0].name) / sizeof(Pics16[0].name[0]);
512
513   /* decrement the column number if it's greater than zero */
514   ncols = (ncols > 1) ? ncols-1 : 4;
515
516   /* Find the device with the longest name */
517   for(i=0,longest=0; i<num_of_supported_PICS; i++) {
518     for(j=0; j<=list_alias; j++) {
519       k = strlen(Pics16[i].name[j]);
520       if(k>longest)
521         longest = k;
522     }
523   }
524
525   col = 0;
526
527   for(i=0;  i < num_of_supported_PICS; i++) {
528     j = 0;
529     do {
530
531       fprintf(stderr,"%s", Pics16[i].name[j]);
532       if(col<ncols) {
533         l = longest + 2 - strlen(Pics16[i].name[j]);
534         for(k=0; k<l; k++)
535           fputc(' ',stderr);
536
537         col++;
538
539       } else {
540         fputc('\n',stderr);
541         col = 0;
542       }
543
544     } while(++j<list_alias);
545
546   }
547   if(col != ncols)
548     fputc('\n',stderr);
549
550 }
551
552 /*-----------------------------------------------------------------*
553  *  
554  *-----------------------------------------------------------------*/
555 PIC16_device *pic16_find_device(char *name)
556 {
557
558   int i,j;
559
560   if(!name)
561     return NULL;
562
563   for(i = 0; i<num_of_supported_PICS; i++) {
564
565     for(j=0; j<PROCESSOR_NAMES; j++)
566       if(!STRCASECMP(Pics16[i].name[j], name) )
567         return &Pics16[i];
568   }
569
570   /* not found */
571   return NULL; 
572 }
573
574 /*-----------------------------------------------------------------*
575  *  
576  *-----------------------------------------------------------------*/
577 void pic16_init_pic(char *pic_type)
578 {
579         pic16 = pic16_find_device(pic_type);
580
581         if(!pic16) {
582                 if(pic_type)
583                         fprintf(stderr, "'%s' was not found.\n", pic_type);
584                 else
585                         fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
586
587                 fprintf(stderr,"Valid devices are:\n");
588
589                 pic16_list_valid_pics(4,0);
590                 exit(1);
591         }
592
593 //      printf("PIC processor found and initialized: %s\n", pic_type);
594         pic16_setMaxRAM( 0xfff  );
595 }
596
597 /*-----------------------------------------------------------------*
598  *  
599  *-----------------------------------------------------------------*/
600 int pic16_picIsInitialized(void)
601 {
602   if(pic16 && pic16->maxRAMaddress > 0)
603     return 1;
604
605   return 0;
606
607 }
608
609 /*-----------------------------------------------------------------*
610  *  char *pic16_processor_base_name(void) - Include file is derived from this.
611  *-----------------------------------------------------------------*/
612 char *pic16_processor_base_name(void)
613 {
614
615   if(!pic16)
616     return NULL;
617
618   return pic16->name[0];
619 }
620
621 #define DEBUG_CHECK     0
622
623 /*
624  * return 1 if register wasn't found and added, 0 otherwise
625  */
626 int checkAddReg(set **set, regs *reg)
627 {
628   regs *tmp;
629
630 #if DEBUG_CHECK
631         fprintf(stderr, "%s: about to insert REGister: %s ... ", __FUNCTION__, reg->name);
632 #endif
633
634         for(tmp = setFirstItem(*set); tmp; tmp = setNextItem(*set)) {
635                 if(!strcmp(tmp->name, reg->name))break;
636         }
637         
638         if(!tmp) {
639                 addSet(set, reg);
640 #if DEBUG_CHECK
641                 fprintf(stderr, "added\n");
642 #endif
643                 return 1;
644         }
645
646 #if DEBUG_CHECK
647         fprintf(stderr, "already added\n");
648 #endif
649   return 0;
650 }
651
652 int checkAddSym(set **set, symbol *sym)
653 {
654   symbol *tmp;
655
656 #if DEBUG_CHECK
657         fprintf(stderr, "%s: about to add SYMbol: %s ... ", __FUNCTION__, sym->name);
658 #endif
659
660         for(tmp = setFirstItem( *set ); tmp; tmp = setNextItem(*set)) {
661                 if(!strcmp(tmp->name, sym->name))break;
662         }
663         
664         if(!tmp) {
665                 addSet(set, sym);
666 #if DEBUG_CHECK
667                 fprintf(stderr, "added\n");
668 #endif
669                 return 1;
670         }
671
672 #if DEBUG_CHECK
673         fprintf(stderr, "already added\n");
674 #endif
675
676   return 0;
677 }
678
679
680 /*-----------------------------------------------------------------*
681  * void pic16_groupRegistersInSection - add each register to its   *
682  *      corresponding section                                      *
683  *-----------------------------------------------------------------*/
684 void pic16_groupRegistersInSection(set *regset)
685 {
686   regs *reg;
687
688         for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
689
690 //              fprintf(stderr, "%s:%d group registers in section, reg: %s\n", __FILE__, __LINE__, reg->name);
691
692                 if(reg->wasUsed
693                         && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
694
695 //                      fprintf(stderr, "%s:%d register %s alias:%d fix:%d\n",
696 //                              __FILE__, __LINE__, reg->name, reg->alias, reg->isFixed);
697
698                         if(reg->alias) {
699                                 checkAddReg(&pic16_equ_data, reg);
700                         } else
701                         if(reg->isFixed) {
702                                 checkAddReg(&pic16_fix_udata, reg);
703                         } else
704                         if(!reg->isFixed) {
705                                 if(reg->pc_type == PO_GPR_TEMP)
706                                         checkAddReg(&pic16_int_regs, reg);
707                                 else
708                                         checkAddReg(&pic16_rel_udata, reg);
709                         }
710                 }
711         }
712 }
713
714
715
716
717
718 /*-----------------------------------------------------------------*
719  *  void pic16_assignConfigWordValue(int address, int value)
720  *
721  * All high performance RISC CPU PICs have seven config word starting
722  * at address 0x300000.
723  * This routine will assign a value to that address.
724  *
725  *-----------------------------------------------------------------*/
726
727 void pic16_assignConfigWordValue(int address, int value)
728 {
729   switch(address) {
730   case CONFIG1H_WORD_ADDRESS:
731     config1h_word = value;
732     break;
733   case CONFIG2L_WORD_ADDRESS:
734     config2l_word = value;
735     break;
736   case CONFIG2H_WORD_ADDRESS:
737     config2h_word = value;
738     break;
739   case CONFIG3H_WORD_ADDRESS:
740     config3h_word = value;
741     break;
742   case CONFIG4L_WORD_ADDRESS:
743     config4l_word = value;
744     break;
745   case CONFIG5L_WORD_ADDRESS:
746     config5l_word = value;
747     break;
748   case CONFIG5H_WORD_ADDRESS:
749     config5h_word = value;
750     break;
751   case CONFIG6L_WORD_ADDRESS:
752     config6l_word = value;
753     break;
754   case CONFIG6H_WORD_ADDRESS:
755     config6h_word = value;
756     break;
757   case CONFIG7L_WORD_ADDRESS:
758     config7l_word = value;
759     break;
760   case CONFIG7H_WORD_ADDRESS:
761     config7h_word = value;
762     break;
763   }
764
765 //      fprintf(stderr,"setting config word to 0x%x\n",value);
766
767 }
768 /*-----------------------------------------------------------------*
769  * int pic16_getConfigWord(int address)
770  *
771  * Get the current value of the config word.
772  *
773  *-----------------------------------------------------------------*/
774
775 int pic16_getConfigWord(int address)
776 {
777   switch(address) {
778   case CONFIG1H_WORD_ADDRESS:
779     return config1h_word;
780   case CONFIG2L_WORD_ADDRESS:
781     return config2l_word;
782   case CONFIG2H_WORD_ADDRESS:
783     return config2h_word;
784   case CONFIG3H_WORD_ADDRESS:
785     return config3h_word;
786   case CONFIG4L_WORD_ADDRESS:
787     return config4l_word;
788   case CONFIG5L_WORD_ADDRESS:
789     return config5l_word;
790   case CONFIG5H_WORD_ADDRESS:
791     return config5h_word;
792   case CONFIG6L_WORD_ADDRESS:
793     return config6l_word;
794   case CONFIG6H_WORD_ADDRESS:
795     return config6h_word;
796   case CONFIG7L_WORD_ADDRESS:
797     return config7l_word;
798   case CONFIG7H_WORD_ADDRESS:
799     return config7h_word;
800   default:
801     return 0;
802   }
803 }
804