+#define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype))
+extern int IS_CONFIG_ADDRESS( int addr );
+static void
+pic14_constructAbsMap (FILE *ofile)
+{
+ memmap *maps[] = { data, sfr, NULL };
+ int i;
+ hTab *ht = NULL;
+ symbol *sym;
+ set *aliases;
+ int addr, min=-1, max=-1;
+ int size;
+
+ for (i=0; maps[i] != NULL; i++)
+ {
+ for (sym = (symbol *)setFirstItem (maps[i]->syms);
+ sym; sym = setNextItem (maps[i]->syms))
+ {
+ if (IS_DEFINED_HERE(sym) && SPEC_ABSA(sym->etype))
+ {
+ addr = SPEC_ADDR(sym->etype);
+
+ /* handle CONFIG words here */
+ if (IS_CONFIG_ADDRESS( addr ))
+ {
+ //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr );
+ //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) );
+ if (sym->ival) {
+ pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) );
+ } else {
+ fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name );
+ }
+ continue;
+ }
+
+ if (max == -1 || addr > max) max = addr;
+ if (min == -1 || addr < min) min = addr;
+ //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
+ aliases = hTabItemWithKey (ht, addr);
+ if (aliases) {
+ /* May not use addSetHead, as we cannot update the
+ * list's head in the hastable `ht'. */
+ addSet (&aliases, sym);
+#if 0
+ fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n",
+ __FUNCTION__, elementsInSet(aliases), sym->name, addr);
+#endif
+ } else {
+ addSet (&aliases, sym);
+ hTabAddItem (&ht, addr, aliases);
+ } // if
+ } // if
+ } // for sym
+ } // for i
+
+ /* now emit definitions for all absolute symbols */
+ fprintf (ofile, "%s", iComments2);
+ fprintf (ofile, "; absolute symbol definitions\n");
+ fprintf (ofile, "%s", iComments2);
+ for (addr=min; addr <= max; addr++)
+ {
+ size = 1;
+ aliases = hTabItemWithKey (ht, addr);
+ if (aliases && elementsInSet(aliases)) {
+ fprintf (ofile, "udata_abs_%s_%x\tudata_ovr\t0x%04x",
+ moduleName, addr, addr);
+ for (sym = setFirstItem (aliases); sym;
+ sym = setNextItem (aliases))
+ {
+ /* emit STATUS as well as _STATUS, required for SFRs only */
+ fprintf (ofile, "\n%s", sym->name);
+ fprintf (ofile, "\n%s", sym->rname);
+ if (getSize(sym->type) > size) {
+ size = getSize(sym->type);
+ }
+ } // for
+ fprintf (ofile, "\tres\t%d\n", size);
+ } // if
+ } // for i
+
+ /* also emit STK symbols
+ * XXX: This is ugly and fails as soon as devices start to get
+ * differently sized sharebanks, since STK12 will be
+ * required by larger devices but only up to STK03 might
+ * be defined using smaller devices. */
+ fprintf (ofile, "\n");
+ if (!pic14_options.isLibrarySource)
+ {
+ fprintf (ofile, "\tglobal PSAVE\n");
+ fprintf (ofile, "\tglobal SSAVE\n");
+ fprintf (ofile, "\tglobal WSAVE\n");
+ for (i=pic14_getSharebankSize()-4; i >= 0; i--) {
+ fprintf (ofile, "\tglobal STK%02d\n", i);
+ } // for i
+ fprintf (ofile, "sharebank udata_ovr 0x%04x\n",
+ pic14_getSharebankAddress() - pic14_getSharebankSize() + 1);
+ fprintf (ofile, "PSAVE\tres 1\n");
+ fprintf (ofile, "SSAVE\tres 1\n");
+ fprintf (ofile, "WSAVE\tres 1\n");
+ /* fill rest of sharebank with stack STKxx .. STK00 */
+ for (i=pic14_getSharebankSize()-4; i >= 0; i--) {
+ fprintf (ofile, "STK%02d\tres 1\n", i);
+ } // for i
+ } else {
+ /* declare STKxx as extern for all files
+ * except the one containing main() */
+ fprintf (ofile, "\textern PSAVE\n");
+ fprintf (ofile, "\textern SSAVE\n");
+ fprintf (ofile, "\textern WSAVE\n");
+ for (i=pic14_getSharebankSize()-4; i >= 0; i--) {
+ fprintf (ofile, "\textern STK%02d\n", i);
+ } // for i
+ }
+}
+