]> Shamusworld >> Repos - rmac/commitdiff
More readability cleanups.
authorJames Hammons <jlhamm@acm.org>
Thu, 19 Jan 2012 22:28:32 +0000 (22:28 +0000)
committerJames Hammons <jlhamm@acm.org>
Thu, 19 Jan 2012 22:28:32 +0000 (22:28 +0000)
18 files changed:
68kgen.c
amode.h
debug.c
mark.c
mark.h
object.c
object.h
parmode.h
procln.c
procln.h
risca.c
rmac.c
sect.c
sect.h
symbol.c
symbol.h
token.c
token.h

index 51a7361a85edd4894b72bb4e8edb3ca5f7e85a98..b614454bbb601d7df82c059dc1455cfa5a77c974 100644 (file)
--- a/68kgen.c
+++ b/68kgen.c
@@ -28,15 +28,13 @@ int main(int argc, char ** argv)
        int namcnt;
        char ln[256];
 
-       if (argc == 2)
-               if ((kfp = fopen(argv[1], "w")) == NULL)
-                       error("Cannot create: %s", argv[1]);
+       if ((argc == 2) && ((kfp = fopen(argv[1], "w")) == NULL))
+               error("Cannot create: %s", argv[1]);
 
-//     while (gets(ln) != NULL)
        while (fgets(ln, 256, stdin) != NULL)
        {
-
                ++lineno;                       /* bump line# */
+
                if (*ln == '#')         /* ignore comments */
                        continue;
 
@@ -66,6 +64,7 @@ int main(int argc, char ** argv)
                if (namcnt)
                        procln(namcnt, namv);
        }
+
        return 0;
 }
 
@@ -99,6 +98,7 @@ void procln(int namc, char ** namv)
                printf("CGSPECIAL");
        else for (s = namv[1], i=0; *s; ++s)
                printf("%sSIZ%c", (i++ ? "|" : ""), *s);
+
        printf(", %s, %s, ", namv[2], namv[3]);
 
        if (*namv[4] == '%')            /* enforce little fascist percent signs */
@@ -126,6 +126,7 @@ void procln(int namc, char ** namv)
        ++kwnum;
 }
 
+
 void error(char * s, char * s1)
 {
        fprintf(stderr, s, s1);
diff --git a/amode.h b/amode.h
index e9419d18efc9cbbb8ba10088dce269c3ac5239db..cde089522e03108859c7a0ca25f981b174ee1e63 100644 (file)
--- a/amode.h
+++ b/amode.h
@@ -92,7 +92,7 @@ extern int a0ixsiz, a1ixsiz;
 extern TOKEN a0oexpr[], a1oexpr[];
 extern VALUE a0oexval, a1oexval;
 extern WORD a0oexattr, a1oexattr;
-extern SYM *a0esym, *a1esym;
+extern SYM * a0esym, * a1esym;
 
 // Mnemonic table structure
 #define MNTAB  struct _mntab
diff --git a/debug.c b/debug.c
index fc3029351fd8d4feca6ec4080ab601c1d6343035..e3f947a3c185037f59cb8a0f423ed1732be99b2e 100644 (file)
--- a/debug.c
+++ b/debug.c
 
 static int siztab[4] = {3, 5, 9, 9};
 
+
 //
-// --- Print 'c' Visibly ---------------------------------------------------------------------------
+// Print 'c' Visibly
 //
-
 int visprt(char c)
 {
-   if (c < 0x20 || c >= 0x7f)
-      putchar('.');
-   else
-      putchar(c);
+       if (c < 0x20 || c >= 0x7F)
+               putchar('.');
+       else
+               putchar(c);
 
-   return 0;
+       return 0;
 }
 
+
 //
-// --- Print expression, return ptr to just past the ENDEXPR ---------------------------------------
+// Print expression, return ptr to just past the ENDEXPR
 //
-
 TOKEN * printexpr(TOKEN * tp)
 {
-   if (tp != NULL)
-   {
-      while (*tp != ENDEXPR)
-         {
-         switch ((int)*tp++)
-                {
-            case SYMBOL:
-               printf("`%s' ", ((SYM *)*tp)->sname);
-               ++tp;
-               break;
-            case CONST:
-               printf("$%ux ", *tp++);
-               break;
-            case ACONST:
-               printf("ACONST=($%ux,$%ux) ", *tp, tp[1]);
-               tp += 2;
-               break;
-            default:
-               printf("%c ", (char)tp[-1]);
-               break;
-         }
-         }
-   }
-
-   printf(";\n");
-   return tp + 1;
+       if (tp != NULL)
+       {
+               while (*tp != ENDEXPR)
+               {
+                       switch ((int)*tp++)
+                       {
+                       case SYMBOL:
+                               printf("`%s' ", ((SYM *)*tp)->sname);
+                               ++tp;
+                               break;
+                       case CONST:
+                               printf("$%ux ", *tp++);
+                               break;
+                       case ACONST:
+                               printf("ACONST=($%ux,$%ux) ", *tp, tp[1]);
+                               tp += 2;
+                               break;
+                       default:
+                               printf("%c ", (char)tp[-1]);
+                               break;
+                       }
+               }
+       }
+
+       printf(";\n");
+       return tp + 1;
 }
 
+
 //
-// --- Dump data in a chunk (and maybe others) in the appropriate format ---------------------------
+// Dump data in a chunk (and maybe others) in the appropriate format
 //
-
 int chdump(CHUNK * ch, int format)
 {
-   while (ch != NULL)
-   {
-      printf("chloc=$%08ux, chsize=$%ux\n", ch->chloc, ch->ch_size);
-      mdump(ch->chptr, ch->ch_size, format, ch->chloc);
-      ch = ch->chnext;
-   }
-
-   return 0;
+       while (ch != NULL)
+       {
+               printf("chloc=$%08ux, chsize=$%ux\n", ch->chloc, ch->ch_size);
+               mdump(ch->chptr, ch->ch_size, format, ch->chloc);
+               ch = ch->chnext;
+       }
+
+       return 0;
 }
 
+
 //
-// --- Dump fixup records in printable format ------------------------------------------------------
+// Dump fixup records in printable format
 //
-
 int fudump(CHUNK * ch)
 {
-   PTR p;
-   char * ep;
-   WORD attr, esiz;
-   WORD line, file;
-   LONG loc;
-
-   for(; ch!=NULL;)
-   {
-      p.cp = ch->chptr;
-      ep = ch->chptr + ch->ch_size;
-
-         while(p.cp < ep)
-         {
-         attr = *p.wp++;
-         loc = *p.lp++;
-         file = *p.wp++;
-         line = *p.wp++;
-
-         printf("$%04x $%08ux %d.%d: ", (int)attr, loc, (int)file, (int)line);
-
-         if (attr & FU_EXPR)
-                {
-            esiz = *p.wp++;
-            printf("(%d long) ", (int)esiz);
-            p.tk = printexpr(p.tk);
-         }
-         else
-                {
-            printf("`%s' ;\n", (*p.sy)->sname);
-            ++p.lp;
-         }
-      }
-
-      ch = ch->chnext;
-   }
-
-   return 0;
+       PTR p;
+       char * ep;
+       WORD attr, esiz;
+       WORD line, file;
+       LONG loc;
+
+       for(; ch!=NULL;)
+       {
+               p.cp = ch->chptr;
+               ep = ch->chptr + ch->ch_size;
+
+               while(p.cp < ep)
+               {
+                       attr = *p.wp++;
+                       loc = *p.lp++;
+                       file = *p.wp++;
+                       line = *p.wp++;
+
+                       printf("$%04x $%08ux %d.%d: ", (int)attr, loc, (int)file, (int)line);
+
+                       if (attr & FU_EXPR)
+                       {
+                               esiz = *p.wp++;
+                               printf("(%d long) ", (int)esiz);
+                               p.tk = printexpr(p.tk);
+                       }
+                       else
+                       {
+                               printf("`%s' ;\n", (*p.sy)->sname);
+                               ++p.lp;
+                       }
+               }
+
+               ch = ch->chnext;
+       }
+
+       return 0;
 }
 
+
 //
-// --- Dump marks ----------------------------------------------------------------------------------
+// Dump marks
 //
-
 int mudump(void)
 {
-   MCHUNK * mch;
-   PTR p;
-   WORD from;
-   WORD w;
-   LONG loc;
-   SYM * symbol;
+       MCHUNK * mch;
+       PTR p;
+       WORD from;
+       WORD w;
+       LONG loc;
+       SYM * symbol;
 
-   from = 0;
+       from = 0;
 
-   for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
-   {
-      printf("mch=$%08ux mcptr=$%08ux mcalloc=$%ux mcused=$%x\n",
-             (uint32_t)mch,
-             (mch->mcptr.lw),
-             mch->mcalloc,
-             (mch->mcused));
+       for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
+       {
+               printf("mch=$%08ux mcptr=$%08ux mcalloc=$%ux mcused=$%x\n",
+                       (uint32_t)mch,
+                       (mch->mcptr.lw),
+                       mch->mcalloc,
+                       (mch->mcused));
 
-      p = mch->mcptr;
-         
-      for(;;)
-         {
-         w = *p.wp++;
+               p = mch->mcptr;
+               
+               for(;;)
+               {
+                       w = *p.wp++;
 
-                if (w & MCHEND)
-            break;
+                       if (w & MCHEND)
+                               break;
 
-         symbol = NULL;
-         loc = *p.lp++;
+                       symbol = NULL;
+                       loc = *p.lp++;
 
-         if (w & MCHFROM)
-            from = *p.wp++;
+                       if (w & MCHFROM)
+                               from = *p.wp++;
 
-         if (w & MSYMBOL)
-            symbol = *p.sy++;
+                       if (w & MSYMBOL)
+                               symbol = *p.sy++;
 
-         printf("m=$%04x to=%d loc=$%ux from=%d siz=%s",
-                 w, w & 0x00ff, loc, from, (w & MLONG) ? "long" : "word");
+                       printf("m=$%04x to=%d loc=$%ux from=%d siz=%s",
+                                       w, w & 0x00ff, loc, from, (w & MLONG) ? "long" : "word");
 
-         if (symbol != NULL)
-            printf(" sym=`%s'", symbol->sname);
+                       if (symbol != NULL)
+                               printf(" sym=`%s'", symbol->sname);
 
-                printf("\n");
-      }
-   }
+                       printf("\n");
+               }
+       }
 
-   return 0;
+       return 0;
 }
 
+
 //
-// -------------------------------------------------------------------------------------------------
 // Dump memory from 'start' for 'count' bytes; `flg' is the following ORed together:
 // 0 - bytes
 // 1 - words
 // 2 - longwords
 // 
 // if `base' is not -1, then print it at the start of each line, incremented accordingly.
-// -------------------------------------------------------------------------------------------------
 //
-
-int mdump(char *start, LONG count, int flg, LONG base) {
-   int i, j, k;
-
-   j = 0;
-   for(i = 0; i < (int)count;) {
-      if((i & 15) == 0) {
-         if(j < i) {
-            printf("  ");
-            while(j < i)
-               visprt(start[j++]);
-            putchar('\n');
-         }
-         j = i;
-         if(base != -1)
-            printf("%08ux  ", base);
-      }
-
-      switch(flg & 3) {
-         case 0:
-            printf("%02x ", start[i] & 0xff);
-            ++i;
-            break;
-         case 1:
-            printf("%02x%02x ", start[i] & 0xff, start[i+1] & 0xff);
-            i += 2;
-            break;
-         case 2:
-            printf("%02x%02x%02x%02x ", start[i] & 0xff, start[i+1] & 0xff,
-                   start[i+2] & 0xff, start[i+3] & 0xff);
-            i += 4;
-            break;
-         case 3:
-            break;
-      }
-
-      if(base != -1)
-         base += 1 << (flg & 3);
-   }
-
-   // Print remaining bit of ascii; the hairy expression computes the number of
-   // spaces to print to make the ascii line up nicely.
-   if(j != i) {
-      k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
-      while(k--)
-         putchar(' ');
-      printf("  ");
-      while(j < i)
-         visprt(start[j++]);
-      putchar('\n');
-   }
-
-   return(0);
+int mdump(char * start, LONG count, int flg, LONG base)
+{
+       int i, j, k;
+       j = 0;
+
+       for(i=0; i<(int)count;)
+       {
+               if ((i & 15) == 0)
+               {
+                       if (j < i)
+                       {
+                               printf("  ");
+
+                               while(j < i)
+                               visprt(start[j++]);
+
+                               putchar('\n');
+                       }
+
+                       j = i;
+
+                       if (base != -1)
+                               printf("%08ux  ", base);
+               }
+
+               switch (flg & 3)
+               {
+               case 0:
+                       printf("%02x ", start[i] & 0xff);
+                       ++i;
+                       break;
+               case 1:
+                       printf("%02x%02x ", start[i] & 0xff, start[i+1] & 0xff);
+                       i += 2;
+                       break;
+               case 2:
+                       printf("%02x%02x%02x%02x ", start[i] & 0xff, start[i+1] & 0xff,
+                               start[i+2] & 0xff, start[i+3] & 0xff);
+                       i += 4;
+                       break;
+               case 3:
+                       break;
+               }
+
+               if (base != -1)
+                       base += 1 << (flg & 3);
+       }
+
+       // Print remaining bit of ascii; the hairy expression computes the number of
+       // spaces to print to make the ascii line up nicely.
+       if (j != i)
+       {
+               k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
+
+               while(k--)
+                       putchar(' ');
+
+               printf("  ");
+
+               while(j < i)
+                       visprt(start[j++]);
+
+               putchar('\n');
+       }
+
+       return 0;
 }
 
+
 //
-// --- Dump list of tokens on stdout in printable form ---------------------------------------------
+// Dump list of tokens on stdout in printable form
 //
-
 int dumptok(TOKEN * tk)
 {
-   int flg = 0;
-
-   while (*tk != EOL)
-   {
-      if (flg++)
-         printf(" ");
-
-      if (*tk >= 128)
-         {
-         printf("REG=%ud", *tk++ - 128);
-         continue;
-      }
-
-      switch ((int)*tk++)
-         {
-         case CONST:                                        // CONST <value>
-            printf("CONST=%ud", *tk++);
-            break;
-         case STRING:                                       // STRING <address>
-            printf("STRING='%s'", (char *)*tk++);
-            break;
-         case SYMBOL:                                       // SYMBOL <address> 
-            printf("SYMBOL='%s'", (char *)*tk++);
-            break;
-         case EOL:                                          // End of line 
-            printf("EOL");
-            break;
-         case TKEOF:                                        // End of file (or macro)
-            printf("TKEOF");
-            break;
-         case DEQUALS:                                      // == 
-            printf("DEQUALS");
-            break;
-         case DCOLON:                                       // :: 
-            printf("DCOLON");
-            break;
-         case GE:                                           // >= 
-            printf("GE");
-            break;
-         case LE:                                           // <= 
-            printf("LE");
-            break;
-         case NE:                                           // <> or != 
-            printf("NE");
-            break;
-         case SHR:                                          // >> 
-            printf("SHR");
-            break;
-         case SHL:                                          // << 
-            printf("SHL");
-            break;
-         default:
-            printf("%c", (int)tk[-1]);
-            break;
-      }
-   }
-
-   printf("\n");
-
-   return 0;
+       int flg = 0;
+
+       while (*tk != EOL)
+       {
+               if (flg++)
+                       printf(" ");
+
+               if (*tk >= 128)
+               {
+                       printf("REG=%ud", *tk++ - 128);
+                       continue;
+               }
+
+               switch ((int)*tk++)
+               {
+               case CONST:                                        // CONST <value>
+                       printf("CONST=%ud", *tk++);
+                       break;
+               case STRING:                                       // STRING <address>
+                       printf("STRING='%s'", (char *)*tk++);
+                       break;
+               case SYMBOL:                                       // SYMBOL <address> 
+                       printf("SYMBOL='%s'", (char *)*tk++);
+                       break;
+               case EOL:                                          // End of line 
+                       printf("EOL");
+                       break;
+               case TKEOF:                                        // End of file (or macro)
+                       printf("TKEOF");
+                       break;
+               case DEQUALS:                                      // == 
+                       printf("DEQUALS");
+                       break;
+               case DCOLON:                                       // :: 
+                       printf("DCOLON");
+                       break;
+               case GE:                                           // >= 
+                       printf("GE");
+                       break;
+               case LE:                                           // <= 
+                       printf("LE");
+                       break;
+               case NE:                                           // <> or != 
+                       printf("NE");
+                       break;
+               case SHR:                                          // >> 
+                       printf("SHR");
+                       break;
+               case SHL:                                          // << 
+                       printf("SHL");
+                       break;
+               default:
+                       printf("%c", (int)tk[-1]);
+                       break;
+               }
+       }
+
+       printf("\n");
+
+       return 0;
 }
 
+
 //
-// --- Dump Everything -----------------------------------------------------------------------------
+// Dump Everything
 //
+int dump_everything(void)
+{
+       int i;
 
-int dump_everything(void) {
-   int i;
-
-   for(i = 1; i < NSECTS; ++i)
-      if(sect[i].scattr & SUSED) {
-         printf("Section %d sloc=$%ux\n", i, sect[i].sloc);
-         printf("Code:\n");
-         chdump(sect[i].sfcode, 1);
+       for(i = 1; i < NSECTS; ++i)
+       {
+               if (sect[i].scattr & SUSED)
+               {
+                       printf("Section %d sloc=$%ux\n", i, sect[i].sloc);
+                       printf("Code:\n");
+                       chdump(sect[i].sfcode, 1);
 
-         printf("Fixup:\n");
-         fudump(sect[i].sffix);
+                       printf("Fixup:\n");
+                       fudump(sect[i].sffix);
 
-         printf("\n");
-      }
+                       printf("\n");
+               }
+       }
 
-   printf("\nMarks:\n");
-   mudump();                                                // Dump marks
-   printf("Total memory allocated=$%ux\n", amemtot);
+       printf("\nMarks:\n");
+       mudump();                                                // Dump marks
+       printf("Total memory allocated=$%ux\n", amemtot);
 
-   return(0);
+       return 0;
 }
diff --git a/mark.c b/mark.c
index 96468bc51d387bb5445cd929a3824b597b614a3d..1cf6e453524fcf5325af127d8db3499350a37ec9 100644 (file)
--- a/mark.c
+++ b/mark.c
 #include "object.h"
 #include "risca.h"
 
-MCHUNK *firstmch;                                           // First mark chunk
-MCHUNK *curmch;                                             // Current mark chunk
-PTR markptr;                                                // Deposit point in current mark chunk
-LONG mcalloc;                                               // #bytes alloc'd to current mark chunk
-LONG mcused;                                                // #bytes used in current mark chunk
-WORD curfrom;                                               // Current "from" section
+MCHUNK * firstmch;             // First mark chunk
+MCHUNK * curmch;               // Current mark chunk
+PTR markptr;                   // Deposit point in current mark chunk
+LONG mcalloc;                  // #bytes alloc'd to current mark chunk
+LONG mcused;                   // #bytes used in current mark chunk
+WORD curfrom;                  // Current "from" section
+
 
 //
-// --- Initialize Marker ---------------------------------------------------------------------------
+// Initialize Marker
 //
-
-void init_mark(void) {
-   firstmch = curmch = NULL;
-   mcalloc = mcused = 0;
-   curfrom = 0;
+void init_mark(void)
+{
+       firstmch = curmch = NULL;
+       mcalloc = mcused = 0;
+       curfrom = 0;
 }
 
+
 //
-// --- Wrap up marker (called after final mark is made) --------------------------------------------
+// Wrap up marker (called after final mark is made)
 //
-
-void stopmark(void) {
-   if(curmch) {
-      *markptr.wp = MCHEND;                                 // Mark end of block
-      curmch->mcused = mcused;                              // Update #used in mark block
-   }
+void stopmark(void)
+{
+       if (curmch)
+       {
+               *markptr.wp = MCHEND;                                 // Mark end of block
+               curmch->mcused = mcused;                              // Update #used in mark block
+       }
 }
 
+
 //
-// --- Mark a word or longword relocatable ---------------------------------------------------------
+// Mark a word or longword relocatable
 //
+int rmark(int from, LONG loc, int to, int size, SYM * symbol)
+{
+       WORD w;
 
-int rmark(int from, LONG loc, int to, int size, SYM *symbol) {
-   WORD w;
+       if ((mcalloc - mcused) < MIN_MARK_MEM)
+               amark();
 
-   if((mcalloc - mcused) < MIN_MARK_MEM)
-      amark();
+       w = (WORD)(size | to);
 
-   w = (WORD)(size | to);
-   if(from != curfrom)
-      w |= MCHFROM;
-   if(symbol != NULL)
-      w |= MSYMBOL;
+       if (from != curfrom)
+               w |= MCHFROM;
 
-   mcused += sizeof(WORD) + sizeof(LONG);
-   *markptr.wp++ = w;
-   *markptr.lp++ = loc;
+       if (symbol != NULL)
+               w |= MSYMBOL;
 
-   if(w & MCHFROM) {
-      *markptr.wp++ = (WORD)from;
-      curfrom = (WORD)from;
-      mcused += sizeof(WORD);
-   }
+       mcused += sizeof(WORD) + sizeof(LONG);
+       *markptr.wp++ = w;
+       *markptr.lp++ = loc;
 
-   if(w & MSYMBOL) {
-      *markptr.sy++ = symbol;
-      mcused += sizeof(LONG);
-   }
+       if (w & MCHFROM)
+       {
+               *markptr.wp++ = (WORD)from;
+               curfrom = (WORD)from;
+               mcused += sizeof(WORD);
+       }
 
-   *markptr.wp = 0x0000;
+       if (w & MSYMBOL)
+       {
+               *markptr.sy++ = symbol;
+               mcused += sizeof(LONG);
+       }
 
-   return(0);
+       *markptr.wp = 0x0000;
+
+       return 0;
 }
 
+
 //
-// --- Allocate another chunk of mark space --------------------------------------------------------
+// Allocate another chunk of mark space
 //
-
-int amark(void) {
-   MCHUNK *p;
-
-   // Alloc mark block header (and data) and set it up.
-   p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
-   p->mcnext = NULL;
-   p->mcalloc = MARK_ALLOC_INCR;
-   p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
-
-   if(curmch) {                                             // Link onto previous chunk 
-      *markptr.wp++ = MCHEND;                               // Mark end of block 
-      curmch->mcused = mcused;
-      curmch->mcnext = p;
-   }
-   if(!firstmch)
-      firstmch = p;
-
-   curmch = p;                                              // Setup global vars 
-   markptr = p->mcptr;
-   mcalloc = MARK_ALLOC_INCR;
-   mcused = 0;
-
-   return(0);
+int amark(void)
+{
+       MCHUNK * p;
+
+       // Alloc mark block header (and data) and set it up.
+       p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
+       p->mcnext = NULL;
+       p->mcalloc = MARK_ALLOC_INCR;
+       p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
+
+       if (curmch)
+       {                                             // Link onto previous chunk 
+               *markptr.wp++ = MCHEND;                               // Mark end of block 
+               curmch->mcused = mcused;
+               curmch->mcnext = p;
+       }
+
+       if (!firstmch)
+               firstmch = p;
+
+       curmch = p;                                              // Setup global vars 
+       markptr = p->mcptr;
+       mcalloc = MARK_ALLOC_INCR;
+       mcused = 0;
+
+       return 0;
 }
 
+
 //
-// --- Make mark image for BSD .o file -------------------------------------------------------------
+// Make mark image for BSD .o file
 //
-
-LONG bsdmarkimg(char *mp, LONG siz, LONG tsize, int reqseg) {
-   MCHUNK *mch;                                             // Mark chunk
-   PTR p;                                                   // Source point from within mark chunk
-   WORD from;                                               // Section fixups are currently FROM
-   WORD w;                                                  // A word (temp)
-   LONG loc;                                                // Location (temp) 
-   SYM *symbol;                                             // Symbols (temp)
-   char *wp;                                                // Pointer into raw relocation info
-   char *dp;                                                // Deposit point for RELMOD info
-   LONG diff;                                               // Difference to relocate (RELMOD)
-   LONG raddr, rflag = 0;                                   // BSD relocation address and flags
-   LONG rsize;                                              // Relocation size
-   int validsegment = 0;                                    // Valid segment being processed
-
-   rsize = 0;                                               // Initialise relocation size
-   chptr = mp;
-
-   from = 0;
-   for(mch = firstmch; mch != NULL; mch = mch->mcnext)
-      for(p = mch->mcptr;;) {
-         w = *p.wp++;                                       // Next mark entry
-
-         if(w & MCHEND) break;                              // End of mark chunk
-
-         // Get mark record
-         symbol = NULL;
-         loc = *p.lp++;                                     // Mark location
-         if(w & MCHFROM) {                                  // Maybe change "from" section
-            from = *p.wp++;
-            if(obj_format == BSD) {
-               if(reqseg == TEXT) {                         // Requested segment is TEXT
-                  if(from == TEXT) validsegment = 1; 
-                  else validsegment = 0;
-               } else {                                     // Requested segment is DATA
-                  if(from == DATA) validsegment = 1; 
-                  else validsegment = 0;
-               }
-            }
-         }
-
-         if(w & MSYMBOL)                                    // Maybe includes a symbol
-            symbol = *p.sy++;
-
-         if(obj_format == BSD) {
-            raddr = loc;                                    // Set relocation address
-            if(validsegment)
-               D_long(raddr);                               // Write relocation address
-            if(w & MPCREL)
-               rflag = 0x000000A0;                          // PC-relative fixup
-            else
-               rflag = 0x00000040;                          // Absolute fixup
-            if(w & MMOVEI)
-               rflag |= 0x00000001;
-         }
-
-         // Compute mark position in relocation information;
-         // in RELMOD mode, get address of data to fix up.
-         if(from == DATA)
-            loc += tsize;
-         wp = (char *)(mp + loc);
-
-         if(symbol) {
-            // Deposit external reference
-            if(obj_format == BSD) {
-               rflag |= 0x00000010;                         // Set external reloc flag bit
-               rflag |= (symbol->senv << 8);                // Put symbol index in flags
-               if(symbol->sattre & RISCSYM) rflag |= 0x00000001;
-               if(validsegment) {
-                  D_long(rflag);                            // Write relocation flags
-                  rsize += 8;                               // Increment relocation size
-               }
-            }
-
-         } else {
-
-            if(obj_format == BSD) {
-               w &= TDB;                                    // Set reloc flags to segment
-               switch(w) {
-                  case TEXT: rflag |= 0x00000400; break;
-                  case DATA: rflag |= 0x00000600; break;
-                  case BSS:  rflag |= 0x00000800; break;
-               }
-               if(validsegment) {
-                  D_long(rflag);                            // Write relocation flags
-                  rsize += 8;                               // Increment relocation size
-               }
-               w &= TDB;
-               if(validsegment) {
-                  if(w & (DATA|BSS)) {
-                     dp = objimage + BSDHDRSIZE + loc;
-                     diff = ((LONG)(*dp++ & 0xff)) << 24;
-                     diff |= ((LONG)(*dp++ & 0xff)) << 16;
-                     diff |= ((LONG)(*dp++ & 0xff)) << 8;
-                     diff |= (LONG)(*dp & 0xff);
-                     DEBUG printf("diff=%ux ==> ", diff);
-                     if(rflag & 0x01)
-                        diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
-                     diff += sect[TEXT].sloc;
-                     if(w == BSS)
-                        diff += sect[DATA].sloc;
-                     if(rflag & 0x01)
-                        diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
-                     dp = objimage + BSDHDRSIZE + loc;
-                     *dp++ = (char)(diff >> 24);
-                     *dp++ = (char)(diff >> 16);
-                     *dp++ = (char)(diff >> 8);
-                     *dp = (char)diff;
-                     DEBUG printf("%ux\n", diff);
-                  }
-               }
-            }
-         }
-      }
-
-   if(obj_format == BSD)                                    // Return relocation size
-      return(rsize);                                        
-   else
-      return(siz);
+LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg)
+{
+       MCHUNK * mch;                                             // Mark chunk
+       PTR p;                                                   // Source point from within mark chunk
+       WORD from;                                               // Section fixups are currently FROM
+       WORD w;                                                  // A word (temp)
+       LONG loc;                                                // Location (temp) 
+       SYM * symbol;                                             // Symbols (temp)
+       char * wp;                                                // Pointer into raw relocation info
+       char * dp;                                                // Deposit point for RELMOD info
+       LONG diff;                                               // Difference to relocate (RELMOD)
+       LONG raddr, rflag = 0;                                   // BSD relocation address and flags
+       LONG rsize;                                              // Relocation size
+       int validsegment = 0;                                    // Valid segment being processed
+
+       rsize = 0;                                               // Initialise relocation size
+       chptr = mp;
+
+       from = 0;
+       for(mch = firstmch; mch != NULL; mch = mch->mcnext)
+       {
+               for(p=mch->mcptr;;)
+               {
+                       w = *p.wp++;                                       // Next mark entry
+
+                       if (w & MCHEND)
+                               break;                              // End of mark chunk
+
+                       // Get mark record
+                       symbol = NULL;
+                       loc = *p.lp++;                                     // Mark location
+
+                       if (w & MCHFROM)
+                       {                                  // Maybe change "from" section
+                               from = *p.wp++;
+
+                               if (obj_format == BSD)
+                               {
+                                       if (reqseg == TEXT)
+                                       {                         // Requested segment is TEXT
+                                               if (from == TEXT)
+                                                       validsegment = 1; 
+                                               else
+                                                       validsegment = 0;
+                                       }
+                                       else
+                                       {                                     // Requested segment is DATA
+                                               if (from == DATA)
+                                                       validsegment = 1; 
+                                               else
+                                                       validsegment = 0;
+                                       }
+                               }
+                       }
+
+                       if (w & MSYMBOL)                                    // Maybe includes a symbol
+                               symbol = *p.sy++;
+
+                       if (obj_format == BSD)
+                       {
+                               raddr = loc;                                    // Set relocation address
+
+                               if (validsegment)
+                                       D_long(raddr);                               // Write relocation address
+
+                               if (w & MPCREL)
+                                       rflag = 0x000000A0;                          // PC-relative fixup
+                               else
+                                       rflag = 0x00000040;                          // Absolute fixup
+
+                               if (w & MMOVEI)
+                                       rflag |= 0x00000001;
+                       }
+
+                       // Compute mark position in relocation information;
+                       // in RELMOD mode, get address of data to fix up.
+                       if (from == DATA)
+                               loc += tsize;
+
+                       wp = (char *)(mp + loc);
+
+                       if (symbol)
+                       {
+                               // Deposit external reference
+                               if (obj_format == BSD)
+                               {
+                                       rflag |= 0x00000010;                         // Set external reloc flag bit
+                                       rflag |= (symbol->senv << 8);                // Put symbol index in flags
+
+                                       if (symbol->sattre & RISCSYM)
+                                               rflag |= 0x00000001;
+
+                                       if (validsegment)
+                                       {
+                                               D_long(rflag);                            // Write relocation flags
+                                               rsize += 8;                               // Increment relocation size
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if (obj_format == BSD)
+                               {
+                                       w &= TDB;                                    // Set reloc flags to segment
+
+                                       switch (w)
+                                       {
+                                       case TEXT: rflag |= 0x00000400; break;
+                                       case DATA: rflag |= 0x00000600; break;
+                                       case BSS:  rflag |= 0x00000800; break;
+                                       }
+
+                                       if (validsegment)
+                                       {
+                                               D_long(rflag);                            // Write relocation flags
+                                               rsize += 8;                               // Increment relocation size
+                                       }
+
+                                       w &= TDB;
+
+                                       if (validsegment)
+                                       {
+                                               if (w & (DATA|BSS))
+                                               {
+                                                       dp = objimage + BSDHDRSIZE + loc;
+                                                       diff = ((LONG)(*dp++ & 0xFF)) << 24;
+                                                       diff |= ((LONG)(*dp++ & 0xFF)) << 16;
+                                                       diff |= ((LONG)(*dp++ & 0xFF)) << 8;
+                                                       diff |= (LONG)(*dp & 0xFF);
+                                                       DEBUG printf("diff=%ux ==> ", diff);
+       
+                                                       if (rflag & 0x01)
+                                                               diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
+
+                                                       diff += sect[TEXT].sloc;
+
+                                                       if (w == BSS)
+                                                               diff += sect[DATA].sloc;
+
+                                                       if (rflag & 0x01)
+                                                               diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
+
+                                                       dp = objimage + BSDHDRSIZE + loc;
+                                                       *dp++ = (char)(diff >> 24);
+                                                       *dp++ = (char)(diff >> 16);
+                                                       *dp++ = (char)(diff >> 8);
+                                                       *dp = (char)diff;
+                                                       DEBUG printf("%ux\n", diff);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // Return relocation size
+       if (obj_format == BSD)
+               return rsize;                                        
+
+       return siz;
 }
diff --git a/mark.h b/mark.h
index a5af238d2ea1d679389e1e3d5cad85ac0303079f..230a77b3a6c69660c7d8613bb156d8395a1dce13 100644 (file)
--- a/mark.h
+++ b/mark.h
@@ -12,7 +12,7 @@
 #include "rmac.h"
 #include "sect.h"
 
-#define MARK_ALLOC_INCR 1024                                // #bytes to alloc for more mark space 
+#define MARK_ALLOC_INCR 1024           // #bytes to alloc for more mark space 
 #define MIN_MARK_MEM    (3*sizeof(WORD)+2*sizeof(LONG))
 
 // Globals, Externals etc
index 9a750ddaa6c638978e25447a081d84cb3165cae3..2148b5f054891351f9bcfdb94d8d1c0b9185e926 100644 (file)
--- a/object.c
+++ b/object.c
@@ -133,6 +133,7 @@ int object(WORD fd)
 
                // Construct TEXT and DATA segments (without relocation changes)
                p = buf + BSDHDRSIZE;
+
                for(i=TEXT; i<=DATA; ++i)
                {
                        for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
index 01f4dadd2f1fcccb3bdefc3cfc72053d1c0db55f..dfb3035851143fdc30002f69e729c1b4bcbe00df 100644 (file)
--- a/object.h
+++ b/object.h
@@ -14,7 +14,7 @@
 #define BSDHDRSIZE   0x20                                   // Size of BSD header
 
 // Globals, externals etc
-extern char *objimage;
+extern char * objimage;
 
 // Prototypes
 int object(WORD);
index 108959237367d88a77774b03df03bdf84ada9f64..4637d72dda1bca9613a2484de82f4bf68ffb9f4c 100644 (file)
--- a/parmode.h
+++ b/parmode.h
 // Source Utilised with the Kind Permission of Landon Dyer
 //
 
-// This file is included (twice) to parse two addressing modes, into slightly different var names
+// This file is included (twice) to parse two addressing modes, into slightly
+// different var names
 {
-   // Dn
-   // An
-   // # expression
-   if((*tok >= KW_D0) && (*tok <= KW_D7)) {
-      AMn = DREG;
-      AnREG = *tok++ & 7;
-   } else if((*tok >= KW_A0) && (*tok <= KW_A7)) {
-      AMn = AREG;
-      AnREG = *tok++ & 7;
-   } else if(*tok == '#') {
-      ++tok;
-      if(expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
-         return(ERROR);
-      AMn = IMMED;
-   }
-   // (An)
-   // (An)+
-   // (An,Xn[.siz][*scale])
-   // (PC,Xn[.siz][*scale])
-   // (d16,An)
-   // (d8,An,Xn[.siz][*scale])
-   // (d16,PC)
-   // (d8,PC,Xn[.siz][*scale])
-   // ([bd,An],Xn,od)
-   // ([bd,An,Xn],od)
-   // ([bd,PC],Xn,od)
-   // ([bd,PC,Xn],od)
-   else if(*tok == '(') {
-      ++tok;
-      if((*tok >= KW_A0) && (*tok <= KW_A7)) {
-         AnREG = *tok++ & 7;
-         if(*tok == ')') {
-            ++tok;
-            if(*tok == '+') {
-               ++tok;
-               AMn = APOSTINC;
-            } else AMn = AIND;
-            goto AnOK;
-         }
-         AMn = AINDEXED;
-         goto AMn_IX0;                                      // Handle ",Xn[.siz][*scale])"
-      } else if(*tok == KW_PC) {                            // (PC,Xn[.siz][*scale]) 
-         ++tok;
-         AMn = PCINDEXED;
-
-         // Common index handler; enter here with `tok' pointing at the comma.
-
-         AMn_IX0:                                           // Handle indexed with missing expr
-
-         AnEXVAL = 0;
-         AnEXATTR = ABS | DEFINED;
-
-         AMn_IXN:                                           // Handle any indexed (tok -> a comma)
-
-         if(*tok++ != ',')
-            goto badmode;
-         if(*tok < KW_D0 || *tok > KW_A7)
-            goto badmode;
-         AnIXREG = *tok++ & 15;
-
-         switch((int)*tok)     {                                // Index reg size: <empty> | .W | .L 
-            case DOTW:
-               ++tok;
-            default:
-               AnIXSIZ = 0;
-               break;
-            case DOTL:
-               AnIXSIZ = 0x0800;
-               ++tok;
-               break;
-            case DOTB:                                      // .B not allowed here...
-               goto badmode;
-         }
-
-         if(*tok == '*') {                                  // scale: *1, *2, *4, *8 
-            ++tok;
-            if(*tok++ != CONST || *tok > 8)
-               goto badmode;
-
-            switch((int)*tok++) {
-               case 1:
-                  break;
-               case 2:
-                  AnIXSIZ |= TIMES2;
-                  break;
-               case 4:
-                  AnIXSIZ |= TIMES4;
-                  break;
-               case 8:
-                  AnIXSIZ |= TIMES8;
-                  break;
-               default:
-                  goto badmode;
-            }
-         }
-
-         if(*tok++ != ')')                                  // final ")" 
-            goto badmode;
-         goto AnOK;
-      } else if(*tok == '[') {                              // ([... 
-         goto unmode;
-      } else {                                              // (expr... 
-         if(expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
-            return ERROR;
-         if(*tok++ != ',')
-            goto badmode;
-
-         if((*tok >= KW_A0) && (*tok <= KW_A7)) {
-            AnREG = *tok & 7;
-            ++tok;
-            if(*tok == ',') {
-               AMn = AINDEXED;
-               goto AMn_IXN;
-            } else if(*tok == ')') {
-               AMn = ADISP;
-               ++tok;
-               goto AnOK;
-            } else goto badmode;
-         } else if(*tok == KW_PC) {
-            if(*++tok == ',') {                             // expr(PC,Xn...)
-               AMn = PCINDEXED;
-               goto AMn_IXN;
-            } else if(*tok == ')') {
-               AMn = PCDISP;                                // expr(PC) 
-               ++tok;
-               goto AnOK;
-            } else goto badmode;
-         } else goto badmode;
-      }
-   } else if(*tok=='-' && tok[1]=='(' && ((tok[2]>=KW_A0) && (tok[2]<=KW_A7)) && tok[3]==')') {
-      AMn = APREDEC;
-      AnREG = tok[2] & 7;
-      tok += 4;
-   } else if(*tok == KW_CCR) {
-      AMn = AM_CCR;
-      ++tok;
-      goto AnOK;
-   } else if(*tok == KW_SR) {
-      AMn = AM_SR;
-      ++tok;
-      goto AnOK;
-   } else if(*tok == KW_USP) {
-      AMn = AM_USP;
-      ++tok;
-      goto AnOK;
-   }
-   // expr
-   // expr.w
-   // expr.l
-   // d16(An)
-   // d8(An,Xn[.siz])
-   // d16(PC)
-   // d8(PC,Xn[.siz])
-   else {
-      if(expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
-         return ERROR;
-
-      if(*tok == DOTW) {                                    // expr.W 
-         ++tok;
-         AMn = ABSW;
-         goto AnOK;
-      } else if(*tok != '(') {                              // expr[.L]
-         AMn = ABSL;
-         // Defined, absolute values from $FFFF8000..$00007FFF get optimized to absolute short
-         if((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
-            AMn = ABSW;
-
-         if(*tok == DOTL) {                                 // force .L 
-            ++tok;
-            AMn = ABSL;
-         }
-         goto AnOK;
-      }
-
-      ++tok;
-      if((*tok >= KW_A0) && (*tok <= KW_A7)) {
-         AnREG = *tok++ & 7;
-         if(*tok == ')') {
-            AMn = ADISP;
-            ++tok;
-            goto AnOK;
-         }
-         AMn = AINDEXED;
-         goto AMn_IXN;
-      } else if(*tok == KW_PC) {
-         if(*++tok == ')') {
-            AMn = PCDISP;
-            ++tok;
-            goto AnOK;
-         }
-         AMn = PCINDEXED;
-         goto AMn_IXN;
-      }
-      goto badmode;
-   }
-
-   // Addressing mode OK
-
-   AnOK:
-   ;
+       // Dn
+       // An
+       // # expression
+       if ((*tok >= KW_D0) && (*tok <= KW_D7))
+       {
+               AMn = DREG;
+               AnREG = *tok++ & 7;
+       }
+       else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+       {
+               AMn = AREG;
+               AnREG = *tok++ & 7;
+       }
+       else if (*tok == '#')
+       {
+               ++tok;
+               if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                       return ERROR;
+
+               AMn = IMMED;
+       }
+       // (An)
+       // (An)+
+       // (An,Xn[.siz][*scale])
+       // (PC,Xn[.siz][*scale])
+       // (d16,An)
+       // (d8,An,Xn[.siz][*scale])
+       // (d16,PC)
+       // (d8,PC,Xn[.siz][*scale])
+       // ([bd,An],Xn,od)
+       // ([bd,An,Xn],od)
+       // ([bd,PC],Xn,od)
+       // ([bd,PC,Xn],od)
+       else if (*tok == '(')
+       {
+               ++tok;
+
+               if ((*tok >= KW_A0) && (*tok <= KW_A7))
+               {
+                       AnREG = *tok++ & 7;
+
+                       if (*tok == ')')
+                       {
+                               ++tok;
+
+                               if (*tok == '+')
+                               {
+                                       ++tok;
+                                       AMn = APOSTINC;
+                               }
+                               else
+                                       AMn = AIND;
+
+                               goto AnOK;
+                       }
+
+                       AMn = AINDEXED;
+                       goto AMn_IX0;                                      // Handle ",Xn[.siz][*scale])"
+               }
+               else if (*tok == KW_PC)
+               {                            // (PC,Xn[.siz][*scale]) 
+                       ++tok;
+                       AMn = PCINDEXED;
+
+                       // Common index handler; enter here with `tok' pointing at the comma.
+
+                       AMn_IX0:                                           // Handle indexed with missing expr
+
+                       AnEXVAL = 0;
+                       AnEXATTR = ABS | DEFINED;
+
+                       AMn_IXN:                                           // Handle any indexed (tok -> a comma)
+
+                       if (*tok++ != ',')
+                               goto badmode;
+
+                       if (*tok < KW_D0 || *tok > KW_A7)
+                               goto badmode;
+
+                       AnIXREG = *tok++ & 15;
+
+                       switch ((int)*tok)
+                       {                                // Index reg size: <empty> | .W | .L 
+                       case DOTW:
+                               ++tok;
+                       default:
+                               AnIXSIZ = 0;
+                               break;
+                       case DOTL:
+                               AnIXSIZ = 0x0800;
+                               ++tok;
+                               break;
+                       case DOTB:                                      // .B not allowed here...
+                               goto badmode;
+                       }
+
+                       if (*tok == '*')
+                       {                                  // scale: *1, *2, *4, *8 
+                               ++tok;
+                               if (*tok++ != CONST || *tok > 8)
+                                       goto badmode;
+
+                               switch ((int)*tok++)
+                               {
+                               case 1:
+                                       break;
+                               case 2:
+                                       AnIXSIZ |= TIMES2;
+                                       break;
+                               case 4:
+                                       AnIXSIZ |= TIMES4;
+                                       break;
+                               case 8:
+                                       AnIXSIZ |= TIMES8;
+                                       break;
+                               default:
+                                       goto badmode;
+                               }
+                       }
+
+                       if (*tok++ != ')')                                  // final ")" 
+                               goto badmode;
+
+                       goto AnOK;
+               }
+               else if (*tok == '[')
+               {                              // ([... 
+                       goto unmode;
+               }
+               else
+               {                                              // (expr... 
+                       if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                               return ERROR;
+
+                       if (*tok++ != ',')
+                               goto badmode;
+
+                       if ((*tok >= KW_A0) && (*tok <= KW_A7))
+                       {
+                               AnREG = *tok & 7;
+                               ++tok;
+
+                               if (*tok == ',')
+                               {
+                                       AMn = AINDEXED;
+                                       goto AMn_IXN;
+                               }
+                               else if (*tok == ')')
+                               {
+                                       AMn = ADISP;
+                                       ++tok;
+                                       goto AnOK;
+                               }
+                               else
+                                       goto badmode;
+                       }
+                       else if (*tok == KW_PC)
+                       {
+                               if (*++tok == ',')
+                               {                             // expr(PC,Xn...)
+                                       AMn = PCINDEXED;
+                                       goto AMn_IXN;
+                               }
+                               else if (*tok == ')')
+                               {
+                                       AMn = PCDISP;                                // expr(PC) 
+                                       ++tok;
+                                       goto AnOK;
+                               }
+                               else
+                                       goto badmode;
+                       }
+                       else
+                               goto badmode;
+               }
+       }
+       else if (*tok=='-' && tok[1]=='(' && ((tok[2]>=KW_A0) && (tok[2]<=KW_A7)) && tok[3]==')')
+       {
+               AMn = APREDEC;
+               AnREG = tok[2] & 7;
+               tok += 4;
+       }
+       else if (*tok == KW_CCR)
+       {
+               AMn = AM_CCR;
+               ++tok;
+               goto AnOK;
+       }
+       else if (*tok == KW_SR)
+       {
+               AMn = AM_SR;
+               ++tok;
+               goto AnOK;
+       }
+       else if (*tok == KW_USP)
+       {
+               AMn = AM_USP;
+               ++tok;
+               goto AnOK;
+       }
+       // expr
+       // expr.w
+       // expr.l
+       // d16(An)
+       // d8(An,Xn[.siz])
+       // d16(PC)
+       // d8(PC,Xn[.siz])
+       else
+       {
+               if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                       return ERROR;
+
+               if (*tok == DOTW)
+               {                                    // expr.W 
+                       ++tok;
+                       AMn = ABSW;
+                       goto AnOK;
+               }
+               else if (*tok != '(')
+               {                              // expr[.L]
+                       AMn = ABSL;
+                       // Defined, absolute values from $FFFF8000..$00007FFF get optimized to absolute short
+
+                       if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
+                               AMn = ABSW;
+
+                       if (*tok == DOTL)
+                       {                                 // force .L 
+                               ++tok;
+                               AMn = ABSL;
+                       }
+
+                       goto AnOK;
+               }
+
+               ++tok;
+
+               if ((*tok >= KW_A0) && (*tok <= KW_A7))
+               {
+                       AnREG = *tok++ & 7;
+
+                       if (*tok == ')')
+                       {
+                               AMn = ADISP;
+                               ++tok;
+                               goto AnOK;
+                       }
+
+                       AMn = AINDEXED;
+                       goto AMn_IXN;
+               }
+               else if (*tok == KW_PC)
+               {
+                       if (*++tok == ')')
+                       {
+                               AMn = PCDISP;
+                               ++tok;
+                               goto AnOK;
+                       }
+
+                       AMn = PCINDEXED;
+                       goto AMn_IXN;
+               }
+               goto badmode;
+       }
+
+       // Addressing mode OK
+
+       AnOK:
+       ;
 }
 
 // Cleanup dirty little macros
index f0abc54af621152b4ad92e72a53150c51c036d3a..d44517cf1b011e75e2337474dd96b89568613adc 100644 (file)
--- a/procln.c
+++ b/procln.c
 #define DECL_MR
 #include "risckw.h"
 
-IFENT *ifent;                                               // Current ifent
+IFENT * ifent;                                               // Current ifent
 static IFENT ifent0;                                        // Root ifent
-static IFENT *f_ifent;                                      // Freelist of ifents
+static IFENT * f_ifent;                                      // Freelist of ifents
 static int disabled;                                        // Assembly conditionally disabled
 int just_bss;                                               // 1, ds.b in microprocessor mode 
 VALUE pcloc;                                                // Value of "PC" at beginning of line 
-IFENT *ifent;                                               // Current ifent
-SYM *lab_sym;                                               // Label on line (or NULL)
+IFENT * ifent;                                               // Current ifent
+SYM * lab_sym;                                               // Label on line (or NULL)
 
 
 char extra_stuff[] = "extra (unexpected) text found after addressing mode";
-char *comma_error = "missing comma";
-char *syntax_error = "syntax error";
-char *locgl_error = "cannot GLOBL local symbol";
-char *lab_ignored = "label ignored";
+char * comma_error = "missing comma";
+char * syntax_error = "syntax error";
+char * locgl_error = "cannot GLOBL local symbol";
+char * lab_ignored = "label ignored";
 
 // Table to convert an addressing-mode number to a bitmask.
 LONG amsktab[0112] = {
-   M_DREG, M_DREG, M_DREG, M_DREG,
-   M_DREG, M_DREG, M_DREG, M_DREG,
-
-   M_AREG, M_AREG, M_AREG, M_AREG,
-   M_AREG, M_AREG, M_AREG, M_AREG,
-
-   M_AIND, M_AIND, M_AIND, M_AIND,
-   M_AIND, M_AIND, M_AIND, M_AIND,
-
-   M_APOSTINC, M_APOSTINC, M_APOSTINC, M_APOSTINC,
-   M_APOSTINC, M_APOSTINC, M_APOSTINC, M_APOSTINC,
-
-   M_APREDEC, M_APREDEC, M_APREDEC, M_APREDEC,
-   M_APREDEC, M_APREDEC, M_APREDEC, M_APREDEC,
-
-   M_ADISP, M_ADISP, M_ADISP, M_ADISP,
-   M_ADISP, M_ADISP, M_ADISP, M_ADISP,
-
-   M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED,
-   M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED,
-
-   M_ABSW,                                                  // 070
-   M_ABSL,                                                  // 071
-   M_PCDISP,                                                // 072
-   M_PCINDEXED,                                             // 073
-   M_IMMED,                                                 // 074
-   0L,                                                      // 075
-   0L,                                                      // 076
-   0L,                                                      // 077
-   M_ABASE,                                                 // 0100
-   M_MEMPOST,                                               // 0101 
-   M_MEMPRE,                                                // 0102 
-   M_PCBASE,                                                // 0103
-   M_PCMPOST,                                               // 0104
-   M_PCMPRE,                                                // 0105
-   M_AM_USP,                                                // 0106
-   M_AM_SR,                                                 // 0107 
-   M_AM_CCR,                                                // 0110
-   M_AM_NONE                                                // 0111 
+       M_DREG, M_DREG, M_DREG, M_DREG,
+       M_DREG, M_DREG, M_DREG, M_DREG,
+
+       M_AREG, M_AREG, M_AREG, M_AREG,
+       M_AREG, M_AREG, M_AREG, M_AREG,
+
+       M_AIND, M_AIND, M_AIND, M_AIND,
+       M_AIND, M_AIND, M_AIND, M_AIND,
+
+       M_APOSTINC, M_APOSTINC, M_APOSTINC, M_APOSTINC,
+       M_APOSTINC, M_APOSTINC, M_APOSTINC, M_APOSTINC,
+
+       M_APREDEC, M_APREDEC, M_APREDEC, M_APREDEC,
+       M_APREDEC, M_APREDEC, M_APREDEC, M_APREDEC,
+
+       M_ADISP, M_ADISP, M_ADISP, M_ADISP,
+       M_ADISP, M_ADISP, M_ADISP, M_ADISP,
+
+       M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED,
+       M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED,
+
+       M_ABSW,                                                  // 070
+       M_ABSL,                                                  // 071
+       M_PCDISP,                                                // 072
+       M_PCINDEXED,                                             // 073
+       M_IMMED,                                                 // 074
+       0L,                                                      // 075
+       0L,                                                      // 076
+       0L,                                                      // 077
+       M_ABASE,                                                 // 0100
+       M_MEMPOST,                                               // 0101 
+       M_MEMPRE,                                                // 0102 
+       M_PCBASE,                                                // 0103
+       M_PCMPOST,                                               // 0104
+       M_PCMPRE,                                                // 0105
+       M_AM_USP,                                                // 0106
+       M_AM_SR,                                                 // 0107 
+       M_AM_CCR,                                                // 0110
+       M_AM_NONE                                                // 0111 
 };                                                          // 0112 length
 
+
 //
-// --- Initialize Line Processor -------------------------------------------------------------------
+// Initialize Line Processor
 //
-
-void init_procln(void) {
-   disabled = 0;
-   ifent = &ifent0;
-   f_ifent = ifent0.if_prev = NULL;
-   ifent0.if_state = 0;
+void init_procln(void)
+{
+       disabled = 0;
+       ifent = &ifent0;
+       f_ifent = ifent0.if_prev = NULL;
+       ifent0.if_state = 0;
 }
 
+
 //
-// --- Line Processor ------------------------------------------------------------------------------
+// Line Processor
 //
-
-void assemble(void) {
-   int state;                                               // Keyword machine state (output)
-   int j;                                                   // Random int, must be fast
-   char *p;                                                 // Random char ptr, must be fast
-   TOKEN *tk;                                               // First token in line
-   char *label;                                             // Symbol (or NULL)
-   char *equate;                                            // Symbol (or NULL)
-   int labtyp = 0;                                          // Label type (':', DCOLON)
-   int equtyp = 0;                                          // Equ type ('=', DEQUALS)
-   VALUE eval;                                              // Expression value
-   WORD eattr;                                              // Expression attributes
-   SYM *esym;                                               // External symbol involved in expr.
-   WORD siz = 0;                                            // Size suffix to mnem/diretve/macro
-   LONG amsk0, amsk1;                                       // Address-type masks for ea0, ea1
-   MNTAB *m;                                                // Code generation table pointer
-   SYM *sy, *sy2;                                           // Symbol (temp usage)
-   char *opname = NULL;                                     // Name of dirctve/mnemonic/macro
-   int listflag;                                            // 0: Don't call listeol()
-   int as68mode = 0;                                        // 1: Handle multiple labels
-   WORD rmask;                                              // Register list, for REG
-   int registerbank;                                        // RISC register bank
-   int riscreg;                                             // RISC register
-
-   listflag = 0;                                            // Initialise listing flag
-
-   loop:                                                    // Line processing loop label
-
-   if(tokln() == TKEOF) {                                   // Get another line of tokens
-      if(list_flag && listflag)                             // Flush last line of source
-         listeol();
-      if(ifent->if_prev != NULL)                            // Check conditional token
-         error("hit EOF without finding matching .endif");
-      return;
-   }
-
-   if(list_flag) {
-      if(listflag && listing > 0) listeol();                // Tell listing generator about EOL
-      lstout((char)(disabled ? '-' : lntag));              // Prepare new line for listing
-      listflag = 1;                                         // OK to call `listeol' now
-      just_bss = 0;                                         // Reset just_bss mode
-   }
-
-   state = -3;                                              // No keyword (just EOL)
-   label = NULL;                                            // No label
-   lab_sym = NULL;                                          // No (exported) label
-   equate = NULL;                                           // No equate
-   tk = tok;                                                // Save first token in line
-   pcloc = (VALUE)sloc;                                     // Set beginning-of-line PC
-
-   loop1:                                                   // Internal line processing loop
-
-   if(*tok == EOL)                                          // Restart loop if end-of-line
-      goto loop;
-
-   if(*tok != SYMBOL) {                                     // First token MUST be a symbol
-      error(syntax_error);
-      goto loop;
-   }
-
-   j = (int)tok[2];                                         // Skip equates (normal statements)
-   if(j == '=' ||      j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF) {   
-      equate = (char *)tok[1];
-      equtyp = j;
-      tok += 3;
-      goto normal;
-   }
-
-   if(j == ':' || j == DCOLON) {                            // Skip past label (but record it)
-   
-      as68label:
-
-      label = (char *)tok[1];                               // Get label name
-      labtyp = tok[2];                                      // Get label type
-      tok += 3;                                             // Go to next line token
-
-      // Handle multiple labels; if there's another label, go process it, 
-      // and come back at `as68label' above.
-      if(as68_flag) {
-         as68mode = 0;
-         if(*tok == SYMBOL && tok[2] == ':') {
-            as68mode = 1;
-            goto do_label;
-         }
-      }
-   }
-
-   if(*tok == EOL)                                          // EOL is legal here...
-      goto normal;
-
-   if(*tok++ != SYMBOL) {                                   // Next token MUST be a symbol
-      error(syntax_error);
-      goto loop;
-   }
-   opname = p = (char *)*tok++;                             // Store opcode name here
-
-   // Check to see if the SYMBOL is a keyword (a mnemonic or directive).
-   // On output, `state' will have one of the values:
-   //    -3          there was no symbol (EOL)
-   //    -2..-1      the symbol didn't match any keyword
-   //    0..499      vanilla directives (dc, ds, etc.)
-   //    500..999    electric directives (macro, rept, etc.)
-   //    1000..+     mnemonics (move, lsr, etc.)
-   for(state = 0; state >= 0;) {
-      j = mnbase[state] + (int)tolowertab[*p];
-      if(mncheck[j] != state) {                             // Reject, character doesn't match
-         state = -1;                                        // No match
-         break;
-      }
-      if(!*++p) {                                           // Must accept or reject at EOS
-         state = mnaccept[j];                               // (-1 on no terminal match)
-         break;
-      }
-      state = mntab[j];
-   }
-
-   // Check for ".b" ".w" ".l" after directive, macro or mnemonic.
-   siz = SIZN;
-   if(*tok == DOTW) 
-      siz = SIZW, ++tok;
-   else if(*tok == DOTL)
-      siz = SIZL, ++tok;
-   else if(*tok == DOTB)
-      siz = SIZB, ++tok;
-
-   // Do special directives (500..999) (These must be handled in "real time")
-   if(state >= 500 && state < 1000)
-      switch(state) {
-         case MN_IF:
-            d_if();
-            goto loop;
-         case MN_ELSE:
-            d_else();
-            goto loop;
-         case MN_ENDIF:
-            d_endif();
-            goto loop;
-         case MN_IIF:                                       // .iif --- immediate if
-            if(disabled || expr(exprbuf, &eval, &eattr, &esym) != OK)
-               goto loop;
-            if(!(eattr & DEFINED)) {
-               error(undef_error);
-               goto loop;
-            }
-            if(*tok++ != ',') {
-               error(comma_error);
-               goto loop;
-            }
-            if(eval == 0)
-               goto loop;
-            goto loop1;
-         case MN_MACRO:                                     // .macro --- macro definition
-            if(!disabled) {
-               if(label != NULL)
-                  warn(lab_ignored);
-               defmac();
-            }
-            goto loop;
-         case MN_EXITM:                                     // .exitm --- exit macro
-         case MN_ENDM:                                      // .endm --- same as .exitm
-            if(!disabled) {
-               if(label != NULL)
-                  warn(lab_ignored);
-               exitmac();
-            }
-            goto loop;
-         case MN_REPT:
-            if(!disabled) {
-               if(label != NULL)
-                  warn(lab_ignored);
-               defrept();
-            }
-            goto loop;
-         case MN_ENDR:
-            if(!disabled)
-               error("mis-nested .endr");
-            goto loop;
-      }
-
-   normal:
-
-   if(disabled)                                             // Conditionally disabled code
-      goto loop;
-
-   // Do equates
-   if(equate != NULL) {
-      j = 0;                                                // Pick global or local sym enviroment
-      if(*equate == '.')
-         j = curenv;
-
-      sy = lookup(equate, LABEL, j);
-      if(sy == NULL) {
-         sy = newsym(equate, LABEL, j);
-         sy->sattr = 0;
-         if(equtyp == DEQUALS) {
-            if(j) {                                         // Can't GLOBAL a local symbol
-               error(locgl_error);
-               goto loop;
-            }
-            sy->sattr = GLOBAL;
-         }
-      } else if((sy->sattr & DEFINED) && equtyp != SET) {
-         if((equtyp == EQUREG) && (sy->sattre & UNDEF_EQUR)) {
-            sy->sattre |= ~UNDEF_EQUR; 
-            sy->svalue  = 0;
-         } else if((equtyp == CCDEF) && (sy->sattre & UNDEF_CC)) {
-            sy->sattre |= ~UNDEF_CC;
-            sy->svalue = 0;
-         } else {
-            errors("multiple equate to '%s'", sy->sname);
-            goto loop;
-         }
-      }
-
-      // Put symbol in "order of definition" list
-      if(!(sy->sattr & SDECLLIST)) sym_decl(sy);
-
-      // Parse value to equate symbol to;
-      // o  .equr
-      // o  .reg
-      // o  everything else
-      if(equtyp == EQUREG) {
-         if(!rgpu && !rdsp) {                               // Check that we are in a RISC section
-            error(".equr/.regequ must be defined in .gpu/.dsp section");
-            goto loop;
-         }
-         if((*tok >= KW_R0) && (*tok <= KW_R31)) {          // Check for register to equate to
-            sy->sattre  = EQUATEDREG | RISCSYM;             // Mark as equated register
-            riscreg = (*tok - KW_R0);
-            sy->sattre |= (riscreg << 8);                   // Store register number
-            if((tok[1] == ',') && (tok[2] == CONST)) {
-               tok += 3;
-               if(*tok == 0) registerbank = BANK_0;
-               else if(*tok == 1) registerbank = BANK_1;
-               else registerbank = BANK_N;
-            } else {
-               registerbank = BANK_N;
-            }
-            sy->sattre |= regbank;                          // Store register bank
-            eattr = ABS | DEFINED | GLOBAL;
-            eval = 0x80000080 + (riscreg) + (registerbank << 8);
-            tok++;
-         } else if(tok[0] == SYMBOL) {                      // Checking for a register symbol
-            sy2 = lookup((char *)tok[1], LABEL, j);
-            if(!sy2 || !(sy2->sattre & EQUATEDREG)) {       // Make sure symbol is a valid equreg
-               error("invalid GPU/DSP .equr/.regequ definition");
-               goto loop;
-            } else {
-               eattr = ABS | DEFINED | GLOBAL;              // Copy symbols attributes
-               sy->sattre = sy2->sattre;
-               eval = (sy2->svalue & 0xFFFFF0FF);
-               tok += 2;
-            }
-         } else {
-            error("invalid GPU/DSP .equr/.regequ definition");
-            goto loop;
-         }
-      } else if(equtyp == REG) {
-         if(reglist(&rmask) < 0)
-            goto loop;
-         eval = (VALUE)rmask;
-         eattr = ABS | DEFINED;
-      } else if(equtyp == CCDEF) {
-         sy->sattre |= EQUATEDCC;
-         eattr = ABS | DEFINED | GLOBAL;
-         if(tok[0] == SYMBOL) {
-            sy2 = lookup((char *)tok[1], LABEL, j);
-            if(!sy2 || !(sy2->sattre & EQUATEDCC)) {
-               error("invalid gpu/dsp .ccdef definition");
-               goto loop;
-            } else {
-               eattr = ABS | DEFINED | GLOBAL;
-               sy->sattre = sy2->sattre;
-               eval = sy2->svalue;
-               tok += 2;
-            }
-         } else
-            if(expr(exprbuf, &eval, &eattr, &esym) != OK)
-               goto loop;
-      } else if(*tok == SYMBOL) {  //equ a equr
-         sy2 = lookup((char *)tok[1], LABEL, j);
-         if(sy2 && (sy2->sattre & EQUATEDREG)) {
-            sy->stype = sy2->stype;
-            sy->sattr = sy2->sattr;
-            sy->sattre = sy2->sattre;
-            sy->svalue = (sy2->svalue & 0xFFFFF0FF);
-            goto loop;
-         } else 
-            if(expr(exprbuf, &eval, &eattr, &esym) != OK)
-               goto loop;
-      } else
-         if(expr(exprbuf, &eval, &eattr, &esym) != OK)
-            goto loop;
-
-      if(!(eattr & DEFINED)) {
-         error(undef_error);
-         goto loop;
-      }
-
-      
-      sy->sattr |= eattr | EQUATED;                         // Symbol inherits value and attributes
-      sy->svalue = eval;
-      if(list_flag)                                         // Put value in listing
-         listvalue(eval);
-
-      at_eol();                                             // Must be at EOL now
-      goto loop;
-   }
-
-   // Do labels
-   if(label != NULL) {
-
-      do_label:
-
-      j = 0;
-      if(*label == '.')
-         j = curenv;
-      sy = lookup(label, LABEL, j);
-
-      if(sy == NULL) {
-         sy = newsym(label, LABEL, j);
-         sy->sattr = 0;
-         sy->sattre = RISCSYM;
-      } else if(sy->sattr & DEFINED) {
-         errors("multiply-defined label '%s'", label);
-         goto loop;
-      }
-
-      // Put symbol in "order of definition" list
-      if(!(sy->sattr & SDECLLIST)) sym_decl(sy);
-
-      if(orgactive) {
-         sy->svalue = orgaddr;
-         sy->sattr |= ABS | DEFINED | EQUATED;
-      } else {
-         sy->svalue = sloc;
-         sy->sattr |= DEFINED | cursect;
-      }
-
-      lab_sym = sy;
-      if(!j)
-         ++curenv;
-
-      if(labtyp == DCOLON) {                                // Make label global
-         if(j) {
-            error(locgl_error);
-            goto loop;
-         }
-         sy->sattr |= GLOBAL;
-      }
-
-      // If we're in as68 mode, and there's another label, go back and handle it
-      if(as68_flag && as68mode)
-         goto as68label;
-   }
-
-   // Punt on EOL
-   if(state == -3)
-      goto loop;
-
-   // If we are in GPU or DSP mode and still in need of a mnemonic then search for one
-   if((rgpu || rdsp) && (state < 0 || state >= 1000)) {
-      for(state = 0, p = opname; state >= 0;) {
-         j = mrbase[state] + (int)tolowertab[*p];
-         if(mrcheck[j] != state)       {                          // Reject, character doesn't match
-            state = -1;                                     // No match
-            break;
-         }
-
-         if(!*++p) {                                        // Must accept or reject at EOS
-            state = mraccept[j];                            // (-1 on no terminal match)
-            break;
-         }
-         state = mrtab[j];
-      }
-
-      // Call RISC code generator if we found a mnemonic
-      if(state >= 3000) {
-         risccg(state);
-         goto loop;
-      }
-   }
-
-   // Invoke macro or complain about bad mnemonic
-   if(state < 0) {
-      if((sy = lookup(opname, MACRO, 0)) != NULL) 
-         invokemac(sy, siz);
-      else errors("unknown op '%s'", opname);
-      goto loop;
-   }
-
-   // Call directive handlers
-   if(state < 500) {
-      (*dirtab[state])(siz);
-      goto loop;
-   }
-
-   // Do mnemonics
-   // o  can't deposit instrs in BSS or ABS
-   // o  do automatic .EVEN for instrs
-   // o  allocate space for largest possible instr
-   // o  can't do ".b" operations with an address register
-   if(scattr & SBSS) {
-      error("cannot initialize non-storage (BSS) section");
-      goto loop;
-   }
-
-   if(sloc & 1)                                             // Automatic .even
-      auto_even();
-
-   if(challoc - ch_size < 18)                               // Make sure have space in current chunk
-      chcheck(0L);
-
-   m = &machtab[state - 1000];
-   if(m->mnattr & CGSPECIAL) {                              // Call special-mode handler
-      (*m->mnfunc)(m->mninst, siz);
-      goto loop;
-   }
-
-   if(amode(1) < 0)                                         // Parse 0, 1 or 2 addr modes
-      goto loop;
-
-   if(*tok != EOL)
-      error(extra_stuff);
-
-   amsk0 = amsktab[am0];
-   amsk1 = amsktab[am1];
-
-   // Catch attempts to use ".B" with an address register (yes, this check does work at this level)
-   if(siz == SIZB && (am0 == AREG || am1 == AREG)) {
-      error("cannot use '.b' with an address register");
-      goto loop;
-   }
-
-   for(;;) {
-      if((m->mnattr & siz) && (amsk0 & m->mn0) != 0 && (amsk1 & m->mn1) != 0) {
-         (*m->mnfunc)(m->mninst, siz);
-         goto loop;
-      }
-      m = &machtab[m->mncont];
-   }
+void assemble(void)
+{
+       int state;                                               // Keyword machine state (output)
+       int j;                                                   // Random int, must be fast
+       char * p;                                                // Random char ptr, must be fast
+       TOKEN * tk;                                              // First token in line
+       char * label;                                            // Symbol (or NULL)
+       char * equate;                                           // Symbol (or NULL)
+       int labtyp = 0;                                          // Label type (':', DCOLON)
+       int equtyp = 0;                                          // Equ type ('=', DEQUALS)
+       VALUE eval;                                              // Expression value
+       WORD eattr;                                              // Expression attributes
+       SYM * esym;                                              // External symbol involved in expr.
+       WORD siz = 0;                                            // Size suffix to mnem/diretve/macro
+       LONG amsk0, amsk1;                                       // Address-type masks for ea0, ea1
+       MNTAB * m;                                               // Code generation table pointer
+       SYM * sy, * sy2;                                         // Symbol (temp usage)
+       char * opname = NULL;                                    // Name of dirctve/mnemonic/macro
+       int listflag;                                            // 0: Don't call listeol()
+       int as68mode = 0;                                        // 1: Handle multiple labels
+       WORD rmask;                                              // Register list, for REG
+       int registerbank;                                        // RISC register bank
+       int riscreg;                                             // RISC register
+
+       listflag = 0;                                            // Initialise listing flag
+
+loop:                                                        // Line processing loop label
+
+       if (tokln() == TKEOF)
+       {                                   // Get another line of tokens
+               if (list_flag && listflag)                             // Flush last line of source
+                       listeol();
+
+               if (ifent->if_prev != NULL)                            // Check conditional token
+                       error("hit EOF without finding matching .endif");
+
+               return;
+       }
+
+       if (list_flag)
+       {
+               if (listflag && listing > 0)
+                       listeol();                // Tell listing generator about EOL
+
+               lstout((char)(disabled ? '-' : lntag));             // Prepare new line for listing
+               listflag = 1;                                         // OK to call `listeol' now
+               just_bss = 0;                                         // Reset just_bss mode
+       }
+
+       state = -3;                                              // No keyword (just EOL)
+       label = NULL;                                            // No label
+       lab_sym = NULL;                                          // No (exported) label
+       equate = NULL;                                           // No equate
+       tk = tok;                                                // Save first token in line
+       pcloc = (VALUE)sloc;                                     // Set beginning-of-line PC
+
+       loop1:                                                   // Internal line processing loop
+
+       if (*tok == EOL)                                          // Restart loop if end-of-line
+               goto loop;
+
+       if (*tok != SYMBOL)
+       {                                     // First token MUST be a symbol
+               error(syntax_error);
+               goto loop;
+       }
+
+       j = (int)tok[2];                                         // Skip equates (normal statements)
+
+       if (j == '=' || j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF)
+       {
+               equate = (char *)tok[1];
+               equtyp = j;
+               tok += 3;
+               goto normal;
+       }
+
+       if (j == ':' || j == DCOLON)
+       {                            // Skip past label (but record it)
+as68label:
+               label = (char *)tok[1];                               // Get label name
+               labtyp = tok[2];                                      // Get label type
+               tok += 3;                                             // Go to next line token
+
+               // Handle multiple labels; if there's another label, go process it, 
+               // and come back at `as68label' above.
+               if (as68_flag)
+               {
+                       as68mode = 0;
+
+                       if (*tok == SYMBOL && tok[2] == ':')
+                       {
+                               as68mode = 1;
+                               goto do_label;
+                       }
+               }
+       }
+
+       if (*tok == EOL)                                          // EOL is legal here...
+               goto normal;
+
+       if (*tok++ != SYMBOL)
+       {                                   // Next token MUST be a symbol
+               error(syntax_error);
+               goto loop;
+       }
+
+       opname = p = (char *)*tok++;                             // Store opcode name here
+
+       // Check to see if the SYMBOL is a keyword (a mnemonic or directive).
+       // On output, `state' will have one of the values:
+       //    -3          there was no symbol (EOL)
+       //    -2..-1      the symbol didn't match any keyword
+       //    0..499      vanilla directives (dc, ds, etc.)
+       //    500..999    electric directives (macro, rept, etc.)
+       //    1000..+     mnemonics (move, lsr, etc.)
+       for(state=0; state>=0;)
+       {
+               j = mnbase[state] + (int)tolowertab[*p];
+
+               if (mncheck[j] != state)
+               {                             // Reject, character doesn't match
+                       state = -1;                                        // No match
+                       break;
+               }
+
+               if (!*++p)
+               {                                           // Must accept or reject at EOS
+                       state = mnaccept[j];                               // (-1 on no terminal match)
+                       break;
+               }
+
+               state = mntab[j];
+       }
+
+       // Check for ".b" ".w" ".l" after directive, macro or mnemonic.
+       siz = SIZN;
+
+       if (*tok == DOTW) 
+               siz = SIZW, ++tok;
+       else if (*tok == DOTL)
+               siz = SIZL, ++tok;
+       else if (*tok == DOTB)
+               siz = SIZB, ++tok;
+
+       // Do special directives (500..999) (These must be handled in "real time")
+       if (state >= 500 && state < 1000)
+       {
+               switch (state)
+               {
+               case MN_IF:
+                       d_if ();
+               goto loop;
+               case MN_ELSE:
+                       d_else();
+                       goto loop;
+               case MN_ENDIF:
+                       d_endif ();
+                       goto loop;
+               case MN_IIF:                                       // .iif --- immediate if
+                       if (disabled || expr(exprbuf, &eval, &eattr, &esym) != OK)
+                               goto loop;
+
+                       if (!(eattr & DEFINED))
+                       {
+                               error(undef_error);
+                               goto loop;
+                       }
+
+                       if (*tok++ != ',')
+                       {
+                               error(comma_error);
+                               goto loop;
+                       }
+
+                       if (eval == 0)
+                               goto loop;
+
+                       goto loop1;
+               case MN_MACRO:                                     // .macro --- macro definition
+                       if (!disabled)
+                       {
+                               if (label != NULL)
+                                       warn(lab_ignored);
+
+                               defmac();
+                       }
+
+                       goto loop;
+               case MN_EXITM:                                     // .exitm --- exit macro
+               case MN_ENDM:                                      // .endm --- same as .exitm
+                       if (!disabled)
+                       {
+                               if (label != NULL)
+                                       warn(lab_ignored);
+
+                               exitmac();
+                       }
+
+                       goto loop;
+               case MN_REPT:
+                       if (!disabled)
+                       {
+                               if (label != NULL)
+                                       warn(lab_ignored);
+
+                               defrept();
+                       }
+
+                       goto loop;
+               case MN_ENDR:
+                       if (!disabled)
+                               error("mis-nested .endr");
+
+                       goto loop;
+               }
+       }
+
+normal:
+       if (disabled)                                             // Conditionally disabled code
+               goto loop;
+
+       // Do equates
+       if (equate != NULL)
+       {
+               j = 0;                                                // Pick global or local sym enviroment
+
+               if (*equate == '.')
+                       j = curenv;
+
+               sy = lookup(equate, LABEL, j);
+
+               if (sy == NULL)
+               {
+                       sy = newsym(equate, LABEL, j);
+                       sy->sattr = 0;
+
+                       if (equtyp == DEQUALS)
+                       {
+                               if (j)
+                               {                                         // Can't GLOBAL a local symbol
+                                       error(locgl_error);
+                                       goto loop;
+                               }
+
+                               sy->sattr = GLOBAL;
+                       }
+               }
+               else if ((sy->sattr & DEFINED) && equtyp != SET)
+               {
+                       if ((equtyp == EQUREG) && (sy->sattre & UNDEF_EQUR))
+                       {
+                               sy->sattre |= ~UNDEF_EQUR; 
+                               sy->svalue  = 0;
+                       }
+                       else if ((equtyp == CCDEF) && (sy->sattre & UNDEF_CC))
+                       {
+                               sy->sattre |= ~UNDEF_CC;
+                               sy->svalue = 0;
+                       }
+                       else
+                       {
+                               errors("multiple equate to '%s'", sy->sname);
+                               goto loop;
+                       }
+               }
+
+               // Put symbol in "order of definition" list
+               if (!(sy->sattr & SDECLLIST))
+                       sym_decl(sy);
+
+               // Parse value to equate symbol to;
+               // o  .equr
+               // o  .reg
+               // o  everything else
+               if (equtyp == EQUREG)
+               {
+                       if (!rgpu && !rdsp)
+                       {                               // Check that we are in a RISC section
+                               error(".equr/.regequ must be defined in .gpu/.dsp section");
+                               goto loop;
+                       }
+
+                       if ((*tok >= KW_R0) && (*tok <= KW_R31))
+                       {          // Check for register to equate to
+                               sy->sattre  = EQUATEDREG | RISCSYM;             // Mark as equated register
+                               riscreg = (*tok - KW_R0);
+                               sy->sattre |= (riscreg << 8);                   // Store register number
+
+                               if ((tok[1] == ',') && (tok[2] == CONST))
+                               {
+                                       tok += 3;
+
+                                       if (*tok == 0)
+                                               registerbank = BANK_0;
+                                       else if (*tok == 1)
+                                               registerbank = BANK_1;
+                                       else
+                                               registerbank = BANK_N;
+                               }
+                               else
+                               {
+                                       registerbank = BANK_N;
+                               }
+
+                               sy->sattre |= regbank;                          // Store register bank
+                               eattr = ABS | DEFINED | GLOBAL;
+                               eval = 0x80000080 + (riscreg) + (registerbank << 8);
+                               tok++;
+                       }
+                       else if (tok[0] == SYMBOL)
+                       {                      // Checking for a register symbol
+                               sy2 = lookup((char *)tok[1], LABEL, j);
+
+                               if (!sy2 || !(sy2->sattre & EQUATEDREG))
+                               {       // Make sure symbol is a valid equreg
+                                       error("invalid GPU/DSP .equr/.regequ definition");
+                                       goto loop;
+                               }
+                               else
+                               {
+                                       eattr = ABS | DEFINED | GLOBAL;              // Copy symbols attributes
+                                       sy->sattre = sy2->sattre;
+                                       eval = (sy2->svalue & 0xFFFFF0FF);
+                                       tok += 2;
+                               }
+                       }
+                       else
+                       {
+                               error("invalid GPU/DSP .equr/.regequ definition");
+                               goto loop;
+                       }
+               }
+               else if (equtyp == REG)
+               {
+                       if (reglist(&rmask) < 0)
+                               goto loop;
+
+                       eval = (VALUE)rmask;
+                       eattr = ABS | DEFINED;
+               }
+               else if (equtyp == CCDEF)
+               {
+                       sy->sattre |= EQUATEDCC;
+                       eattr = ABS | DEFINED | GLOBAL;
+
+                       if (tok[0] == SYMBOL)
+                       {
+                               sy2 = lookup((char *)tok[1], LABEL, j);
+
+                               if (!sy2 || !(sy2->sattre & EQUATEDCC))
+                               {
+                                       error("invalid gpu/dsp .ccdef definition");
+                                       goto loop;
+                               }
+                               else
+                               {
+                                       eattr = ABS | DEFINED | GLOBAL;
+                                       sy->sattre = sy2->sattre;
+                                       eval = sy2->svalue;
+                                       tok += 2;
+                               }
+                       }
+                       else if (expr(exprbuf, &eval, &eattr, &esym) != OK)
+                               goto loop;
+               }
+               else if (*tok == SYMBOL)
+               {  //equ a equr
+                       sy2 = lookup((char *)tok[1], LABEL, j);
+
+                       if (sy2 && (sy2->sattre & EQUATEDREG))
+                       {
+                               sy->stype = sy2->stype;
+                               sy->sattr = sy2->sattr;
+                               sy->sattre = sy2->sattre;
+                               sy->svalue = (sy2->svalue & 0xFFFFF0FF);
+                               goto loop;
+                       }
+                       else if (expr(exprbuf, &eval, &eattr, &esym) != OK)
+                               goto loop;
+               }
+               else if (expr(exprbuf, &eval, &eattr, &esym) != OK)
+                       goto loop;
+
+               if (!(eattr & DEFINED))
+               {
+                       error(undef_error);
+                       goto loop;
+               }
+
+               
+               sy->sattr |= eattr | EQUATED;                         // Symbol inherits value and attributes
+               sy->svalue = eval;
+               if (list_flag)                                         // Put value in listing
+                       listvalue(eval);
+
+               at_eol();                                             // Must be at EOL now
+               goto loop;
+       }
+
+       // Do labels
+       if (label != NULL)
+       {
+do_label:
+               j = 0;
+
+               if (*label == '.')
+                       j = curenv;
+
+               sy = lookup(label, LABEL, j);
+
+               if (sy == NULL)
+               {
+                       sy = newsym(label, LABEL, j);
+                       sy->sattr = 0;
+                       sy->sattre = RISCSYM;
+               }
+               else if (sy->sattr & DEFINED)
+               {
+                       errors("multiply-defined label '%s'", label);
+                       goto loop;
+               }
+
+               // Put symbol in "order of definition" list
+               if (!(sy->sattr & SDECLLIST))
+                       sym_decl(sy);
+
+               if (orgactive)
+               {
+                       sy->svalue = orgaddr;
+                       sy->sattr |= ABS | DEFINED | EQUATED;
+               }
+               else
+               {
+                       sy->svalue = sloc;
+                       sy->sattr |= DEFINED | cursect;
+               }
+
+               lab_sym = sy;
+
+               if (!j)
+                       ++curenv;
+
+               if (labtyp == DCOLON)
+               {                                // Make label global
+                       if (j)
+                       {
+                               error(locgl_error);
+                               goto loop;
+                       }
+
+                       sy->sattr |= GLOBAL;
+               }
+
+               // If we're in as68 mode, and there's another label, go back and handle it
+               if (as68_flag && as68mode)
+                       goto as68label;
+       }
+
+       // Punt on EOL
+       if (state == -3)
+               goto loop;
+
+       // If we are in GPU or DSP mode and still in need of a mnemonic then search for one
+       if ((rgpu || rdsp) && (state < 0 || state >= 1000))
+       {
+               for(state=0, p=opname; state>=0;)
+               {
+                       j = mrbase[state] + (int)tolowertab[*p];
+
+                       if (mrcheck[j] != state)
+                       {                          // Reject, character doesn't match
+                               state = -1;                                     // No match
+                               break;
+                       }
+
+                       if (!*++p)
+                       {                                        // Must accept or reject at EOS
+                               state = mraccept[j];                            // (-1 on no terminal match)
+                               break;
+                       }
+
+                       state = mrtab[j];
+               }
+
+               // Call RISC code generator if we found a mnemonic
+               if (state >= 3000)
+               {
+                       risccg(state);
+                       goto loop;
+               }
+       }
+
+       // Invoke macro or complain about bad mnemonic
+       if (state < 0)
+       {
+               if ((sy = lookup(opname, MACRO, 0)) != NULL) 
+                       invokemac(sy, siz);
+               else
+                       errors("unknown op '%s'", opname);
+
+               goto loop;
+       }
+
+       // Call directive handlers
+       if (state < 500)
+       {
+               (*dirtab[state])(siz);
+               goto loop;
+       }
+
+       // Do mnemonics
+       // o  can't deposit instrs in BSS or ABS
+       // o  do automatic .EVEN for instrs
+       // o  allocate space for largest possible instr
+       // o  can't do ".b" operations with an address register
+       if (scattr & SBSS)
+       {
+               error("cannot initialize non-storage (BSS) section");
+               goto loop;
+       }
+
+       if (sloc & 1)                                             // Automatic .even
+               auto_even();
+
+       if (challoc - ch_size < 18)                               // Make sure have space in current chunk
+               chcheck(0L);
+
+       m = &machtab[state - 1000];
+
+       if (m->mnattr & CGSPECIAL)
+       {                              // Call special-mode handler
+               (*m->mnfunc)(m->mninst, siz);
+               goto loop;
+       }
+
+       if (amode(1) < 0)                                         // Parse 0, 1 or 2 addr modes
+               goto loop;
+
+       if (*tok != EOL)
+               error(extra_stuff);
+
+       amsk0 = amsktab[am0];
+       amsk1 = amsktab[am1];
+
+       // Catch attempts to use ".B" with an address register (yes, this check does work at this level)
+       if (siz == SIZB && (am0 == AREG || am1 == AREG))
+       {
+               error("cannot use '.b' with an address register");
+               goto loop;
+       }
+
+       for(;;)
+       {
+               if ((m->mnattr & siz) && (amsk0 & m->mn0) != 0 && (amsk1 & m->mn1) != 0)
+               {
+                       (*m->mnfunc)(m->mninst, siz);
+                       goto loop;
+               }
+
+               m = &machtab[m->mncont];
+       }
 }
 
+
 // 
-// --- .if, Start Conditional Assembly -------------------------------------------------------------
+// .if, Start Conditional Assembly
 //
-
-int d_if(void) {
-   IFENT *rif;
-   WORD eattr;
-   VALUE eval;
-   SYM *esym;
-
-   // Alloc an IFENTRY
-   if((rif = f_ifent) == NULL) rif = (IFENT *)amem((LONG)sizeof(IFENT));
-   else f_ifent = rif->if_prev;
-
-   rif->if_prev = ifent;
-   ifent = rif;
-
-   if(!disabled) {
-      if(expr(exprbuf, &eval, &eattr, &esym) != OK) return(0);
-      if((eattr & DEFINED) == 0) return(error(undef_error));
-      disabled = !eval;
-   }
-   rif->if_state = (WORD)disabled;
-   return(0);
+int d_if (void)
+{
+       IFENT * rif;
+       WORD eattr;
+       VALUE eval;
+       SYM * esym;
+
+       // Alloc an IFENTRY
+       if ((rif = f_ifent) == NULL)
+               rif = (IFENT *)amem((LONG)sizeof(IFENT));
+       else
+               f_ifent = rif->if_prev;
+
+       rif->if_prev = ifent;
+       ifent = rif;
+
+       if (!disabled)
+       {
+               if (expr(exprbuf, &eval, &eattr, &esym) != OK) return 0;
+
+               if ((eattr & DEFINED) == 0)
+                       return error(undef_error);
+
+               disabled = !eval;
+       }
+
+       rif->if_state = (WORD)disabled;
+       return 0;
 }
 
+
 // 
-// --- .else, Do Alternate Case For .if ------------------------------------------------------------
+// .else, Do Alternate Case For .if
 //
+int d_else(void)
+{
+       IFENT * rif = ifent;
 
-int d_else(void) {
-   IFENT *rif;
+       if (rif->if_prev == NULL)
+               return error("mismatched .else");
 
-   rif = ifent;
+       if (disabled)
+               disabled = rif->if_prev->if_state;
+       else
+               disabled = 1;
 
-   if(rif->if_prev == NULL) return(error("mismatched .else"));
-
-   if(disabled) disabled = rif->if_prev->if_state;
-   else disabled = 1;
-
-   rif->if_state = (WORD)disabled;
-   return(0);
+       rif->if_state = (WORD)disabled;
+       return 0;
 }
 
+
 //
-// -------------------------------------------------------------------------------------------------
 // .endif, End of conditional assembly block
-// This is also called by fpop() to pop levels of IFENTs in case a macro or include file exits 
-// early with `exitm' or `end'.
-// -------------------------------------------------------------------------------------------------
+// This is also called by fpop() to pop levels of IFENTs in case a macro or
+// include file exits early with `exitm' or `end'.
 //
-
-int d_endif(void) {
-   IFENT *rif;
-
-   rif = ifent;
-   if(rif->if_prev == NULL) return(error("mismatched .endif"));
-
-   ifent = rif->if_prev;
-   disabled = rif->if_prev->if_state;
-   rif->if_prev = f_ifent;
-   f_ifent = rif;
-   return(0);
+int d_endif (void)
+{
+       IFENT * rif = ifent;
+
+       if (rif->if_prev == NULL)
+               return error("mismatched .endif");
+
+       ifent = rif->if_prev;
+       disabled = rif->if_prev->if_state;
+       rif->if_prev = f_ifent;
+       f_ifent = rif;
+       return 0;
 }
-
index 053e80316c114485db543aa916672a8c835f3a24..a6ebe84e44f571c96286f230cdab05859b635b2b 100644 (file)
--- a/procln.h
+++ b/procln.h
 #include "token.h"
 
 // Globals, externals etc
-extern IFENT *ifent;
-extern char *comma_error;
-extern char *locgl_error;
-extern char *syntax_error;
+extern IFENT * ifent;
+extern char * comma_error;
+extern char * locgl_error;
+extern char * syntax_error;
 extern int just_bss;
 extern VALUE pcloc;
-extern IFENT *ifent;
-extern SYM *lab_sym;
+extern IFENT * ifent;
+extern SYM * lab_sym;
 extern char extra_stuff[];
 extern LONG amsktab[];
 
diff --git a/risca.c b/risca.c
index 5f658dc53f8a42b59a70c6d2993266e3cbdf5680..f1d2ed64cba8824c9ee1d495589a703e8d38767b 100644 (file)
--- a/risca.c
+++ b/risca.c
@@ -34,8 +34,9 @@ char reg_err[] = "missing register R0...R31";
 
 // Jaguar Jump Condition Names
 char condname[MAXINTERNCC][5] = { 
-   "NZ", "Z", "NC", "NCNZ", "NCZ", "C", "CNZ", "CZ", "NN", "NNNZ", "NNZ", "N", "N_NZ", "N_Z ",
-   "T", "A", "NE", "EQ", "CC", "HS", "HI", "CS", "LO", "PL", "MI", "F"
+       "NZ", "Z", "NC", "NCNZ", "NCZ", "C", "CNZ", "CZ", "NN", "NNNZ", "NNZ",
+       "N", "N_NZ", "N_Z ", "T", "A", "NE", "EQ", "CC", "HS", "HI", "CS", "LO",
+       "PL", "MI", "F"
 };
 
 // Jaguar Jump Condition Numbers
@@ -43,674 +44,954 @@ char condnumber[] = {1, 2, 4, 5, 6, 8, 9, 10, 20, 21, 22, 24, 25, 26,
                      0, 0, 1, 2, 4, 4, 5,  8,  8, 20, 24, 31};
 
 struct opcoderecord roptbl[] = {
-   { MR_ADD,     RI_TWO,    0 },
-   { MR_ADDC,    RI_TWO,    1 },
-   { MR_ADDQ,    RI_NUM_32, 2 },
-   { MR_ADDQT,   RI_NUM_32, 3 },
-   { MR_SUB,     RI_TWO,    4 },
-   { MR_SUBC,    RI_TWO,    5 },
-   { MR_SUBQ,    RI_NUM_32, 6 },
-   { MR_SUBQT,   RI_NUM_32, 7 },
-   { MR_NEG,     RI_ONE,    8 },
-   { MR_AND,     RI_TWO,    9 },
-   { MR_OR,      RI_TWO,    10 },
-   { MR_XOR,     RI_TWO,    11 },
-   { MR_NOT,     RI_ONE,    12 },
-   { MR_BTST,    RI_NUM_31, 13 },
-   { MR_BSET,    RI_NUM_31, 14 },
-   { MR_BCLR,    RI_NUM_31, 15 },
-   { MR_MULT,    RI_TWO,    16 },
-   { MR_IMULT,   RI_TWO,    17 },
-   { MR_IMULTN,  RI_TWO,    18 },
-   { MR_RESMAC,  RI_ONE,    19 },
-   { MR_IMACN,   RI_TWO,    20 },
-   { MR_DIV,     RI_TWO,    21 },
-   { MR_ABS,     RI_ONE,    22 },
-   { MR_SH,      RI_TWO,    23 },
-   { MR_SHLQ,    RI_NUM_32, 24 + SUB32 },
-   { MR_SHRQ,    RI_NUM_32, 25 },
-   { MR_SHA,     RI_TWO,    26 },
-   { MR_SHARQ,   RI_NUM_32, 27 },
-   { MR_ROR,     RI_TWO,    28 },
-   { MR_RORQ,    RI_NUM_32, 29 },
-   { MR_ROLQ,    RI_NUM_32, 29 + SUB32 },
-   { MR_CMP,     RI_TWO,    30 },
-   { MR_CMPQ,    RI_NUM_15, 31 },
-   { MR_SAT8,    RI_ONE,    32 + GPUONLY },
-   { MR_SUBQMOD, RI_NUM_32, 32 + DSPONLY },
-   { MR_SAT16,   RI_ONE,    33 + GPUONLY },
-   { MR_SAT16S,  RI_ONE,    33 + DSPONLY },
-   { MR_MOVEQ,   RI_NUM_31, 35 },
-   { MR_MOVETA,  RI_TWO,    36 },
-   { MR_MOVEFA,  RI_TWO,    37 },
-   { MR_MOVEI,   RI_MOVEI,  38 },
-   { MR_LOADB,   RI_LOADN,  39 },
-   { MR_LOADW,   RI_LOADN,  40 },
-   { MR_LOADP,   RI_LOADN,  42 + GPUONLY },
-   { MR_SAT32S,  RI_ONE,    42 + DSPONLY },
-   { MR_STOREB,  RI_STOREN, 45 },
-   { MR_STOREW,  RI_STOREN, 46 },
-   { MR_STOREP,  RI_STOREN, 48 + GPUONLY },
-   { MR_MIRROR,  RI_ONE,    48 + DSPONLY },
-   { MR_JUMP,    RI_JUMP,   52 },
-   { MR_JR,      RI_JR,     53 },
-   { MR_MMULT,   RI_TWO,    54 },
-   { MR_MTOI,    RI_TWO,    55 },
-   { MR_NORMI,   RI_TWO,    56 },
-   { MR_NOP,     RI_NONE,   57 },
-   { MR_SAT24,   RI_ONE,    62 },
-   { MR_UNPACK,  RI_ONE,    63 + GPUONLY },
-   { MR_PACK,    RI_ONE,    63 + GPUONLY },
-   { MR_ADDQMOD, RI_NUM_32, 63 + DSPONLY },
-   { MR_MOVE,    RI_MOVE,   0 },
-   { MR_LOAD,    RI_LOAD,   0 },
-   { MR_STORE,   RI_STORE,  0 }
+       { MR_ADD,     RI_TWO,    0 },
+       { MR_ADDC,    RI_TWO,    1 },
+       { MR_ADDQ,    RI_NUM_32, 2 },
+       { MR_ADDQT,   RI_NUM_32, 3 },
+       { MR_SUB,     RI_TWO,    4 },
+       { MR_SUBC,    RI_TWO,    5 },
+       { MR_SUBQ,    RI_NUM_32, 6 },
+       { MR_SUBQT,   RI_NUM_32, 7 },
+       { MR_NEG,     RI_ONE,    8 },
+       { MR_AND,     RI_TWO,    9 },
+       { MR_OR,      RI_TWO,    10 },
+       { MR_XOR,     RI_TWO,    11 },
+       { MR_NOT,     RI_ONE,    12 },
+       { MR_BTST,    RI_NUM_31, 13 },
+       { MR_BSET,    RI_NUM_31, 14 },
+       { MR_BCLR,    RI_NUM_31, 15 },
+       { MR_MULT,    RI_TWO,    16 },
+       { MR_IMULT,   RI_TWO,    17 },
+       { MR_IMULTN,  RI_TWO,    18 },
+       { MR_RESMAC,  RI_ONE,    19 },
+       { MR_IMACN,   RI_TWO,    20 },
+       { MR_DIV,     RI_TWO,    21 },
+       { MR_ABS,     RI_ONE,    22 },
+       { MR_SH,      RI_TWO,    23 },
+       { MR_SHLQ,    RI_NUM_32, 24 + SUB32 },
+       { MR_SHRQ,    RI_NUM_32, 25 },
+       { MR_SHA,     RI_TWO,    26 },
+       { MR_SHARQ,   RI_NUM_32, 27 },
+       { MR_ROR,     RI_TWO,    28 },
+       { MR_RORQ,    RI_NUM_32, 29 },
+       { MR_ROLQ,    RI_NUM_32, 29 + SUB32 },
+       { MR_CMP,     RI_TWO,    30 },
+       { MR_CMPQ,    RI_NUM_15, 31 },
+       { MR_SAT8,    RI_ONE,    32 + GPUONLY },
+       { MR_SUBQMOD, RI_NUM_32, 32 + DSPONLY },
+       { MR_SAT16,   RI_ONE,    33 + GPUONLY },
+       { MR_SAT16S,  RI_ONE,    33 + DSPONLY },
+       { MR_MOVEQ,   RI_NUM_31, 35 },
+       { MR_MOVETA,  RI_TWO,    36 },
+       { MR_MOVEFA,  RI_TWO,    37 },
+       { MR_MOVEI,   RI_MOVEI,  38 },
+       { MR_LOADB,   RI_LOADN,  39 },
+       { MR_LOADW,   RI_LOADN,  40 },
+       { MR_LOADP,   RI_LOADN,  42 + GPUONLY },
+       { MR_SAT32S,  RI_ONE,    42 + DSPONLY },
+       { MR_STOREB,  RI_STOREN, 45 },
+       { MR_STOREW,  RI_STOREN, 46 },
+       { MR_STOREP,  RI_STOREN, 48 + GPUONLY },
+       { MR_MIRROR,  RI_ONE,    48 + DSPONLY },
+       { MR_JUMP,    RI_JUMP,   52 },
+       { MR_JR,      RI_JR,     53 },
+       { MR_MMULT,   RI_TWO,    54 },
+       { MR_MTOI,    RI_TWO,    55 },
+       { MR_NORMI,   RI_TWO,    56 },
+       { MR_NOP,     RI_NONE,   57 },
+       { MR_SAT24,   RI_ONE,    62 },
+       { MR_UNPACK,  RI_ONE,    63 + GPUONLY },
+       { MR_PACK,    RI_ONE,    63 + GPUONLY },
+       { MR_ADDQMOD, RI_NUM_32, 63 + DSPONLY },
+       { MR_MOVE,    RI_MOVE,   0 },
+       { MR_LOAD,    RI_LOAD,   0 },
+       { MR_STORE,   RI_STORE,  0 }
 };
 
+
 //
-// --- Convert a String to Uppercase ---------------------------------------------------------------
+// Convert a String to Uppercase
 //
-
-void strtoupper(char *s) {
-   while(*s) {
-      *s = (char)(toupper(*s));
-      s++;
-   }
+void strtoupper(char * s)
+{
+       while (*s)
+       {
+               *s = (char)(toupper(*s));
+               s++;
+       }
 }
 
+
 //
-// --- Build RISC Instruction Word -----------------------------------------------------------------
+// Build RISC Instruction Word
 //
+void risc_instruction_word(unsigned short parm, int reg1, int reg2)
+{
+       int value = 0xE400;
+
+       previousop = currentop;                                  // Opcode tracking for nop padding
+       currentop = parm;
+
+       if (!orgwarning)
+       {                                        // Check for absolute address setting
+               if (!orgactive && !in_main)
+               {
+                       warn("GPU/DSP code outside of absolute section");
+                       orgwarning = 1;
+               }
+       }
+
+       if (jpad)
+       {                                               // JPAD directive
+               //                JUMP                   JR                    NOP
+               if (((previousop == 52) || (previousop == 53)) && (currentop != 57))
+                       D_word(value);                                     // Insert NOP
+       }
+       else
+       {
+               //               JUMP                   JR
+               if ((previousop == 52) || (previousop == 53))
+               {
+                       switch (currentop)
+                       {
+                       case 38:
+                               warn("NOP inserted before MOVEI instruction.");
+                               D_word(value);
+                               break;
+                       case 53:
+                               warn("NOP inserted before JR instruction.");
+                               D_word(value);
+                               break;
+                       case 52:
+                               warn("NOP inserted before JUMP instruction.");
+                               D_word(value);
+                               break;
+                       case 51:
+                               warn("NOP inserted before MOVE PC instruction.");
+                               D_word(value);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+
+       if (currentop == 20)
+       {                                    // IMACN checks
+               if ((previousop != 18) && (previousop != 20))
+               {
+                       error("IMULTN/IMACN instruction must preceed IMACN instruction");
+               }
+       }
 
-void risc_instruction_word(unsigned short parm, int reg1, int reg2) {
-   int value = 0xE400;
-
-   previousop = currentop;                                  // Opcode tracking for nop padding
-   currentop = parm;
-   
-   if(!orgwarning) {                                        // Check for absolute address setting
-      if(!orgactive && !in_main) {
-         warn("GPU/DSP code outside of absolute section");
-         orgwarning = 1;
-      }
-   }
-   
-   if(jpad) {                                               // JPAD directive
-      //                JUMP                   JR                    NOP
-      if(((previousop == 52) || (previousop == 53)) && (currentop != 57))
-         D_word(value);                                     // Insert NOP
-   } else {
-      //               JUMP                   JR
-      if((previousop == 52) || (previousop == 53)) {
-         switch(currentop) {
-            case 38: warn("NOP inserted before MOVEI instruction.");   D_word(value); break;
-            case 53: warn("NOP inserted before JR instruction.");      D_word(value); break;
-            case 52: warn("NOP inserted before JUMP instruction.");    D_word(value); break;
-            case 51: warn("NOP inserted before MOVE PC instruction."); D_word(value); break;
-            default:
-               break;
-         }
-      }
-   }
-
-   if(currentop == 20) {                                    // IMACN checks
-      if((previousop != 18) && (previousop != 20)) {
-         error("IMULTN/IMACN instruction must preceed IMACN instruction");
-      }
-   }
-
-   if(currentop == 19) {                                    // RESMAC checks
-      if(previousop != 20) {
-         error("IMACN instruction must preceed RESMAC instruction");
-      }
-   }
-
-   value =((parm & 0x3F) << 10) + ((reg1 & 0x1F) << 5) + (reg2 & 0x1F);
-   D_word(value);
+       if (currentop == 19)
+       {                                    // RESMAC checks
+               if (previousop != 20)
+               {
+                       error("IMACN instruction must preceed RESMAC instruction");
+               }
+       }
+
+       value =((parm & 0x3F) << 10) + ((reg1 & 0x1F) << 5) + (reg2 & 0x1F);
+       D_word(value);
 }
 
+
 //
-// --- Get a RISC Register -------------------------------------------------------------------------
+// Get a RISC Register
 //
+int getregister(WORD rattr)
+{
+       VALUE eval;                                     // Expression value
+       WORD eattr;                                     // Expression attributes
+       SYM * esym;                                     // External symbol involved in expr.
+       TOKEN r_expr[EXPRSIZE];         // Expression token list
+       WORD defined;                           // Symbol defined flag
+
+       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+       {
+               error("malformed opcode");
+               return ERROR;
+       }
+       else
+       {
+               defined = (WORD)(eattr & DEFINED);
 
-int getregister(WORD rattr) {
-   VALUE eval;                                              // Expression value
-   WORD eattr;                                              // Expression attributes
-   SYM *esym;                                               // External symbol involved in expr.
-   TOKEN r_expr[EXPRSIZE];                                  // Expression token list
-   WORD defined;                                            // Symbol defined flag
-
-   if(expr(r_expr, &eval, &eattr, &esym) != OK) {
-      error("malformed opcode");
-      return(ERROR);
-   } else {
-      defined = (WORD)(eattr & DEFINED);
-      if((challoc - ch_size) < 4)
-         chcheck(4L);
-      if(!defined) {
-         fixup((WORD)(FU_WORD|rattr), sloc, r_expr);      
-         return(0);
-      } else {
-         if((eval >= 0) && (eval <= 31)) {                  // Check for specified register, r0->r31
-            return(eval);
-         } else {
-            error(reg_err);
-            return(ERROR);
-         }
-      }
-   }
-   
-   return(ERROR);
+               if ((challoc - ch_size) < 4)
+                       chcheck(4L);
+
+               if (!defined)
+               {
+                       fixup((WORD)(FU_WORD|rattr), sloc, r_expr);      
+                       return 0;
+               }
+               else
+               {
+                       // Check for specified register, r0->r31
+                       if ((eval >= 0) && (eval <= 31))
+                       {
+                               return eval;
+                       }
+                       else
+                       {
+                               error(reg_err);
+                               return ERROR;
+                       }
+               }
+       }
+
+       return ERROR;
 }
 
+
 //
-// --- Do RISC Code Generation ---------------------------------------------------------------------
+// Do RISC Code Generation
 //
+int risccg(int state)
+{
+       unsigned short parm;                                     // Opcode parameters
+       unsigned type;                                           // Opcode type
+       int reg1;                                                // Register 1
+       int reg2;                                                // Register 2
+       int val = 0;                                             // Constructed value
+       char scratch[80];
+       SYM * ccsym;
+       SYM * sy;
+       int i;                                                   // Iterator
+       int t, c;
+       WORD tdb;
+       unsigned locptr = 0;                                     // Address location pointer
+       unsigned page_jump = 0;                                  // Memory page jump flag
+       VALUE eval;                                              // Expression value
+       WORD eattr;                                              // Expression attributes
+       SYM * esym;                                              // External symbol involved in expr.
+       TOKEN r_expr[EXPRSIZE];                                  // Expression token list
+       WORD defined;                                            // Symbol defined flag
+       WORD attrflg;
+       int indexed;                                             // Indexed register flag
 
-int risccg(int state) {
-   unsigned short parm;                                     // Opcode parameters
-   unsigned type;                                           // Opcode type
-   int reg1;                                                // Register 1
-   int reg2;                                                // Register 2
-   int val = 0;                                             // Constructed value
-   char scratch[80];
-   SYM *ccsym;
-   SYM *sy;
-   int i;                                                   // Iterator
-   int t, c;
-   WORD tdb;
-   unsigned locptr = 0;                                     // Address location pointer
-   unsigned page_jump = 0;                                  // Memory page jump flag
-   VALUE eval;                                              // Expression value
-   WORD eattr;                                              // Expression attributes
-   SYM *esym;                                               // External symbol involved in expr.
-   TOKEN r_expr[EXPRSIZE];                                  // Expression token list
-   WORD defined;                                            // Symbol defined flag
-   WORD attrflg;
-   int indexed;                                             // Indexed register flag
-
-   parm = (WORD)(roptbl[state-3000].parm);                  // Get opcode parameter and type
-   type = roptbl[state-3000].typ;
-
-   // Detect whether the opcode parmeter passed determines that the opcode is specific to only one 
-   // of the RISC processors and ensure it is legal in the current code section. 
-   // If not then error and return.
-   if(((parm & GPUONLY) && rdsp) || ((parm & DSPONLY) && rgpu) ) {
-      error("opcode is not valid in this code section");
-      return(ERROR);
-   }
-
-   // Process RISC opcode
-   switch(type) {
-      // No operand instructions
-      // NOP
-      case RI_NONE: 
-         risc_instruction_word(parm, 0, 0);
-         break;
-      // Single operand instructions (Rd)
-      // ABS, MIRROR, NEG, NOT, PACK, RESMAC, SAT8, SAT16, SAT16S, SAT24, SAT32S, UNPACK
-      case RI_ONE:
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         risc_instruction_word(parm, parm >> 6, reg2);
-         break;   
-      // Two operand instructions (Rs,Rd)
-      // ADD, ADDC, AND, CMP, DIV, IMACN, IMULT, IMULTN, MOVEFA, MOVETA, MULT, MMULT, 
-      // MTOI, NORMI, OR, ROR, SH, SHA, SUB, SUBC, XOR
-      case RI_TWO:                      
-         if(parm == 37) altbankok = 1;                      // MOVEFA
-         reg1 = getregister(FU_REGONE);
-         CHECK_COMMA;         
-         if(parm == 36) altbankok = 1;                      // MOVETA
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         risc_instruction_word(parm, reg1, reg2);
-         break;
-      // Numeric operand (n,Rd) where n = -16..+15
-      // CMPQ
-      case RI_NUM_15:                   
-      // Numeric operand (n,Rd) where n = 0..31
-      // BCLR, BSET, BTST, MOVEQ
-      case RI_NUM_31:      
-      // Numeric operand (n,Rd) where n = 1..32
-      // ADDQ, ADDQMOD, ADDQT, SHARQ, SHLQ, SHRQ, SUBQ, SUBQMOD, SUBQT, ROLQ, RORQ
-      case RI_NUM_32:                   
-         switch(type) {
-            case RI_NUM_15: reg1 = -16; reg2 = 15; attrflg = FU_NUM15; break;
-            default:
-            case RI_NUM_31: reg1 =   0; reg2 = 31; attrflg = FU_NUM31; break;
-            case RI_NUM_32: reg1 =   1; reg2 = 32; attrflg = FU_NUM32; break;
-         }
-         if(parm & SUB32) attrflg |= FU_SUB32;
-         if(*tok == '#') {
-            ++tok;
-            if(expr(r_expr, &eval, &eattr, &esym) != OK)
-               goto malformed;
-            else {
-               defined = (WORD)(eattr & DEFINED);
-               if((challoc - ch_size) < 4)
-                  chcheck(4L);
-               if(!defined) {
-                  fixup((WORD)(FU_WORD|attrflg), sloc, r_expr);
-                  reg1 = 0;
-               } else {
-                  if((int)eval < reg1 || (int)eval > reg2) {
-                     error("constant out of range");
-                     return(ERROR);
-                  }
-                  if(parm & SUB32) 
-                     reg1 = 32 - eval; 
-                  else if(type == RI_NUM_32)
-                     reg1 = (reg1 == 32) ? 0 : eval;
-                  else
-                     reg1 = eval;
-               }
-            }
-         } else goto malformed;
-         CHECK_COMMA;
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         risc_instruction_word(parm, reg1, reg2);
-         break;
-      // Move Immediate - n,Rn - n in Second Word
-      case RI_MOVEI:       
-         if(*tok == '#') {
-            ++tok;
-            if(expr(r_expr, &eval, &eattr, &esym) != OK) {
-               malformed:
-               error("malformed opcode");
-               return(ERROR);
-            } else {
-               // Opcode tracking for nop padding
-               previousop = currentop;                          
-               currentop = parm;
-               // JUMP or JR
-               if((previousop == 52) || (previousop == 53) && !jpad) {
-                  warn("NOP inserted before MOVEI instruction.");   
-                  D_word(0xE400);
-               }
-               tdb = (WORD)(eattr & TDB);
-               defined = (WORD)(eattr & DEFINED);
-               if((challoc - ch_size) < 4)
-                  chcheck(4L);
-               if(!defined) {
-                  fixup(FU_LONG|FU_MOVEI, sloc + 2, r_expr);
-                  eval = 0;
-               } else {
-                  if(tdb) {
-                     rmark(cursect, sloc + 2, tdb, MLONG|MMOVEI, NULL);
-                  }
-               }       
-               val = eval;
-               // Store the defined flags and value of the movei when used in mjump
-               if(mjump_align) {
-                  mjump_defined = defined;
-                  mjump_dest = val;
-               }
-            }
-         } else goto malformed;
-         ++tok;
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         D_word((((parm & 0x3F) << 10) + reg2));
-         val = ((val >> 16) & 0x0000FFFF) | ((val << 16) & 0xFFFF0000);
-         D_long(val);
-         break;
-      case RI_MOVE:                     // PC,Rd or Rs,Rd
-         if(*tok == KW_PC) {
-            parm = 51;
-            reg1 = 0;
-            ++tok;
-         } else {
-            parm = 34;
-            reg1 = getregister(FU_REGONE);
-         }
-         CHECK_COMMA;
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         risc_instruction_word(parm, reg1, reg2);
-         break;
-      // (Rn),Rn = 41 / (R14/R15+n),Rn = 43/44 / (R14/R15+Rn),Rn = 58/59
-      case RI_LOAD:          
-         indexed = 0;
-         parm = 41;
-         if(*tok != '(') goto malformed;
-         ++tok;
-         if((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')')) 
-            indexed = (*tok - KW_R0);
-         if(*tok == SYMBOL) {
-            sy = lookup((char *)tok[1], LABEL, 0);
-            if(!sy) {
-               error(reg_err);
-               return(ERROR);
-            }
-            if(sy->sattre & EQUATEDREG) 
-               if(((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) && (*(tok+2) != ')')) {
-                  indexed = (sy->svalue & 0x1F);
-                  ++tok;
-               }
-         }
-         if(!indexed) {
-            reg1 = getregister(FU_REGONE);
-         } else {
-            reg1 = indexed;
-            indexed = 0;
-            ++tok;
-            if(*tok == '+') {
-               parm = (WORD)(reg1 - 14 + 58);
-               tok++;
-               if(*tok >= KW_R0 && *tok <= KW_R31) {
-                  indexed = 1;
-               }
-               if(*tok == SYMBOL) {
-                  sy = lookup((char *)tok[1], LABEL, 0);
-                  if(!sy) {
-                     error(reg_err);
-                     return(ERROR);
-                  }
-                  if(sy->sattre & EQUATEDREG) {
-                     indexed = 1;
-                  } 
-               }
-               if(indexed) {
-                  reg1 = getregister(FU_REGONE);
-               } else {
-                  if(expr(r_expr, &eval, &eattr, &esym) != OK) {
-                     goto malformed;
-                  } else {
-                     tdb = (WORD)(eattr & TDB);
-                     defined = (WORD)(eattr & DEFINED);
-                     if((challoc - ch_size) < 4)
-                        chcheck(4L);
-                     if(!defined) {
-                        error("constant expected");
-                        return(ERROR);
-                        //fixup(FU_WORD|FU_REGONE, sloc, r_expr);
-                        reg1 = 0;
-                     } else {
-                        reg1 = eval;
-                        if(reg1 == 0) {
-                           reg1 = 14+(parm-58);
-                           parm = 41;
-                           warn("NULL offset removed");
-                        } else {
-                           if(reg1 < 1 || reg1 > 32) {
-                              error("constant out of range");
-                              return(ERROR);
-                           }
-                           if(reg1 == 32) reg1 = 0;
-                           parm = (WORD)(parm - 58 + 43);
-                        }
-                     } 
-                  }
-               }
-            } else {
-               reg1 = getregister(FU_REGONE);
-            }
-         }
-         if(*tok != ')') goto malformed;
-         ++tok;
-         CHECK_COMMA;
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         risc_instruction_word(parm, reg1, reg2);
-         break;
-      // Rn,(Rn) = 47 / Rn,(R14/R15+n) = 49/50 / Rn,(R14/R15+Rn) = 60/61
-      case RI_STORE:    
-         parm = 47;
-         reg1 = getregister(FU_REGONE);
-         CHECK_COMMA;
-         if(*tok != '(') goto malformed;
-         ++tok;
-         indexed = 0;
-         if((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')')) 
-            indexed = (*tok - KW_R0);
-         if(*tok == SYMBOL) {
-            sy = lookup((char *)tok[1], LABEL, 0);
-            if(!sy) {
-               error(reg_err);
-               return(ERROR);
-            }
-            if(sy->sattre & EQUATEDREG) 
-               if(((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) && (*(tok+2) != ')')) {
-                  indexed = (sy->svalue & 0x1F);
-                  ++tok;
-               }
-         }
-         if(!indexed) {
-            reg2 = getregister(FU_REGTWO);
-         } else {
-            reg2 = indexed;
-            indexed = 0;
-            ++tok;
-            if(*tok == '+') {
-               parm = (WORD)(reg2 - 14 + 60);
-               tok++;
-               if(*tok >= KW_R0 && *tok <= KW_R31) {
-                  indexed = 1;
-               }
-               if(*tok == SYMBOL) {
-                  sy = lookup((char *)tok[1], LABEL, 0);
-                  if(!sy) {
-                     error(reg_err);
-                     return(ERROR);
-                  }
-                  if(sy->sattre & EQUATEDREG) {
-                     indexed = 1;
-                  }
-               }
-               if(indexed) {
-                  reg2 = getregister(FU_REGTWO);
-               } else {
-                  if(expr(r_expr, &eval, &eattr, &esym) != OK) {
-                     goto malformed;
-                  } else {
-                     tdb = (WORD)(eattr & TDB);
-                     defined = (WORD)(eattr & DEFINED);
-                     if((challoc - ch_size) < 4)
-                        chcheck(4L);
-                     if(!defined) {
-                        fixup(FU_WORD|FU_REGTWO, sloc, r_expr);
-                        reg2 = 0;
-                     } else {
-                        reg2 = eval;
-                        if(reg2 == 0 ) {
-                           reg2 = 14+(parm-60);
-                           parm = 47;
-                           warn("NULL offset removed");
-                        } else {
-                           if(reg2 < 1 || reg2 > 32) {
-                              error("constant out of range");
-                              return(ERROR);
-                           }
-                           if(reg2 == 32) reg2 = 0;
-                           parm = (WORD)(parm - 60 + 49);
-                        }
-                     } 
-                  }
-               }
-            } else {
-               reg2 = getregister(FU_REGTWO);
-            }
-         }
-         if(*tok != ')') goto malformed;
-         ++tok;
-         at_eol();
-         risc_instruction_word(parm, reg2, reg1);
-         break;
-      // LOADB/LOADP/LOADW (Rn),Rn
-      case RI_LOADN:                    
-         if(*tok != '(') goto malformed;
-         ++tok;
-         reg1 = getregister(FU_REGONE);
-         if(*tok != ')') goto malformed;
-         ++tok;
-         CHECK_COMMA;
-         reg2 = getregister(FU_REGTWO);
-         at_eol();
-         risc_instruction_word(parm, reg1, reg2);
-         break;
-      // STOREB/STOREP/STOREW Rn,(Rn)
-      case RI_STOREN:                   
-         reg1 = getregister(FU_REGONE);
-         CHECK_COMMA;
-         if(*tok != '(') goto malformed;
-         ++tok;
-         reg2 = getregister(FU_REGTWO);
-         if(*tok != ')') goto malformed;
-         ++tok;
-         at_eol();
-         risc_instruction_word(parm, reg2, reg1);
-         break;
-      case RI_JR:                       // Jump Relative - cc,n - n=-16..+15 words, reg2=cc
-      case RI_JUMP:                     // Jump Absolute - cc,(Rs) - reg2=cc
-         // Check to see if there is a comma in the token string. If not then the JR or JUMP should
-         // default to 0, Jump Always
-         t = i = c = 0;
-         while(t != EOL) {
-            t = *(tok + i);
-            if(t == ',') c = 1;
-            i++;
-         }
-         if(c) {                                            // Comma present in token string
-            if(*tok == CONST) {                             // CC using a constant number
-               ++tok;
-               val = *tok;
-               ++tok;
-               CHECK_COMMA;
-            } else if(*tok == SYMBOL) {
-               val = 99;
-               for(i = 0; i < MAXINTERNCC; i++) {
-                  strcpy(scratch, (char *)tok[1]);
-                  strtoupper(scratch);
-                  if(!strcmp(condname[i], scratch)) 
-                     val = condnumber[i];
-               }
-               if(val == 99) {
-                  ccsym = lookup((char *)tok[1], LABEL, 0);
-                  if(ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC)) {
-                     val = ccsym->svalue;
-                  } else {
-                     error("unknown condition code");
-                     return(ERROR);
-                  }
-               }
-               tok += 2;
-               CHECK_COMMA;
-            } else if(*tok == '(') {
-               val = 0;                                     // Jump always
-            }
-         } else {
-            val = 0;                                        // Jump always
-         }
-
-         if(val < 0 || val > 31) {
-            error("condition constant out of range");
-            return(ERROR);
-         } else {
-            reg1 = val;                                     // Store condition code
-         }
-         if(type == RI_JR) {                                // JR cc,n
-            if(expr(r_expr, &eval, &eattr, &esym) != OK)
-               goto malformed;
-            else {
-               tdb = (WORD)(eattr & TDB);
-               defined = (WORD)(eattr & DEFINED);
-               if((challoc - ch_size) < 4)
-                  chcheck(4L);
-               if(!defined) {
-                  if(in_main) {
-                     fixup(FU_WORD|FU_MJR, sloc, r_expr);
-                  } else {
-                     fixup(FU_WORD|FU_JR, sloc, r_expr);
-                  }
-                  reg2 = 0;
-               } else {
-                  val = eval;
-                  if(orgactive) {
-                     reg2 = ((int)(val - (orgaddr + 2))) / 2;
-                     if((reg2 < -16) || (reg2 > 15))
-                        error("PC relative overflow");
-                     locptr = orgaddr;
-                  } else {
-                     reg2 = ((int)(val - (sloc + 2))) / 2;
-                     if((reg2 < -16) || (reg2 > 15))
-                        error("PC relative overflow");
-                     locptr = sloc;
-                  }
-               }       
-               if(in_main) {
-                  if(defined) {
-                     if(((locptr >= 0xF03000) && (locptr < 0xF04000) && (val    < 0xF03000)) ||
-                        ((val    >= 0xF03000) && (val    < 0xF04000) && (locptr < 0xF03000)) ) {
-                        warn("* cannot jump relative between main memory and local gpu ram");
-                     } else {
-                        page_jump = (locptr & 0xFFFFFF00) - (val & 0xFFFFFF00);
-                        if(page_jump) {
-                           if(val % 4) {
-                              warn("* destination address not aligned for long page jump relative, "
-                                   "insert a \'nop\' before the destination label/address");
-                           }
-                        } else {
-                           if((val - 2) % 4) {
-                              warn("* destination address not aligned for short page jump relative, "
-                                   "insert a \'nop\' before the destination label/address");
-                           }
-                        }
-                     }
-                  }
-               }
-            }
-            risc_instruction_word(parm, reg2, reg1);
-         } else {                                           // JUMP cc, (Rn)
-            if(*tok != '(') goto malformed;
-            ++tok;
-            reg2 = getregister(FU_REGTWO);
-            if(*tok != ')') goto malformed;
-            ++tok;
-            at_eol();
-            if(in_main) {
-               if(!mjump_align) {
-                  warn("* \'jump\' is not recommended for .gpumain as destination addresses "
-                       "cannot be validated for alignment, use \'mjump\'");
-                  locptr = (orgactive) ? orgaddr : sloc;
-                  if(locptr % 4) {
-                     warn("* source address not aligned for long or short jump, "
-                          "insert a \'nop\' before the \'jump\'");
-                  }          
-               } else {
-                  if(mjump_defined) {
-                     locptr = (orgactive) ? orgaddr : sloc;
-                     page_jump = (locptr & 0xFFFFFF00) - (mjump_dest & 0xFFFFFF00);
-                     if(page_jump) {
-                        if(mjump_dest % 4) {
-                           warn("* destination address not aligned for long page jump, "
-                          "insert a \'nop\' before the destination label/address");
-                        }          
-                     } else {
-                        if(!(mjump_dest & 0x0000000F) || ((mjump_dest - 2) % 4)) {
-                           warn("* destination address not aligned for short page jump, "
-                          "insert a \'nop\' before the destination label/address");
-                        }          
-                     }
-                  } else {
-                     locptr = (orgactive) ? orgaddr : sloc;
-                     fwdjump[fwindex++] = locptr;
-                  }
-               }
-
-            }
-            risc_instruction_word(parm, reg2, reg1);
-         }
-         break;
-      // Should never get here :D
-      default:                                              
-         error("unknown risc opcode type");
-         return(ERROR);
-         break;
-
-   }
-
-   return(0);
-}
+       parm = (WORD)(roptbl[state-3000].parm);                  // Get opcode parameter and type
+       type = roptbl[state-3000].typ;
+
+       // Detect whether the opcode parmeter passed determines that the opcode is specific to only one 
+       // of the RISC processors and ensure it is legal in the current code section. 
+       // If not then error and return.
+       if (((parm & GPUONLY) && rdsp) || ((parm & DSPONLY) && rgpu))
+       {
+               error("opcode is not valid in this code section");
+               return ERROR;
+       }
+
+       // Process RISC opcode
+       switch (type)
+       {
+       // No operand instructions
+       // NOP
+       case RI_NONE: 
+               risc_instruction_word(parm, 0, 0);
+               break;
+       // Single operand instructions (Rd)
+       // ABS, MIRROR, NEG, NOT, PACK, RESMAC, SAT8, SAT16, SAT16S, SAT24, SAT32S, UNPACK
+       case RI_ONE:
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               risc_instruction_word(parm, parm >> 6, reg2);
+               break;   
+       // Two operand instructions (Rs,Rd)
+       // ADD, ADDC, AND, CMP, DIV, IMACN, IMULT, IMULTN, MOVEFA, MOVETA, MULT, MMULT, 
+       // MTOI, NORMI, OR, ROR, SH, SHA, SUB, SUBC, XOR
+       case RI_TWO:                      
+               if (parm == 37)
+                       altbankok = 1;                      // MOVEFA
+
+               reg1 = getregister(FU_REGONE);
+               CHECK_COMMA;         
+
+               if (parm == 36)
+                       altbankok = 1;                      // MOVETA
+
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               risc_instruction_word(parm, reg1, reg2);
+               break;
+       // Numeric operand (n,Rd) where n = -16..+15
+       // CMPQ
+       case RI_NUM_15:                   
+       // Numeric operand (n,Rd) where n = 0..31
+       // BCLR, BSET, BTST, MOVEQ
+       case RI_NUM_31:      
+       // Numeric operand (n,Rd) where n = 1..32
+       // ADDQ, ADDQMOD, ADDQT, SHARQ, SHLQ, SHRQ, SUBQ, SUBQMOD, SUBQT, ROLQ, RORQ
+       case RI_NUM_32:                   
+               switch (type)
+               {
+               case RI_NUM_15:
+                       reg1 = -16; reg2 = 15; attrflg = FU_NUM15;
+                       break;
+               default:
+               case RI_NUM_31:
+                       reg1 =   0; reg2 = 31; attrflg = FU_NUM31;
+                       break;
+               case RI_NUM_32:
+                       reg1 =   1; reg2 = 32; attrflg = FU_NUM32;
+                       break;
+               }
+
+               if (parm & SUB32) attrflg |= FU_SUB32;
+               {
+                       if (*tok == '#')
+                       {
+                               ++tok;
+
+                               if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                                       goto malformed;
+                               else
+                               {
+                                       defined = (WORD)(eattr & DEFINED);
+
+                                       if ((challoc - ch_size) < 4)
+                                               chcheck(4L);
+
+                                       if (!defined)
+                                       {
+                                               fixup((WORD)(FU_WORD|attrflg), sloc, r_expr);
+                                               reg1 = 0;
+                                       }
+                                       else
+                                       {
+                                               if ((int)eval < reg1 || (int)eval > reg2)
+                                               {
+                                                       error("constant out of range");
+                                                       return ERROR;
+                                               }
+
+                                               if (parm & SUB32) 
+                                                       reg1 = 32 - eval; 
+                                               else if (type == RI_NUM_32)
+                                                       reg1 = (reg1 == 32) ? 0 : eval;
+                                               else
+                                                       reg1 = eval;
+                                       }
+                               }
+                       }
+                       else
+                               goto malformed;
+               }
+
+               CHECK_COMMA;
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               risc_instruction_word(parm, reg1, reg2);
+               break;
+       // Move Immediate - n,Rn - n in Second Word
+       case RI_MOVEI:       
+               if (*tok == '#')
+               {
+                       ++tok;
+                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                       {
+                               malformed:
+                               error("malformed opcode");
+                               return ERROR;
+                       }
+                       else
+                       {
+                               // Opcode tracking for nop padding
+                               previousop = currentop;                          
+                               currentop = parm;
+
+                               // JUMP or JR
+                               if ((previousop == 52) || (previousop == 53) && !jpad)
+                               {
+                                       warn("NOP inserted before MOVEI instruction.");   
+                                       D_word(0xE400);
+                               }
+
+                               tdb = (WORD)(eattr & TDB);
+                               defined = (WORD)(eattr & DEFINED);
+
+                               if ((challoc - ch_size) < 4)
+                                       chcheck(4L);
+
+                               if (!defined)
+                               {
+                                       fixup(FU_LONG|FU_MOVEI, sloc + 2, r_expr);
+                                       eval = 0;
+                               }
+                               else
+                               {
+                                       if (tdb)
+                                       {
+                                               rmark(cursect, sloc + 2, tdb, MLONG|MMOVEI, NULL);
+                                       }
+                               }       
+
+                               val = eval;
+
+                               // Store the defined flags and value of the movei when used in mjump
+                               if (mjump_align)
+                               {
+                                       mjump_defined = defined;
+                                       mjump_dest = val;
+                               }
+                       }
+               }
+               else
+                       goto malformed;
+
+               ++tok;
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               D_word((((parm & 0x3F) << 10) + reg2));
+               val = ((val >> 16) & 0x0000FFFF) | ((val << 16) & 0xFFFF0000);
+               D_long(val);
+               break;
+       case RI_MOVE:                     // PC,Rd or Rs,Rd
+               if (*tok == KW_PC)
+               {
+                       parm = 51;
+                       reg1 = 0;
+                       ++tok;
+               }
+               else
+               {
+                       parm = 34;
+                       reg1 = getregister(FU_REGONE);
+               }
+
+               CHECK_COMMA;
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               risc_instruction_word(parm, reg1, reg2);
+               break;
+       // (Rn),Rn = 41 / (R14/R15+n),Rn = 43/44 / (R14/R15+Rn),Rn = 58/59
+       case RI_LOAD:          
+               indexed = 0;
+               parm = 41;
+
+               if (*tok != '(')
+                       goto malformed;
+
+               ++tok;
+               if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')')) 
+                       indexed = (*tok - KW_R0);
+
+               if (*tok == SYMBOL)
+               {
+                       sy = lookup((char *)tok[1], LABEL, 0);
+                       if (!sy)
+                       {
+                               error(reg_err);
+                               return ERROR;
+                       }
+
+                       if (sy->sattre & EQUATEDREG)
+                       {
+                               if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15)
+                                       && (*(tok+2) != ')'))
+                               {
+                                       indexed = (sy->svalue & 0x1F);
+                                       ++tok;
+                               }
+                       }
+               }
+
+               if (!indexed)
+               {
+                       reg1 = getregister(FU_REGONE);
+               }
+               else
+               {
+                       reg1 = indexed;
+                       indexed = 0;
+                       ++tok;
+
+                       if (*tok == '+')
+                       {
+                               parm = (WORD)(reg1 - 14 + 58);
+                               tok++;
+
+                               if (*tok >= KW_R0 && *tok <= KW_R31)
+                               {
+                                       indexed = 1;
+                               }
+
+                               if (*tok == SYMBOL)
+                               {
+                                       sy = lookup((char *)tok[1], LABEL, 0);
+
+                                       if (!sy)
+                                       {
+                                               error(reg_err);
+                                               return ERROR;
+                                       }
+
+                                       if (sy->sattre & EQUATEDREG)
+                                       {
+                                               indexed = 1;
+                                       } 
+                               }
+
+                               if (indexed)
+                               {
+                                       reg1 = getregister(FU_REGONE);
+                               }
+                               else
+                               {
+                                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                                       {
+                                               goto malformed;
+                                       }
+                                       else
+                                       {
+                                               tdb = (WORD)(eattr & TDB);
+                                               defined = (WORD)(eattr & DEFINED);
+
+                                               if ((challoc - ch_size) < 4)
+                                                       chcheck(4L);
+
+                                               if (!defined)
+                                               {
+                                                       error("constant expected");
+                                                       return ERROR;
+                                                       //fixup(FU_WORD|FU_REGONE, sloc, r_expr);
+                                                       reg1 = 0;
+                                               }
+                                               else
+                                               {
+                                                       reg1 = eval;
+
+                                                       if (reg1 == 0)
+                                                       {
+                                                               reg1 = 14 + (parm - 58);
+                                                               parm = 41;
+                                                               warn("NULL offset removed");
+                                                       }
+                                                       else
+                                                       {
+                                                               if (reg1 < 1 || reg1 > 32)
+                                                               {
+                                                                       error("constant out of range");
+                                                                       return ERROR;
+                                                               }
+
+                                                               if (reg1 == 32)
+                                                                       reg1 = 0;
+
+                                                               parm = (WORD)(parm - 58 + 43);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               reg1 = getregister(FU_REGONE);
+                       }
+               }
+
+               if (*tok != ')')
+                       goto malformed;
+
+               ++tok;
+               CHECK_COMMA;
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               risc_instruction_word(parm, reg1, reg2);
+               break;
+       // Rn,(Rn) = 47 / Rn,(R14/R15+n) = 49/50 / Rn,(R14/R15+Rn) = 60/61
+       case RI_STORE:    
+               parm = 47;
+               reg1 = getregister(FU_REGONE);
+               CHECK_COMMA;
 
+               if (*tok != '(') goto malformed;
+
+               ++tok;
+               indexed = 0;
+
+               if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok+1) != ')')) 
+                       indexed = (*tok - KW_R0);
+
+               if (*tok == SYMBOL)
+               {
+                       sy = lookup((char *)tok[1], LABEL, 0);
+
+                       if (!sy)
+                       {
+                               error(reg_err);
+                               return ERROR;
+                       }
+
+                       if (sy->sattre & EQUATEDREG) 
+                       {
+                               if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15)
+                                       && (*(tok+2) != ')'))
+                               {
+                                       indexed = (sy->svalue & 0x1F);
+                                       ++tok;
+                               }
+                       }
+               }
+
+               if (!indexed)
+               {
+                       reg2 = getregister(FU_REGTWO);
+               }
+               else
+               {
+                       reg2 = indexed;
+                       indexed = 0;
+                       ++tok;
+
+                       if (*tok == '+')
+                       {
+                               parm = (WORD)(reg2 - 14 + 60);
+                               tok++;
+
+                               if (*tok >= KW_R0 && *tok <= KW_R31)
+                               {
+                                       indexed = 1;
+                               }
+
+                               if (*tok == SYMBOL)
+                               {
+                                       sy = lookup((char *)tok[1], LABEL, 0);
+
+                                       if (!sy)
+                                       {
+                                               error(reg_err);
+                                               return ERROR;
+                                       }
+
+                                       if (sy->sattre & EQUATEDREG)
+                                       {
+                                               indexed = 1;
+                                       }
+                               }
+
+                               if (indexed)
+                               {
+                                       reg2 = getregister(FU_REGTWO);
+                               }
+                               else
+                               {
+                                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                                       {
+                                               goto malformed;
+                                       }
+                                       else
+                                       {
+                                               tdb = (WORD)(eattr & TDB);
+                                               defined = (WORD)(eattr & DEFINED);
+
+                                               if ((challoc - ch_size) < 4)
+                                                       chcheck(4L);
+
+                                               if (!defined)
+                                               {
+                                                       fixup(FU_WORD|FU_REGTWO, sloc, r_expr);
+                                                       reg2 = 0;
+                                               }
+                                               else
+                                               {
+                                                       reg2 = eval;
+
+                                                       if (reg2 == 0 )
+                                                       {
+                                                               reg2 = 14 + (parm - 60);
+                                                               parm = 47;
+                                                               warn("NULL offset removed");
+                                                       }
+                                                       else
+                                                       {
+                                                               if (reg2 < 1 || reg2 > 32)
+                                                               {
+                                                                       error("constant out of range");
+                                                                       return ERROR;
+                                                               }
+
+                                                               if (reg2 == 32)
+                                                                       reg2 = 0;
+
+                                                               parm = (WORD)(parm - 60 + 49);
+                                                       }
+                                               }       
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               reg2 = getregister(FU_REGTWO);
+                       }
+               }
+
+               if (*tok != ')')
+                       goto malformed;
+
+               ++tok;
+               at_eol();
+               risc_instruction_word(parm, reg2, reg1);
+               break;
+       // LOADB/LOADP/LOADW (Rn),Rn
+       case RI_LOADN:                    
+               if (*tok != '(')
+                       goto malformed;
+
+               ++tok;
+               reg1 = getregister(FU_REGONE);
+
+               if (*tok != ')')
+                       goto malformed;
+
+               ++tok;
+               CHECK_COMMA;
+               reg2 = getregister(FU_REGTWO);
+               at_eol();
+               risc_instruction_word(parm, reg1, reg2);
+               break;
+       // STOREB/STOREP/STOREW Rn,(Rn)
+       case RI_STOREN:                   
+               reg1 = getregister(FU_REGONE);
+               CHECK_COMMA;
+
+               if (*tok != '(')
+                       goto malformed;
+
+               ++tok;
+               reg2 = getregister(FU_REGTWO);
+
+               if (*tok != ')')
+                       goto malformed;
+
+               ++tok;
+               at_eol();
+               risc_instruction_word(parm, reg2, reg1);
+               break;
+       case RI_JR:                       // Jump Relative - cc,n - n=-16..+15 words, reg2=cc
+       case RI_JUMP:                     // Jump Absolute - cc,(Rs) - reg2=cc
+               // Check to see if there is a comma in the token string. If not then the JR or JUMP should
+               // default to 0, Jump Always
+               t = i = c = 0;
+               while (t != EOL)
+               {
+                       t = *(tok + i);
+                       if (t == ',') c = 1;
+                       i++;
+               }
+
+               if (c)
+               {                                            // Comma present in token string
+                       if (*tok == CONST)
+                       {                             // CC using a constant number
+                               ++tok;
+                               val = *tok;
+                               ++tok;
+                               CHECK_COMMA;
+                       }
+                       else if (*tok == SYMBOL)
+                       {
+                               val = 99;
+
+                               for(i=0; i<MAXINTERNCC; i++)
+                               {
+                                       strcpy(scratch, (char *)tok[1]);
+                                       strtoupper(scratch);
+
+                                       if (!strcmp(condname[i], scratch)) 
+                                               val = condnumber[i];
+                               }
+
+                               if (val == 99)
+                               {
+                                       ccsym = lookup((char *)tok[1], LABEL, 0);
+
+                                       if (ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC))
+                                       {
+                                               val = ccsym->svalue;
+                                       }
+                                       else
+                                       {
+                                               error("unknown condition code");
+                                               return ERROR;
+                                       }
+                               }
+
+                               tok += 2;
+                               CHECK_COMMA;
+                       }
+                       else if (*tok == '(')
+                       {
+                               val = 0;                                     // Jump always
+                       }
+               }
+               else
+               {
+                       val = 0;                                        // Jump always
+               }
+
+               if (val < 0 || val > 31)
+               {
+                       error("condition constant out of range");
+                       return ERROR;
+               }
+               else
+               {
+                       reg1 = val;                                     // Store condition code
+               }
+
+               if (type == RI_JR)
+               {                                // JR cc,n
+                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                               goto malformed;
+                       else
+                       {
+                               tdb = (WORD)(eattr & TDB);
+                               defined = (WORD)(eattr & DEFINED);
+
+                               if ((challoc - ch_size) < 4)
+                                       chcheck(4L);
+
+                               if (!defined)
+                               {
+                                       if (in_main)
+                                       {
+                                               fixup(FU_WORD|FU_MJR, sloc, r_expr);
+                                       }
+                                       else
+                                       {
+                                               fixup(FU_WORD|FU_JR, sloc, r_expr);
+                                       }
+
+                                       reg2 = 0;
+                               }
+                               else
+                               {
+                                       val = eval;
+
+                                       if (orgactive)
+                                       {
+                                               reg2 = ((int)(val - (orgaddr + 2))) / 2;
+                                               if ((reg2 < -16) || (reg2 > 15))
+                                               error("PC relative overflow");
+                                               locptr = orgaddr;
+                                       }
+                                       else
+                                       {
+                                               reg2 = ((int)(val - (sloc + 2))) / 2;
+                                               if ((reg2 < -16) || (reg2 > 15))
+                                               error("PC relative overflow");
+                                               locptr = sloc;
+                                       }
+                               }       
+
+                               if (in_main)
+                               {
+                                       if (defined)
+                                       {
+                                               if (((locptr >= 0xF03000) && (locptr < 0xF04000)
+                                                       && (val < 0xF03000)) || ((val >= 0xF03000)
+                                                       && (val < 0xF04000) && (locptr < 0xF03000)))
+                                               {
+                                                       warn("* cannot jump relative between main memory and local gpu ram");
+                                               }
+                                               else
+                                               {
+                                                       page_jump = (locptr & 0xFFFFFF00) - (val & 0xFFFFFF00);
+
+                                                       if (page_jump)
+                                                       {
+                                                               if (val % 4)
+                                                               {
+                                                                       warn("* destination address not aligned for long page jump relative, "
+                                                                       "insert a \'nop\' before the destination label/address");
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               if ((val - 2) % 4)
+                                                               {
+                                                                       warn("* destination address not aligned for short page jump relative, "
+                                                                               "insert a \'nop\' before the destination label/address");
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       risc_instruction_word(parm, reg2, reg1);
+               }
+               else
+               {                                           // JUMP cc, (Rn)
+                       if (*tok != '(')
+                               goto malformed;
+
+                       ++tok;
+                       reg2 = getregister(FU_REGTWO);
+
+                       if (*tok != ')')
+                               goto malformed;
+
+                       ++tok;
+                       at_eol();
+
+                       if (in_main)
+                       {
+                               if (!mjump_align)
+                               {
+                                       warn("* \'jump\' is not recommended for .gpumain as destination addresses "
+                                               "cannot be validated for alignment, use \'mjump\'");
+                                       locptr = (orgactive) ? orgaddr : sloc;
+
+                                       if (locptr % 4)
+                                       {
+                                               warn("* source address not aligned for long or short jump, "
+                                                       "insert a \'nop\' before the \'jump\'");
+                                       }          
+                               }
+                               else
+                               {
+                                       if (mjump_defined)
+                                       {
+                                               locptr = (orgactive) ? orgaddr : sloc;
+                                               page_jump = (locptr & 0xFFFFFF00) - (mjump_dest & 0xFFFFFF00);
+
+                                               if (page_jump)
+                                               {
+                                                       if (mjump_dest % 4)
+                                                       {
+                                                               warn("* destination address not aligned for long page jump, "
+                                                               "insert a \'nop\' before the destination label/address");
+                                                       }          
+                                               }
+                                               else
+                                               {
+                                                       if (!(mjump_dest & 0x0000000F) || ((mjump_dest - 2) % 4))
+                                                       {
+                                                               warn("* destination address not aligned for short page jump, "
+                                                               "insert a \'nop\' before the destination label/address");
+                                                       }          
+                                               }
+                                       }
+                                       else
+                                       {
+                                               locptr = (orgactive) ? orgaddr : sloc;
+                                               fwdjump[fwindex++] = locptr;
+                                       }
+                               }
+                       }
+
+                       risc_instruction_word(parm, reg2, reg1);
+               }
+
+               break;
+       // Should never get here :D
+       default:                                              
+               error("unknown risc opcode type");
+               return ERROR;
+               break;
+       }
+
+       return 0;
+}
diff --git a/rmac.c b/rmac.c
index f0b7efb41b8f3ec94e3cda5154a5fee35e0ff2eb..3cc24f4e3ee74dc80416735311ede284c72cb74d 100644 (file)
--- a/rmac.c
+++ b/rmac.c
@@ -68,15 +68,16 @@ static int mthresh;                                         // MTHRESHold in cha
 
 
 //
-// qst: Do a quicksort. First, find the median element, and put that one in the first place as 
-// the discriminator.  (This "median" is just the median of the first, last and middle elements).
-// (Using this median instead of the first element is a big win).  Then, the usual 
-// partitioning/swapping, followed by moving the discriminator into the right place.  Then, 
-// figure out the sizes of the two partions, do the smaller one recursively and the larger one 
-// via a repeat of this code.  Stopping when there are less than THRESH elements in a partition
-// and cleaning up with an insertion sort (in our caller) is a huge win. All data swaps are done 
-// in-line, which is space-losing but time-saving. (And there are only three places where 
-// this is done).
+// qst: Do a quicksort. First, find the median element, and put that one in the
+// first place as the discriminator. (This "median" is just the median of the
+// first, last and middle elements). (Using this median instead of the first
+// element is a big win). Then, the usual partitioning/swapping, followed by
+// moving the discriminator into the right place. Then, figure out the sizes of
+// the two partions, do the smaller one recursively and the larger one via a
+// repeat of this code.  Stopping when there are less than THRESH elements in a
+// partition and cleaning up with an insertion sort (in our caller) is a huge
+// win. All data swaps are done in-line, which is space-losing but time-saving.
+// (And there are only three places where this is done).
 //
 static int qst(char * base, char * max)
 {
@@ -87,58 +88,85 @@ static int qst(char * base, char * max)
 
    /*
         * At the top here, lo is the number of characters of elements in the
-        * current partition.  (Which should be max - base).
+        * current partition. (Which should be max - base).
         * Find the median of the first, last, and middle element and make
-        * that the middle element.  Set j to largest of first and middle.
+        * that the middle element. Set j to largest of first and middle.
         * If max is larger than that guy, then it's that guy, else compare
-        * max with loser of first and take larger.  Things are set up to
+        * max with loser of first and take larger. Things are set up to
         * prefer the middle, then the first in case of ties.
         */
        lo = max - base;                /* number of elements as chars */
-       do      {
+
+       do
+       {
                mid = i = base + qsz * ((lo / qsz) >> 1);
-               if (lo >= mthresh) {
+
+               if (lo >= mthresh)
+               {
                        j = (qcmp((jj = base), i) > 0 ? jj : i);
-                       if (qcmp(j, (tmp = max - qsz)) > 0) {
+
+                       if (qcmp(j, (tmp = max - qsz)) > 0)
+                       {
                                /* switch to first loser */
                                j = (j == jj ? i : jj);
+
                                if (qcmp(j, tmp) < 0)
                                        j = tmp;
                        }
-                       if (j != i) {
+
+                       if (j != i)
+                       {
                                ii = qsz;
-                               do      {
+
+                               do
+                               {
                                        c = *i;
                                        *i++ = *j;
                                        *j++ = c;
-                               } while (--ii);
+                               }
+                               while (--ii);
                        }
                }
+
                /*
                 * Semi-standard quicksort partitioning/swapping
                 */
-               for (i = base, j = max - qsz; ; ) {
+               for(i=base, j=max-qsz; ;)
+               {
                        while (i < mid && qcmp(i, mid) <= 0)
                                i += qsz;
-                       while (j > mid) {
-                               if (qcmp(mid, j) <= 0) {
+
+                       while (j > mid)
+                       {
+                               if (qcmp(mid, j) <= 0)
+                               {
                                        j -= qsz;
                                        continue;
                                }
+
                                tmp = i + qsz;  /* value of i after swap */
-                               if (i == mid) {
+
+                               if (i == mid)
+                               {
                                        /* j <-> mid, new mid is j */
                                        mid = jj = j;
-                               } else {
+                               }
+                               else
+                               {
                                        /* i <-> j */
                                        jj = j;
                                        j -= qsz;
                                }
+
                                goto swap;
                        }
-                       if (i == mid) {
+
+                       if (i == mid)
+                       {
                                break;
-                       } else {
+                       }
+                       else
+                       {
                                /* i <-> mid, new mid is i */
                                jj = mid;
                                tmp = mid = i;  /* value of i after swap */
@@ -146,13 +174,18 @@ static int qst(char * base, char * max)
                        }
 swap:
                        ii = qsz;
-                       do      {
+
+                       do
+                       {
                                c = *i;
                                *i++ = *jj;
                                *jj++ = c;
-                       } while (--ii);
+                       }
+                       while (--ii);
+
                        i = tmp;
                }
+
                /*
                 * Look at sizes of the two partitions, do the smaller
                 * one first by recursion, then do the larger one by
@@ -162,19 +195,26 @@ swap:
                 * of at least size THRESH.
                 */
                i = (j = mid) + qsz;
-               if ((lo = j - base) <= (hi = max - i)) {
+
+               if ((lo = j - base) <= (hi = max - i))
+               {
                        if (lo >= thresh)
                                qst(base, j);
+
                        base = i;
                        lo = hi;
-               } else {
+               }
+               else
+               {
                        if (hi >= thresh)
                                qst(i, max);
+
                        max = j;
                }
-       } while (lo >= thresh);
+       }
+       while (lo >= thresh);
 
-   return(0);
+       return 0;
 }
 
 
@@ -184,13 +224,13 @@ swap:
  * with qst(), and then a cleanup insertion sort ourselves.  Sound simple?
  * It's not...
  */
-int rmac_qsort(char * base, int n, int size, int       (*compar)())
+int rmac_qsort(char * base, int n, int size, int (*compar)())
 {
        register char c, * i, * j, * lo, * hi;
        char * min, * max;
 
        if (n <= 1)
-               return(0);
+               return 0;
 
        qsz = size;
        qcmp = compar;
@@ -214,20 +254,23 @@ int rmac_qsort(char * base, int n, int size, int  (*compar)())
         * the first THRESH elements (or the first n if n < THRESH), finding
         * the min, and swapping it into the first position.
         */
-       for (j = lo = base; (lo += qsz) < hi; )
+       for(j=lo=base; (lo+=qsz)<hi;)
+       {
                if (qcmp(j, lo) > 0)
                        j = lo;
+       }
 
        if (j != base)
        {
                /* swap j into place */
-               for (i = base, hi = base + qsz; i < hi; )
+               for(i=base, hi=base+qsz; i<hi;)
                {
                        c = *j;
                        *j++ = *i;
                        *i++ = c;
                }
        }
+
        /*
         * With our sentinel in place, we now run the following hyper-fast
         * insertion sort.  For each remaining element, min, from [1] to [n-1],
@@ -235,19 +278,26 @@ int rmac_qsort(char * base, int n, int size, int  (*compar)())
         * Then, do the standard insertion sort shift on a character at a time
         * basis for each element in the frob.
         */
-       for (min = base; (hi = min += qsz) < max; ) {
+       for(min=base; (hi=min+=qsz)<max;)
+       {
                while (qcmp(hi -= qsz, min) > 0)
                        /* void */;
-               if ((hi += qsz) != min) {
-                       for (lo = min + qsz; --lo >= min; ) {
+
+               if ((hi += qsz) != min)
+               {
+                       for(lo=min+qsz; --lo>=min;)
+                       {
                                c = *lo;
-                               for (i = j = lo; (j -= qsz) >= hi; i = j)
+
+                               for(i=j=lo; (j-=qsz)>=hi; i=j)
                                        *i = *j;
+
                                *i = c;
                        }
                }
        }
-   return(0);
+
+       return 0;
 }
 
 
@@ -477,331 +527,308 @@ void display_version(void)
 //
 int process(int argc, char ** argv)
 {
-   int argno;                                               // Argument number
-   SYM * sy;                                                 // Pointer to a symbol record
-   char * s;                                                 // String pointer
-   int fd;                                                  // File descriptor
-   char fnbuf[FNSIZ];                                       // Filename buffer 
-   int i;                                                   // Iterator
-
-   errcnt = 0;                                              // Initialise error count
-   listing = 0;                                             // Initialise listing level
-   list_flag = 0;                                           // Initialise listing flag
-   verb_flag = perm_verb_flag;                              // Initialise verbose flag
-   as68_flag = 0;                                           // Initialise as68 kludge mode
-   glob_flag = 0;                                           // Initialise .globl flag
-   sbra_flag = 0;                                           // Initialise short branch flag
-   debug = 0;                                               // Initialise debug flag
-   searchpath = NULL;                                       // Initialise search path
-   objfname = NULL;                                         // Initialise object filename
-   list_fname = NULL;                                       // Initialise listing filename
-   err_fname = NULL;                                        // Initialise error filename
-   obj_format = BSD;                                        // Initialise object format
-   firstfname = NULL;                                       // Initialise first filename
-   err_fd = ERROUT;                                         // Initialise error file descriptor
-   err_flag = 0;                                            // Initialise error flag
-   rgpu = 0;                                                // Initialise GPU assembly flag
-   rdsp = 0;                                                // Initialise DSP assembly flag
-   lsym_flag = 1;                                           // Include local symbols in object file
-   regbank = BANK_N;                                        // No RISC register bank specified
-   orgactive = 0;                                           // Not in RISC org section
-   orgwarning = 0;                                          // No ORG warning issued
-   a_amount = 0;
-   segpadsize = 2;                                          // Initialise segment padding size
-   in_main = 0;
-
-   // Initialise modules
-       init_sym();                                              // Symbol table
-   init_token();                                            // Tokenizer
-   init_procln();                                           // Line processor
-   init_expr();                                             // Expression analyzer
-   init_sect();                                             // Section manager / code generator
-   init_mark();                                             // Mark tape-recorder
-       init_macro();                                            // Macro processor
-   init_list();                                             // Listing generator
-
-   // Process command line arguments and assemble source files
-   for(argno = 0; argno < argc; ++argno) {
-      if (*argv[argno] == '-') {
-         switch(argv[argno][1]) {
-            case 'd':                                       // Define symbol
-            case 'D':
-               for(s = argv[argno] + 2; *s != EOS;) {
-                  if (*s++ == '=') {
-                     s[-1] = EOS;
-                     break;
-                                               }
-               }
-               if (argv[argno][2] == EOS) {
-                  printf("-d: empty symbol\n");
-                  ++errcnt;
-                  return(errcnt);
-               }
-               sy = lookup(argv[argno] + 2, 0, 0);
-               if (sy == NULL) {
-                  sy = newsym(argv[argno] + 2, LABEL, 0);
-                  sy->svalue = 0;
-               }
-               sy->sattr = DEFINED | EQUATED | ABS;
-               if (*s)
-                  sy->svalue = (VALUE)atoi(s);
-               else
-                  sy->svalue = 0;
-               break;
-            case 'e':                                       // Redirect error message output
-            case 'E':
-               err_fname = argv[argno] + 2;
-               break;
-            case 'f':                                       // -f<format>
-            case 'F':
-               switch(argv[argno][2]) {
-                  case EOS:
-                  case 'b':                                 // -fb = BSD (Jaguar Recommended)
-                  case 'B':
-                     obj_format = BSD;
-                     break;
-                  default:
-                     printf("-f: unknown object format specified\n");
-                     ++errcnt;
-                     return(errcnt);
-               }
-               break;
-            case 'g':                                       // Debugging flag
-            case 'G':
-               printf("Debugging flag (-g) not yet implemented\n");
-               break;
-            case 'i':                                       // Set directory search path
-            case 'I':
-               searchpath = argv[argno] + 2;
-               break;
-            case 'l':                                       // Produce listing file
-            case 'L':
-               list_fname = argv[argno] + 2;
-               listing = 1;
-               list_flag = 1;
-               ++lnsave;
-               break;
-            case 'o':                                       // Direct object file output
-            case 'O':
-               if (argv[argno][2] != EOS) objfname = argv[argno] + 2;
-               else {
-                  if (++argno >= argc) {
-                     printf("Missing argument to -o");
-                     ++errcnt;
-                     return(errcnt);
-                  }
-                  objfname = argv[argno];
-               }
-               break;
-            case 'r':                                       // Pad seg to requested boundary size
-            case 'R':
-               switch(argv[argno][2]) {
-                  case 'w': case 'W': segpadsize = 2;  break;  
-                  case 'l': case 'L': segpadsize = 4;  break;
-                  case 'p': case 'P': segpadsize = 8;  break;
-                  case 'd': case 'D': segpadsize = 16; break;
-                  case 'q': case 'Q': segpadsize = 32; break;
-                  default: segpadsize = 2; break;           // Effective autoeven();
-               }
-               break;
-            case 's':                                       // Warn about possible short branches
-            case 'S':
-               sbra_flag = 1;
-               break;
-            case 'u':                                       // Make undefined symbols .globl
-            case 'U':
-               glob_flag = 1;
-               break;
-            case 'v':                                       // Verbose flag
-            case 'V':
-               verb_flag++;
-               if (verb_flag > 1) display_version();
-               break;
-            case 'x':                                       // Turn on debugging
-            case 'X':
-               debug = 1;
-               printf("~ Debugging ON\n");
-               break;
-            case 'y':                                       // -y<pagelen>
-            case 'Y':
-               pagelen = atoi(argv[argno] + 2);
-               if (pagelen < 10) {
-                  printf("-y: bad page length\n");
-                  ++errcnt;
-                  return(errcnt);
-               }
-               break;
-            case EOS:                                       // Input is stdin
-               if (firstfname == NULL)                       // Kludge first filename
-                  firstfname = defname;
-               include(0, "(stdin)");
-               assemble();
-               break;
-            case 'h':                                       // Display command line usage
-            case 'H':
-            case '?':
-               display_version();
-               display_help();
-               ++errcnt;
-               break;
-            default:
-               display_version();
-               printf("Unknown switch: %s\n\n", argv[argno]);
-               display_help();
-               ++errcnt;
-               break;
-         }
-      } else {
-         // Record first filename.
-         if (firstfname == NULL)
-            firstfname = argv[argno];
-         strcpy(fnbuf, argv[argno]);
-         fext(fnbuf, ".s", 0);
-         fd = open(fnbuf, 0);
-         if (fd < 0) {
-            printf("Cannot open: %s\n", fnbuf);
-            ++errcnt;
-            continue;
-         }
-         include(fd, fnbuf);
-         assemble();
-      }
-   }
-
-   // Wind-up processing;
-   // o  save current section (no more code generation)
-   // o  do auto-even of all sections (or boundary alignment as requested through '-r')
-   // o  determine name of object file:
-   //    -  "foo.o" for linkable output;
-   //    -  "foo.prg" for GEMDOS executable (-p flag).
-   savsect();
-   for(i = TEXT; i <= BSS; i <<= 1) {
-      switchsect(i);
-      switch(segpadsize) {
-         case 2:  d_even();    break;
-         case 4:  d_long();    break;
-         case 8:  d_phrase();  break;
-         case 16: d_dphrase(); break;
-         case 32: d_qphrase(); break;
-      }
-      savsect();
-   }
-
-   if (objfname == NULL) {
-      if (firstfname == NULL)
-         firstfname = defname;
-      strcpy(fnbuf, firstfname);
-      //fext(fnbuf, prg_flag ? ".prg" : ".o", 1);
-      fext(fnbuf, ".o", 1);
-      objfname = fnbuf;
-   }
-
-   // With one pass finished, go back and:
-   // (1)   run through all the fixups and resolve forward references;
-   // (1.5) ensure that remaining fixups can be handled by the linker
-   //       (`lo68' format, extended (postfix) format....)
-   // (2)   generate the output file image and symbol table;
-   // (3)   generate relocation information from left-over fixups.
-   fixups();                                                // Do all fixups
-   stopmark();                                              // Stop mark tape-recorder
-   if (errcnt == 0) {
-      if ((fd = open(objfname, _OPEN_FLAGS, _PERM_MODE)) < 0)
-         cantcreat(objfname);
-      if (verb_flag) {
-         s = "object";
-         printf("[Writing %s file: %s]\n", s, objfname);
-      }
-      object((WORD)fd);
-      close(fd);
-      if (errcnt != 0)
-         unlink(objfname);
-   }
-
-   if (list_flag) {
-      if (verb_flag) printf("[Wrapping-up listing file]\n");
-      listing = 1;
-      symtable();
-      close(list_fd);
-   }
-
-   if (err_flag)
-      close(err_fd);
-
-   DEBUG dump_everything();
-
-   return(errcnt);
-}
+       int argno;                                              // Argument number
+       SYM * sy;                                               // Pointer to a symbol record
+       char * s;                                               // String pointer
+       int fd;                                                 // File descriptor
+       char fnbuf[FNSIZ];                              // Filename buffer 
+       int i;                                                  // Iterator
+
+       errcnt = 0;                                             // Initialise error count
+       listing = 0;                                    // Initialise listing level
+       list_flag = 0;                                  // Initialise listing flag
+       verb_flag = perm_verb_flag;             // Initialise verbose flag
+       as68_flag = 0;                                  // Initialise as68 kludge mode
+       glob_flag = 0;                                  // Initialise .globl flag
+       sbra_flag = 0;                                  // Initialise short branch flag
+       debug = 0;                                              // Initialise debug flag
+       searchpath = NULL;                              // Initialise search path
+       objfname = NULL;                                // Initialise object filename
+       list_fname = NULL;                              // Initialise listing filename
+       err_fname = NULL;                               // Initialise error filename
+       obj_format = BSD;                               // Initialise object format
+       firstfname = NULL;                              // Initialise first filename
+       err_fd = ERROUT;                                // Initialise error file descriptor
+       err_flag = 0;                                   // Initialise error flag
+       rgpu = 0;                                               // Initialise GPU assembly flag
+       rdsp = 0;                                               // Initialise DSP assembly flag
+       lsym_flag = 1;                                  // Include local symbols in object file
+       regbank = BANK_N;                               // No RISC register bank specified
+       orgactive = 0;                                  // Not in RISC org section
+       orgwarning = 0;                                 // No ORG warning issued
+       a_amount = 0;
+       segpadsize = 2;                                 // Initialise segment padding size
+       in_main = 0;
+
+       // Initialise modules
+       init_sym();                                             // Symbol table
+       init_token();                                   // Tokenizer
+       init_procln();                                  // Line processor
+       init_expr();                                    // Expression analyzer
+       init_sect();                                    // Section manager / code generator
+       init_mark();                                    // Mark tape-recorder
+       init_macro();                                   // Macro processor
+       init_list();                                    // Listing generator
+
+       // Process command line arguments and assemble source files
+       for(argno = 0; argno < argc; ++argno)
+       {
+               if (*argv[argno] == '-')
+               {
+                       switch (argv[argno][1])
+                       {
+                       case 'd':                                       // Define symbol
+                       case 'D':
+                               for(s=argv[argno]+2; *s!=EOS;)
+                               {
+                                       if (*s++ == '=')
+                                       {
+                                               s[-1] = EOS;
+                                               break;
+                                       }
+                               }
 
+                               if (argv[argno][2] == EOS)
+                               {
+                                       printf("-d: empty symbol\n");
+                                       ++errcnt;
+                                       return errcnt;
+                               }
 
-#if 0
-//
-// Interactive Mode
-//
-void interactive(void)
-{
-       char * s;                                                 // String pointer for banner
-       char ln[LNSIZ];                                          // Input line
-       char * argv[MAXARGV];                                     // Argument values
-       int argcnt;                                              // Argument count
-
-   // As there is no command line, print a copyright message and prompt for command line
-       s = "*****************************************************\n";
-       printf("\n%s* RMAC - Reboot's Macro Assembler for Atari Jaguar  *\n", s);
-       printf("* Copyright (C) 199x Landon Dyer, 2011 Reboot       *\n");
-       printf("* Version %01i.%01i.%01i                Platform: %-9s  *\n",MAJOR,MINOR,PATCH,PLATFORM);
-       printf("* ------------------------------------------------- *\n");
-       printf("* INTERACTIVE MODE (press ENTER by itself to quit)  *\n%s\n", s);
-
-       perm_verb_flag = 1;                                      // Enter permanent verbose mode
-
-       // Handle commandlines until EOF or we get an empty one
-       for(;;)
-       {
-               loop:
-               printf("* ");
-               fflush(stdout);                                       // Make prompt visible
+                               sy = lookup(argv[argno] + 2, 0, 0);
 
-//             if (gets(ln) == NULL || !*ln)                          // Get input line
-               if (fgets(ln, LNSIZ, stdin) == NULL || !*ln)                          // Get input line
-                       break;
+                               if (sy == NULL)
+                               {
+                                       sy = newsym(argv[argno] + 2, LABEL, 0);
+                                       sy->svalue = 0;
+                               }
 
-               argcnt = 0;                                           // Process input line
-               s = ln;
+                               sy->sattr = DEFINED | EQUATED | ABS;
 
-               while (*s)
-               {
-                       if (isspace(*s))
-                       {                                  // Skip whitespace
-                               ++s;
-                       }
-                       else
-                       {
-                               if (argcnt >= MAXARGV)
+                               if (*s)
+                                       sy->svalue = (VALUE)atoi(s);
+                               else
+                                       sy->svalue = 0;
+
+                               break;
+                       case 'e':                                       // Redirect error message output
+                       case 'E':
+                               err_fname = argv[argno] + 2;
+                               break;
+                       case 'f':                                       // -f<format>
+                       case 'F':
+                               switch (argv[argno][2])
                                {
-                                       printf("Too many arguments\n");
-                                       goto loop;
+                               case EOS:
+                               case 'b':                                 // -fb = BSD (Jaguar Recommended)
+                               case 'B':
+                                       obj_format = BSD;
+                                       break;
+                               default:
+                                       printf("-f: unknown object format specified\n");
+                                       ++errcnt;
+                                       return errcnt;
+                               }
+                               break;
+                       case 'g':                                       // Debugging flag
+                       case 'G':
+                               printf("Debugging flag (-g) not yet implemented\n");
+                               break;
+                       case 'i':                                       // Set directory search path
+                       case 'I':
+                               searchpath = argv[argno] + 2;
+                               break;
+                       case 'l':                                       // Produce listing file
+                       case 'L':
+                               list_fname = argv[argno] + 2;
+                               listing = 1;
+                               list_flag = 1;
+                               ++lnsave;
+                               break;
+                       case 'o':                                       // Direct object file output
+                       case 'O':
+                               if (argv[argno][2] != EOS)
+                                       objfname = argv[argno] + 2;
+                               else
+                               {
+                                       if (++argno >= argc)
+                                       {
+                                               printf("Missing argument to -o");
+                                               ++errcnt;
+                                               return errcnt;
+                                       }
+                                       objfname = argv[argno];
                                }
 
-                               argv[argcnt++] = s;
+                               break;
+                       case 'r':                                       // Pad seg to requested boundary size
+                       case 'R':
+                               switch(argv[argno][2])
+                               {
+                               case 'w': case 'W': segpadsize = 2;  break;  
+                               case 'l': case 'L': segpadsize = 4;  break;
+                               case 'p': case 'P': segpadsize = 8;  break;
+                               case 'd': case 'D': segpadsize = 16; break;
+                               case 'q': case 'Q': segpadsize = 32; break;
+                               default: segpadsize = 2; break;           // Effective autoeven();
+                               }
+                               break;
+                       case 's':                                       // Warn about possible short branches
+                       case 'S':
+                               sbra_flag = 1;
+                               break;
+                       case 'u':                                       // Make undefined symbols .globl
+                       case 'U':
+                               glob_flag = 1;
+                               break;
+                       case 'v':                                       // Verbose flag
+                       case 'V':
+                               verb_flag++;
+
+                               if (verb_flag > 1)
+                                       display_version();
+
+                               break;
+                       case 'x':                                       // Turn on debugging
+                       case 'X':
+                               debug = 1;
+                               printf("~ Debugging ON\n");
+                               break;
+                       case 'y':                                       // -y<pagelen>
+                       case 'Y':
+                               pagelen = atoi(argv[argno] + 2);
+
+                               if (pagelen < 10)
+                               {
+                                       printf("-y: bad page length\n");
+                                       ++errcnt;
+                                       return errcnt;
+                               }
 
-                               while (*s && !isspace(*s))
-                                       ++s;
+                               break;
+                       case EOS:                                       // Input is stdin
+                               if (firstfname == NULL)                       // Kludge first filename
+                                       firstfname = defname;
 
-                               if (isspace(*s))
-                                       *s++ = EOS;
+                               include(0, "(stdin)");
+                               assemble();
+                               break;
+                       case 'h':                                       // Display command line usage
+                       case 'H':
+                       case '?':
+                               display_version();
+                               display_help();
+                               ++errcnt;
+                               break;
+                       default:
+                               display_version();
+                               printf("Unknown switch: %s\n\n", argv[argno]);
+                               display_help();
+                               ++errcnt;
+                               break;
                        }
                }
+               else
+               {
+                       // Record first filename.
+                       if (firstfname == NULL)
+                               firstfname = argv[argno];
 
-               if (argcnt == 0)                                       // Exit if no arguments
-                       break;
+                       strcpy(fnbuf, argv[argno]);
+                       fext(fnbuf, ".s", 0);
+                       fd = open(fnbuf, 0);
 
-               process(argcnt, argv);                                // Process arguments
+                       if (fd < 0)
+                       {
+                               printf("Cannot open: %s\n", fnbuf);
+                               ++errcnt;
+                               continue;
+                       }
+
+                       include(fd, fnbuf);
+                       assemble();
+               }
+       }
+
+       // Wind-up processing;
+       // o  save current section (no more code generation)
+       // o  do auto-even of all sections (or boundary alignment as requested through '-r')
+       // o  determine name of object file:
+       //    -  "foo.o" for linkable output;
+       //    -  "foo.prg" for GEMDOS executable (-p flag).
+       savsect();
+
+       for(i=TEXT; i<=BSS; i<<=1)
+       {
+               switchsect(i);
+
+               switch(segpadsize)
+               {
+               case 2:  d_even();    break;
+               case 4:  d_long();    break;
+               case 8:  d_phrase();  break;
+               case 16: d_dphrase(); break;
+               case 32: d_qphrase(); break;
+               }
+
+               savsect();
+       }
+
+       if (objfname == NULL)
+       {
+               if (firstfname == NULL)
+                       firstfname = defname;
+
+               strcpy(fnbuf, firstfname);
+               //fext(fnbuf, prg_flag ? ".prg" : ".o", 1);
+               fext(fnbuf, ".o", 1);
+               objfname = fnbuf;
+       }
+
+       // With one pass finished, go back and:
+       // (1)   run through all the fixups and resolve forward references;
+       // (1.5) ensure that remaining fixups can be handled by the linker
+       //       (`lo68' format, extended (postfix) format....)
+       // (2)   generate the output file image and symbol table;
+       // (3)   generate relocation information from left-over fixups.
+       fixups();                                                // Do all fixups
+       stopmark();                                              // Stop mark tape-recorder
+
+       if (errcnt == 0)
+       {
+               if ((fd = open(objfname, _OPEN_FLAGS, _PERM_MODE)) < 0)
+                       cantcreat(objfname);
+
+               if (verb_flag)
+               {
+                       s = "object";
+                       printf("[Writing %s file: %s]\n", s, objfname);
+               }
+
+               object((WORD)fd);
+               close(fd);
 
-               if (errcnt)
-                       printf("%d assembly error%s\n", errcnt, (errcnt > 1) ? "s" : "");
+               if (errcnt != 0)
+                       unlink(objfname);
        }
+
+       if (list_flag)
+       {
+               if (verb_flag)
+                       printf("[Wrapping-up listing file]\n");
+
+               listing = 1;
+               symtable();
+               close(list_fd);
+       }
+
+       if (err_flag)
+               close(err_fd);
+
+       DEBUG dump_everything();
+
+       return errcnt;
 }
-#endif
 
 
 //
@@ -824,28 +851,24 @@ int get_endianess(void)
 //
 int main(int argc, char ** argv)
 {
-       int status;                                              // Status flag
+       int status;
        int i;
 
-       perm_verb_flag = 0;                                      // Clobber "permanent" verbose flag
-       cmdlnexec = argv[0];                                     // Obtain executable name
+       perm_verb_flag = 0;                             // Clobber "permanent" verbose flag
+       cmdlnexec = argv[0];                    // Obtain executable name
 
-       endian = get_endianess();                                // Get processor endianess
+       endian = get_endianess();               // Get processor endianess
 
        for(i=0; i<MAXFWDJUMPS; i++)
                fwdjump[i] = 0;
 
+       // Full command line passed
        if (argc > 1)
-       {                                           // Full command line passed
+       {
                status = process(argc - 1, argv + 1);              
        }
-       // Interactive mode 
        else
        {
-// Sorry Landon, this is the year 20xx and we haz plenty of resources now ;-)
-//             status = 0;
-//             interactive();
-               // Instead, we show a nice banner and switches :-)
                display_version();
                display_help();
        }
diff --git a/sect.c b/sect.c
index 3968dd57ed485331a8aee25001e95d05d8eb32db..0a23b4b3776878f333c10e34b6873e5cf0c90406 100644 (file)
--- a/sect.c
+++ b/sect.c
@@ -26,12 +26,12 @@ int cursect;                                                // Current section n
 WORD scattr;                                                // Section attributes 
 LONG sloc;                                                  // Current loc in section 
 
-CHUNK *scode;                                               // Current (last) code chunk 
+CHUNK * scode;                                              // Current (last) code chunk 
 LONG challoc;                                               // #bytes alloc'd to code chunk 
 LONG ch_size;                                               // #bytes used in code chunk 
-char *chptr;                                                // Deposit point in code chunk buffer 
+char * chptr;                                               // Deposit point in code chunk buffer 
 
-CHUNK *sfix;                                                // Current (last) fixup chunk
+CHUNK * sfix;                                               // Current (last) fixup chunk
 LONG fchalloc;                                              // #bytes alloc'd to fixup chunk
 LONG fchsize;                                               // #bytes used in fixup chunk
 PTR fchptr;                                                 // Deposit point in fixup chunk buffer
@@ -64,632 +64,812 @@ static char fusizoffs[] = {
    0,                                                       // FU_6BRA
 };
 
+
 //
-// --- Make a New (Clean) Section ------------------------------------------------------------------
+// Make a New (Clean) Section
 //
-
-void mksect(int sno, WORD attr) {
-   SECT *p;                                                 // Section pointer
-
-   p = &sect[sno];
-   p->scattr = attr;
-   p->sloc = 0;
-   p->scode = p->sfcode = NULL;
-   p->sfix = p->sffix = NULL;
+void mksect(int sno, WORD attr)
+{
+       SECT * p;                                                 // Section pointer
+
+       p = &sect[sno];
+       p->scattr = attr;
+       p->sloc = 0;
+       p->scode = p->sfcode = NULL;
+       p->sfix = p->sffix = NULL;
 }
 
+
 //
-// --- Switch to Another Section (Copy Section & Chunk Descriptors to Global Vars for Fast Access) -
+// Switch to Another Section (Copy Section & Chunk Descriptors to Global Vars
+// for Fast Access)
 //
-
-void switchsect(int sno) {
-   SECT *p;                                                 // Section pointer
-   CHUNK *cp;                                               // Chunk pointer
-
-   cursect = sno;
-   p = &sect[sno];
-
-   scattr = p->scattr;                                      // Copy section vars
-   sloc = p->sloc;
-   scode = p->scode;
-   sfix = p->sfix;
-
-   if((cp = scode) != NULL) {                               // Copy code chunk vars
-      challoc = cp->challoc;
-      ch_size = cp->ch_size;
-      chptr = cp->chptr + ch_size;
-   } else challoc = ch_size = 0;
-
-   if((cp = sfix) != NULL) {                                // Copy fixup chunk vars 
-      fchalloc = cp->challoc;
-      fchsize = cp->ch_size;
-      fchptr.cp = cp->chptr + fchsize;
-   } else fchalloc = fchsize = 0;
+void switchsect(int sno)
+{
+       SECT * p;                                                // Section pointer
+       CHUNK * cp;                                              // Chunk pointer
+
+       cursect = sno;
+       p = &sect[sno];
+
+       scattr = p->scattr;                                      // Copy section vars
+       sloc = p->sloc;
+       scode = p->scode;
+       sfix = p->sfix;
+
+       if ((cp = scode) != NULL)
+       {                               // Copy code chunk vars
+               challoc = cp->challoc;
+               ch_size = cp->ch_size;
+               chptr = cp->chptr + ch_size;
+       }
+       else
+               challoc = ch_size = 0;
+
+       if ((cp = sfix) != NULL)
+       {                                // Copy fixup chunk vars 
+               fchalloc = cp->challoc;
+               fchsize = cp->ch_size;
+               fchptr.cp = cp->chptr + fchsize;
+       }
+       else
+               fchalloc = fchsize = 0;
 }
 
+
 //
-// --- Save Current Section ------------------------------------------------------------------------
+// Save Current Section
 //
+void savsect(void)
+{
+       SECT * p = &sect[cursect];
 
-void savsect(void) {
-   SECT *p;
+       p->scattr = scattr;                                      // Bailout section vars
+       p->sloc = sloc;
 
-   p = &sect[cursect];
+       if (scode != NULL)                                        // Bailout code chunk
+               scode->ch_size = ch_size;
 
-   p->scattr = scattr;                                      // Bailout section vars
-   p->sloc = sloc;
-
-   if(scode != NULL)                                        // Bailout code chunk
-      scode->ch_size = ch_size;
-
-   if(sfix != NULL)                                         // Bailout fixup chunk
-      sfix->ch_size = fchsize;
+       if (sfix != NULL)                                         // Bailout fixup chunk
+               sfix->ch_size = fchsize;
 }
 
+
 //
-// --- Initialize Sections; Setup initial ABS, TEXT, DATA and BSS sections -------------------------
+// Initialize Sections; Setup initial ABS, TEXT, DATA and BSS sections
 //
-
-void init_sect(void) {
-   int i;                                                   // Iterator
-
-   // Cleanup all sections
-   for(i = 0; i < NSECTS; ++i)
-      mksect(i, 0);
-
-   // Construct default sections, make TEXT the current section
-   mksect(ABS,   SUSED|SABS|SBSS);                          // ABS
-   mksect(TEXT,  SUSED|TEXT     );                          // TEXT
-   mksect(DATA,  SUSED|DATA     );                          // DATA
-   mksect(BSS,   SUSED|BSS |SBSS);                          // BSS
-//   mksect(M6502, SUSED|TEXT     );                          // 6502 code section
-
-   switchsect(TEXT);                                        // Switch to TEXT for starters
+void init_sect(void)
+{
+       int i;                                                   // Iterator
+
+       // Cleanup all sections
+       for(i=0; i<NSECTS; ++i)
+               mksect(i, 0);
+
+       // Construct default sections, make TEXT the current section
+       mksect(ABS,   SUSED|SABS|SBSS);                          // ABS
+       mksect(TEXT,  SUSED|TEXT     );                          // TEXT
+       mksect(DATA,  SUSED|DATA     );                          // DATA
+       mksect(BSS,   SUSED|BSS |SBSS);                          // BSS
+//     mksect(M6502, SUSED|TEXT     );                          // 6502 code section
+
+       switchsect(TEXT);                                        // Switch to TEXT for starters
 }
 
+
 //
-// -------------------------------------------------------------------------------------------------
-// Test to see if a location has a fixup sic'd on it.  This is used by the listing
-// generator to print 'xx's instead of '00's for forward references
-// -------------------------------------------------------------------------------------------------
+// Test to see if a location has a fixup sic'd on it.  This is used by the
+// listing generator to print 'xx's instead of '00's for forward references
 //
-
-int fixtest(int sno, LONG loc) {
-   CHUNK *ch;
-   PTR fup;
-   char *fuend;
-   WORD w;
-   LONG xloc;
-
-   stopmark();                                              // Force update to sect[] variables
-
-   // Hairy, ugly linear search for a mark on our location;
-   // the speed doesn't matter, since this is only done when generating a listing, which is SLOW.
-   for(ch = sect[sno].sffix; ch != NULL; ch = ch->chnext) {
-      fup.cp = (char *)ch->chptr;
-      fuend = fup.cp + ch->ch_size;
-
-      while(fup.cp < fuend) {
-         w = *fup.wp++;
-         xloc = *fup.lp++ + (int)fusizoffs[w & FUMASK];
-         fup.wp += 2;
-
-         if(xloc == loc)
-            return((int)fusiztab[w & FUMASK]);
-
-         if(w & FU_EXPR) {
-            w = *fup.wp++;
-            fup.lp += w;
-         } else ++fup.lp;
-      }
-   }
-
-   return(0);
+int fixtest(int sno, LONG loc)
+{
+       CHUNK * ch;
+       PTR fup;
+       char * fuend;
+       WORD w;
+       LONG xloc;
+
+       stopmark();                                              // Force update to sect[] variables
+
+       // Hairy, ugly linear search for a mark on our location;
+       // the speed doesn't matter, since this is only done when generating a listing, which is SLOW.
+       for(ch=sect[sno].sffix; ch!=NULL; ch=ch->chnext)
+       {
+               fup.cp = (char *)ch->chptr;
+               fuend = fup.cp + ch->ch_size;
+
+               while (fup.cp < fuend)
+               {
+                       w = *fup.wp++;
+                       xloc = *fup.lp++ + (int)fusizoffs[w & FUMASK];
+                       fup.wp += 2;
+
+                       if (xloc == loc)
+                               return (int)fusiztab[w & FUMASK];
+
+                       if (w & FU_EXPR)
+                       {
+                               w = *fup.wp++;
+                               fup.lp += w;
+                       }
+                       else
+                               ++fup.lp;
+               }
+       }
+
+       return 0;
 }
 
+
 // 
-// -------------------------------------------------------------------------------------------------
-// Check that there are at least `amt' bytes left in the current chunk.  If there are not, 
-// allocate another chunk of at least `amt' bytes (and probably more).
+// Check that there are at least `amt' bytes left in the current chunk. If
+// there are not, allocate another chunk of at least `amt' bytes (and probably
+// more).
 // 
 // If `amt' is zero, ensure there are at least CH_THRESHOLD bytes, likewise.
-// -------------------------------------------------------------------------------------------------
 //
-
-int chcheck(LONG amt) {
-   CHUNK *cp;
-   SECT *p;
-
-   if(scattr & SBSS) return(0);                             // If in BSS section, forget it
-
-   if(!amt) amt = CH_THRESHOLD;
-
-   if((int)(challoc - ch_size) >= (int)amt) 
-      return(0);
-
-   if(amt < CH_CODE_SIZE) amt = CH_CODE_SIZE;
-   p = &sect[cursect];
-   cp = (CHUNK *)amem((long)(sizeof(CHUNK) + amt));
-   if(scode == NULL) {                                      // First chunk in section
-      cp->chprev = NULL;
-      p->sfcode = cp;
-   } else {                                                 // Add chunk to other chunks
-      cp->chprev = scode;
-      scode->chnext = cp;
-      scode->ch_size = ch_size;                             // Save old chunk's globals 
-   }
-
-   // Setup chunk and global vars
-   cp->chloc = sloc;
-   cp->chnext = NULL;
-   challoc = cp->challoc = amt;
-   ch_size = cp->ch_size = 0;
-   chptr = cp->chptr = ((char *)cp) + sizeof(CHUNK);
-   scode = p->scode = cp;
-
-   return(0);
+int chcheck(LONG amt)
+{
+       CHUNK * cp;
+       SECT * p;
+
+       if (scattr & SBSS)
+               return 0;                             // If in BSS section, forget it
+
+       if (!amt)
+               amt = CH_THRESHOLD;
+
+       if ((int)(challoc - ch_size) >= (int)amt) 
+               return 0;
+
+       if (amt < CH_CODE_SIZE)
+               amt = CH_CODE_SIZE;
+
+       p = &sect[cursect];
+       cp = (CHUNK *)amem((long)(sizeof(CHUNK) + amt));
+
+       if (scode == NULL)
+       {                                      // First chunk in section
+               cp->chprev = NULL;
+               p->sfcode = cp;
+       }
+       else
+       {                                                 // Add chunk to other chunks
+               cp->chprev = scode;
+               scode->chnext = cp;
+               scode->ch_size = ch_size;                             // Save old chunk's globals 
+       }
+
+       // Setup chunk and global vars
+       cp->chloc = sloc;
+       cp->chnext = NULL;
+       challoc = cp->challoc = amt;
+       ch_size = cp->ch_size = 0;
+       chptr = cp->chptr = ((char *)cp) + sizeof(CHUNK);
+       scode = p->scode = cp;
+
+       return 0;
 }
 
+
 //
-// --- Arrange for a fixup on a location -----------------------------------------------------------
+// Arrange for a fixup on a location
 //
-
-int fixup(WORD attr, LONG loc, TOKEN *fexpr) {
-   LONG i;
-   LONG len = 0;
-   CHUNK *cp;
-   SECT *p;
-
-   // Compute length of expression (could be faster); determine if it's the single-symbol case;
-   // no expression if it's just a mark. This code assumes 16 bit WORDs and 32 bit LONGs
-   if(*fexpr == SYMBOL && fexpr[2] == ENDEXPR)
-      //if((attr & 0x0F00) == FU_JR) {
-      if((attr & 0x0200) == FU_JR) {
-         i = 18;                  // Just a single symbol
-      } else {
-         i = 14;
-      }
-   else {
-      attr |= FU_EXPR;
-      for(len = 0; fexpr[len] != ENDEXPR; ++len)
-         if(fexpr[len] == CONST || fexpr[len] == SYMBOL)
-            ++len;
-      ++len;                                                // Add 1 for ENDEXPR 
-      i = (len << 2) + 12;
-   }
-
-   // Maybe alloc another fixup chunk for this one to fit in
-   if((fchalloc - fchsize) < i) {
-      p = &sect[cursect];
-         cp = (CHUNK *)amem((long)(sizeof(CHUNK) + CH_FIXUP_SIZE));
-      if(sfix == NULL) {                                 // First fixup chunk in section
-         cp->chprev = NULL;
-         p->sffix = cp;
-      } else {                                           // Add to other chunks
-         cp->chprev = sfix;
-         sfix->chnext = cp;
-         sfix->ch_size = fchsize;
-      }
-
-      // Setup fixup chunk and its global vars
-      cp->chnext = NULL;
-      fchalloc = cp->challoc = CH_FIXUP_SIZE;
-      fchsize = cp->ch_size = 0;
-      fchptr.cp = cp->chptr = ((char *)cp) + sizeof(CHUNK);
-      sfix = p->sfix = cp;
-   }
-
-   // Record fixup type, fixup location, and the file number and line number the fixup is 
-   // located at.
-   *fchptr.wp++ = attr;
-   *fchptr.lp++ = loc;
-   *fchptr.wp++ = cfileno;
-   *fchptr.wp++ = (WORD)curlineno;
-   // Store postfix expression or pointer to a single symbol, or nothing for a mark.
-   if(attr & FU_EXPR) {
-      *fchptr.wp++ = (WORD)len;
-      while(len--)
-         *fchptr.lp++ = (LONG)*fexpr++;
-   } else  {
-      *fchptr.lp++ = (LONG)fexpr[1];
-   }
-
-   //if((attr & 0x0F00) == FU_JR) {
-   if((attr & 0x0200) == FU_JR) {
-      if(orgactive) *fchptr.lp++ = orgaddr;
-      else *fchptr.lp++ = 0x00000000;
-   }
-
-   fchsize += i;
-
-   return(0);
+int fixup(WORD attr, LONG loc, TOKEN * fexpr)
+{
+       LONG i;
+       LONG len = 0;
+       CHUNK * cp;
+       SECT * p;
+
+       // Compute length of expression (could be faster); determine if it's the single-symbol case;
+       // no expression if it's just a mark. This code assumes 16 bit WORDs and 32 bit LONGs
+       if (*fexpr == SYMBOL && fexpr[2] == ENDEXPR)
+       {
+               //if ((attr & 0x0F00) == FU_JR) {
+               if ((attr & 0x0200) == FU_JR)
+               {
+                       i = 18;                  // Just a single symbol
+               }
+               else
+               {
+                       i = 14;
+               }
+       }
+       else
+       {
+               attr |= FU_EXPR;
+
+               for(len=0; fexpr[len]!=ENDEXPR; ++len)
+               {
+                       if (fexpr[len] == CONST || fexpr[len] == SYMBOL)
+                               ++len;
+               }
+
+               ++len;                                                // Add 1 for ENDEXPR 
+               i = (len << 2) + 12;
+       }
+
+       // Maybe alloc another fixup chunk for this one to fit in
+       if ((fchalloc - fchsize) < i)
+       {
+               p = &sect[cursect];
+               cp = (CHUNK *)amem((long)(sizeof(CHUNK) + CH_FIXUP_SIZE));
+
+               if (sfix == NULL)
+               {                                 // First fixup chunk in section
+                       cp->chprev = NULL;
+                       p->sffix = cp;
+               }
+               else
+               {                                           // Add to other chunks
+                       cp->chprev = sfix;
+                       sfix->chnext = cp;
+                       sfix->ch_size = fchsize;
+               }
+
+               // Setup fixup chunk and its global vars
+               cp->chnext = NULL;
+               fchalloc = cp->challoc = CH_FIXUP_SIZE;
+               fchsize = cp->ch_size = 0;
+               fchptr.cp = cp->chptr = ((char *)cp) + sizeof(CHUNK);
+               sfix = p->sfix = cp;
+       }
+
+       // Record fixup type, fixup location, and the file number and line number the fixup is 
+       // located at.
+       *fchptr.wp++ = attr;
+       *fchptr.lp++ = loc;
+       *fchptr.wp++ = cfileno;
+       *fchptr.wp++ = (WORD)curlineno;
+
+       // Store postfix expression or pointer to a single symbol, or nothing for a mark.
+       if (attr & FU_EXPR)
+       {
+               *fchptr.wp++ = (WORD)len;
+
+               while (len--)
+                       *fchptr.lp++ = (LONG)*fexpr++;
+       }
+       else
+       {
+               *fchptr.lp++ = (LONG)fexpr[1];
+       }
+
+       //if ((attr & 0x0F00) == FU_JR) {
+       if ((attr & 0x0200) == FU_JR)
+       {
+               if (orgactive)
+                       *fchptr.lp++ = orgaddr;
+               else
+                       *fchptr.lp++ = 0x00000000;
+       }
+
+       fchsize += i;
+
+       return 0;
 }
 
+
 //
-// --- Resolve all Fixups --------------------------------------------------------------------------
+// Resolve all Fixups
 //
-
-int fixups(void) {
-   unsigned i;                                              // Iterator
-   char buf[EBUFSIZ];
-
-   if(glob_flag)                                            // Make undefined symbols GLOBL
-      syg_fix();
-   resfix(TEXT);
-   resfix(DATA);
-   
-   // We need to do a final check of forward 'jump' destination addresses that are external
-   for(i = 0; i < MAXFWDJUMPS; i++) {
-      if(fwdjump[i]) {
-         err_setup();
-         sprintf(buf, "* \'jump\' at $%08X - destination address is external to this source file and "
-                 "cannot have its aligment validated", fwdjump[i]);
-         if(listing > 0) ship_ln(buf);
-         if(err_flag) write(err_fd, buf, (LONG)strlen(buf));
-         else printf("%s\n", buf);
-      }
-   }
-
-   return(0);
+int fixups(void)
+{
+       unsigned i;
+       char buf[EBUFSIZ];
+
+       // Make undefined symbols GLOBL
+       if (glob_flag)
+               syg_fix();
+
+       resfix(TEXT);
+       resfix(DATA);
+       
+       // We need to do a final check of forward 'jump' destination addresses that are external
+       for(i=0; i<MAXFWDJUMPS; i++)
+       {
+               if (fwdjump[i])
+               {
+                       err_setup();
+                       sprintf(buf, "* \'jump\' at $%08X - destination address is external to this source file and cannot have its aligment validated", fwdjump[i]);
+
+                       if (listing > 0)
+                               ship_ln(buf);
+
+                       if (err_flag)
+                               write(err_fd, buf, (LONG)strlen(buf));
+                       else
+                               printf("%s\n", buf);
+               }
+       }
+
+       return 0;
 }
 
+
 //
-// --- Resolve Fixups in a Section -----------------------------------------------------------------
+// Resolve Fixups in a Section
 //
-
-int resfix(int sno) {
-   SECT *sc;                                                // Section
-   CHUNK *ch;
-   PTR fup;                                                 // Current fixup
-   WORD *fuend;                                             // End of last fixup (in this chunk)
-   CHUNK *cch;                                              // Cached chunk for target
-   WORD w;                                                  // Fixup word (type+modes+flags)
-   char *locp;                                              // Location to fix (in cached chunk) 
-   LONG loc;                                                // Location to fixup
-   VALUE eval;                                              // Expression value 
-   WORD eattr;                                              // Expression attrib
-   SYM *esym;                                               // External symbol involved in expr
-   SYM *sy;                                                 // (Temp) pointer to a symbol
-   WORD i;                                                  // (Temp) word
-   WORD tdb;                                                // eattr & TDB
-   LONG oaddr;
-   int reg2;
-   WORD flags;
-   unsigned page_jump = 0;
-   unsigned address = 0;
-   unsigned j;                                              // iterator
-   char buf[EBUFSIZ];
-   
-   sc = &sect[sno];
-   ch = sc->sffix;
-
-   if(ch == NULL)
-      return(0);
-
-   cch = sc->sfcode;                                        // "cache" first chunk
-   if(cch == NULL)                                          // Can't fixup a sect with nothing in it
-      return(0);
-
-   do {
-      fup.cp = ch->chptr;                                   // fup -> start of chunk
-      fuend = (WORD *)(fup.cp + ch->ch_size);               // fuend -> end of chunk
-      while(fup.wp < fuend) {
-         w = *fup.wp++;
-         loc = *fup.lp++;
-         cfileno = *fup.wp++;
-         curlineno = (int)*fup.wp++;
-
-         esym = NULL;
-         // Search for chunk containing location to fix up; compute a pointer to the location 
-         // (in the chunk). Often we will find the fixup is in the "cached" chunk, so the 
-         // linear-search is seldom executed.
-         if(loc < cch->chloc || loc >= (cch->chloc + cch->ch_size)) {
-            for(cch = sc->sfcode; cch != NULL; cch = cch->chnext)
-               if(loc >= cch->chloc && loc < (cch->chloc + cch->ch_size))
-                  break;
-            if(cch == NULL) {
-               interror(7);                                 // Fixup (loc) out of range 
+int resfix(int sno)
+{
+       SECT * sc;                                      // Section
+       CHUNK * ch;
+       PTR fup;                                        // Current fixup
+       WORD * fuend;                           // End of last fixup (in this chunk)
+       CHUNK * cch;                            // Cached chunk for target
+       WORD w;                                         // Fixup word (type+modes+flags)
+       char * locp;                            // Location to fix (in cached chunk) 
+       LONG loc;                                       // Location to fixup
+       VALUE eval;                                     // Expression value 
+       WORD eattr;                                     // Expression attrib
+       SYM * esym;                                     // External symbol involved in expr
+       SYM * sy;                                       // (Temp) pointer to a symbol
+       WORD i;                                         // (Temp) word
+       WORD tdb;                                       // eattr & TDB
+       LONG oaddr;
+       int reg2;
+       WORD flags;
+       unsigned page_jump = 0;
+       unsigned address = 0;
+       unsigned j;
+       char buf[EBUFSIZ];
+       
+       sc = &sect[sno];
+       ch = sc->sffix;
+
+       if (ch == NULL)
+               return 0;
+
+       cch = sc->sfcode;                                        // "cache" first chunk
+
+       if (cch == NULL)                                          // Can't fixup a sect with nothing in it
+               return 0;
+
+       do
+       {
+               fup.cp = ch->chptr;                                   // fup -> start of chunk
+               fuend = (WORD *)(fup.cp + ch->ch_size);               // fuend -> end of chunk
+
+               while (fup.wp < fuend)
+               {
+                       w = *fup.wp++;
+                       loc = *fup.lp++;
+                       cfileno = *fup.wp++;
+                       curlineno = (int)*fup.wp++;
+
+                       esym = NULL;
+
+                       // Search for chunk containing location to fix up; compute a pointer to the location 
+                       // (in the chunk). Often we will find the fixup is in the "cached" chunk, so the 
+                       // linear-search is seldom executed.
+                       if (loc < cch->chloc || loc >= (cch->chloc + cch->ch_size))
+                       {
+                               for(cch=sc->sfcode; cch!=NULL; cch=cch->chnext)
+                               {
+                                       if (loc >= cch->chloc && loc < (cch->chloc + cch->ch_size))
+                                               break;
+                               }
+
+                               if (cch == NULL)
+                               {
+                                       interror(7);                                 // Fixup (loc) out of range 
                                        // NOTREACHED
-            }
-         }
-         locp = cch->chptr + (loc - cch->chloc);
-
-         eattr = 0;
-
-         // Compute expression/symbol value and attribs
-         if(w & FU_EXPR) {                                  // Complex expression
-            i = *fup.wp++;
-            if(evexpr(fup.tk, &eval, &eattr, &esym) != OK) {
-               fup.lp += i;
-               continue;
-            }
-            fup.lp += i;
-         } else {                                           // Simple symbol
-            sy = *fup.sy++;
-            eattr = sy->sattr;
-            if(eattr & DEFINED)
-               eval = sy->svalue;
-            else eval = 0;
-
-            if((eattr & (GLOBAL|DEFINED)) == GLOBAL)
-               esym = sy;
-         }
-         tdb = (WORD)(eattr & TDB);
-         // If the expression is undefined and no external symbol is involved, then it's an error.
-         if(!(eattr & DEFINED) && esym == NULL) {
-            error(undef_error);
-            continue;
-         }
-
-
-         if(((w & 0x0F00) == FU_MOVEI) && esym)
-            esym->sattre |= RISCSYM;
-
-         // Do the fixup
-         // 
-         // If a PC-relative fixup is undefined, its value is *not* subtracted from the location
-         // (that will happen in the linker when the external reference is resolved).
-         // 
-         // MWC expects PC-relative things to have the LOC subtracted from the value, if the 
-         // value is external (that is, undefined at this point).
-         // 
-         // PC-relative fixups must be DEFINED and either in the same section (whereupon the 
-         // subtraction takes place) or ABS (with no subtract).
-         if(w & FU_PCREL) {
-            if(eattr & DEFINED) {
-               if(tdb == sno) eval -= (VALUE)loc;
-               else if(tdb) {
-                  error("PC-relative expr across sections");
-                  continue;
-               }
-
-               if(sbra_flag && (w & FU_LBRA) && (eval + 0x80 < 0x100))
-                  warn("unoptimized short branch");
-            } else 
-               if(obj_format == MWC) eval -= (VALUE)loc;
-
-            tdb = 0;
-            eattr &= ~TDB;
-         }
-
-         // Do fixup classes
-         switch((int)(w & FUMASK)) {
-            // FU_BBRA fixes up a one-byte branch offset.
-            case FU_BBRA:
-               if(!(eattr & DEFINED)) {
-                  error("external short branch");
-                  continue;
-               }
-               eval -= 2;
-               if(eval + 0x80 >= 0x100)
-                  goto range;
-               if(eval == 0) {
-                  error("illegal bra.s with zero offset");
-                  continue;
-               }
-               *++locp = (char)eval;
-               break;
-            // Fixup one-byte value at locp + 1.
-            case FU_WBYTE:
-               ++locp;
-               // FALLTHROUGH
-               // Fixup one-byte forward references
-            case FU_BYTE:
-               if(!(eattr & DEFINED)) {
-                  error("external byte reference");
-                  continue;
-               }
-               if(tdb) {
-                  error("non-absolute byte reference");
-                  continue;
-               }
-               if((w & FU_PCREL) && eval + 0x80 >= 0x100) goto range;
-               if(w & FU_SEXT) {
-                  if(eval + 0x100 >= 0x200) goto range;
-               } else 
-                  if(eval >= 0x100) goto range;
-
-               *locp = (char)eval;
-               break;
-            // Fixup WORD forward references; 
-            // the word could be unaligned in the section buffer, so we have to be careful.
-            case FU_WORD:
-               if(((w & 0x0F00) == FU_JR) || ((w & 0x0F00) == FU_MJR)) {
-                  oaddr = *fup.lp++;
-                  if(oaddr) {
-                     reg2 = (signed)((eval - (oaddr + 2)) / 2);// & 0x1F;
-                  } else {
-                     reg2 = (signed)((eval - (loc + 2)) / 2);// & 0x1F;
-                  }
-                  if((w & 0x0F00) == FU_MJR) {
-                     // Main code destination alignment checking here for forward declared labels
-                     address = (oaddr) ? oaddr : loc;
-                     if(((address >= 0xF03000) && (address < 0xF04000) && (eval    < 0xF03000)) ||
-                        ((eval    >= 0xF03000) && (eval    < 0xF04000) && (address < 0xF03000)) ) {
-                        warni("* \'jr\' at $%08X - cannot jump relative between "
-                              "main memory and local gpu ram", address);
-                     } else {
-                        page_jump = (address & 0xFFFFFF00) - (eval & 0xFFFFFF00);
-                        if(page_jump) {
-                           // This jump is to a page outside of the current 256 byte page
-                           if(eval % 4) {
-                              warni("* \'jr\' at $%08X - destination address not aligned for long page jump, "
-                                   "insert a \'nop\' before the destination address", address);
-                           }
-                        } else {
-                           // This jump is in the current 256 byte page
-                           if((eval - 2) % 4) {
-                              warni("* \'jr\' at $%08X - destination address not aligned for short page jump, "
-                                   "insert a \'nop\' before the destination address", address);
-                           }
-                        }
-                     }
-                  }
-                  if((reg2 < -16) || (reg2 > 15)) {
-                     error("relative jump out of range");
-                     break;
-                  }
-                  *locp = (char)(*locp | ((reg2 >> 3) & 0x03));
-                  locp++;
-                  *locp = (char)(*locp | ((reg2 & 0x07) << 5));
-                  break;
-               }
-               if((w & 0x0F00) == FU_NUM15) {
-                  if(eval < -16 || eval > 15) {
-                     error("constant out of range");
-                     break;
-                  }
-                  *locp = (char)(*locp | ((eval >> 3) & 0x03));
-                  locp++;
-                  *locp = (char)(*locp | ((eval & 0x07) << 5));
-                  break;
-               }
-               if((w & 0x0F00) == FU_NUM31) {
-                  if(eval < 0 || eval > 31) {
-                     error("constant out of range");
-                     break;
-                  }
-                  *locp = (char)(*locp | ((eval >> 3) & 0x03));
-                  locp++;
-                  *locp = (char)(*locp | ((eval & 0x07) << 5));
-                  break;
-               }
-               if((w & 0x0F00) == FU_NUM32) {
-                  if(eval < 1 || eval > 32) {
-                     error("constant out of range");
-                     break;
-                  }
-                  if(w & FU_SUB32)
-                     eval = (32 - eval);
-                  eval = (eval == 32) ? 0 : eval;
-                  *locp = (char)(*locp | ((eval >> 3) & 0x03));
-                  locp++;
-                  *locp = (char)(*locp | ((eval & 0x07) << 5));
-                  break;
-               }
-               if((w & 0x0F00) == FU_REGONE) {
-                  if(eval < 0 || eval > 31) {
-                     error("register value out of range");
-                     break;
-                  }
-                  *locp = (char)(*locp | ((eval >> 3) & 0x03));
-                  locp++;
-                  *locp = (char)(*locp | ((eval & 0x07) << 5));
-                  break;
-               }
-               if((w & 0x0F00) == FU_REGTWO) {
-                  if(eval < 0 || eval > 31) {
-                     error("register value out of range");
-                     break;
-                  }
-                  locp++;
-                  *locp = (char)(*locp | (eval & 0x1F));
-                  break;
-               }
-
-               if(!(eattr & DEFINED)) {
-                  if(w & FU_PCREL)
-                     w = MPCREL | MWORD;
-                  else w = MWORD;
-                  rmark(sno, loc, 0, w, esym);
-               } else {
-                  if(tdb)
-                     rmark(sno, loc, tdb, MWORD, NULL);
-                  if(w & FU_SEXT) {
-                     if(eval + 0x10000 >= 0x20000)
-                        goto range;
-                  } else 
-                     if(w & FU_ISBRA) {                     // Range-check BRA and DBRA
-                        if(eval + 0x8000 >= 0x10000)
-                           goto range;
-                     } else 
-                        if(eval >= 0x10000)
-                           goto range;
-               }
-
-               *locp++ = (char)(eval >> 8);
-               *locp = (char)eval;
-               break;
-            // Fixup LONG forward references;
-            // the long could be unaligned in the section buffer, so be careful (again).
-            case FU_LONG:
-               if((w & 0x0F00) == FU_MOVEI) {
-                  address = loc + 4;
-                  if(eattr & DEFINED) {
-                     for(j = 0; j < fwindex; j++) {
-                        if(fwdjump[j] == address) {
-                           page_jump = (address & 0xFFFFFF00) - (eval & 0xFFFFFF00);
-                           if(page_jump) {
-                              if(eval % 4) {
-                                 err_setup();
-                                 sprintf(buf, "* \'jump\' at $%08X - destination address not aligned for long page jump, "
-                                         "insert a \'nop\' before the destination address", address);
-                                 if(listing > 0) ship_ln(buf);
-                                 if(err_flag) write(err_fd, buf, (LONG)strlen(buf));
-                                 else printf("%s\n", buf);
-                              }          
-                           } else {
-                              if(!(eval & 0x0000000F) || ((eval - 2) % 4)) {
-                                 err_setup();
-                                 sprintf(buf, "* \'jump\' at $%08X - destination address not aligned for short page jump, "
-                                         "insert a \'nop\' before the destination address", address);
-                                 if(listing > 0) ship_ln(buf);
-                                 if(err_flag) write(err_fd, buf, (LONG)strlen(buf));
-                                 else printf("%s\n", buf);
-                              }          
-                           }
-                           // Clear this jump as it has been checked
-                           fwdjump[j] = 0;
-                           j = fwindex;
-                        }
-                     }
-                  }
-                  eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
-                  flags = (MLONG|MMOVEI);
-               } else flags = MLONG;
-               if(!(eattr & DEFINED)) {
-                  rmark(sno, loc, 0, flags, esym);
-               }
-               else if(tdb) {
-                  rmark(sno, loc, tdb, flags, NULL);
-               }
-               *locp++ = (char)(eval >> 24);
-               *locp++ = (char)(eval >> 16);
-               *locp++ = (char)(eval >> 8);
-               *locp = (char)eval;
-               break;
-            // Fixup a 3-bit "QUICK" reference in bits 9..1
-            // (range of 1..8) in a word.  Really bits 1..3 in a byte.
-            case FU_QUICK:
-               if(!(eattr & DEFINED)) {
-                  error("External quick reference");
-                  continue;
-               }
-
-               if(eval < 1 || eval > 8)
-                  goto range;
-               *locp |= (eval & 7) << 1;
-               break;
-            // Fix up 6502 funny branch
-            case FU_6BRA:
-               eval -= (loc + 1);
-               if(eval + 0x80 >= 0x100)
-                  goto range;
-               *locp = (char)eval;
-               break;
-            default:
-               interror(4);                                 // Bad fixup type
-               // NOTREACHED
-         }
-         continue;
-
-         range:
-
-         error("expression out of range");
-      }
-
-      ch = ch->chnext;
-   } while(ch != NULL);
-
-   return(0);
+                               }
+                       }
+
+                       locp = cch->chptr + (loc - cch->chloc);
+
+                       eattr = 0;
+
+                       // Compute expression/symbol value and attribs
+                       if (w & FU_EXPR)
+                       {                                  // Complex expression
+                               i = *fup.wp++;
+
+                               if (evexpr(fup.tk, &eval, &eattr, &esym) != OK)
+                               {
+                                       fup.lp += i;
+                                       continue;
+                               }
+
+                               fup.lp += i;
+                       }
+                       else
+                       {                                           // Simple symbol
+                               sy = *fup.sy++;
+                               eattr = sy->sattr;
+
+                               if (eattr & DEFINED)
+                                       eval = sy->svalue;
+                               else
+                                       eval = 0;
+
+                               if ((eattr & (GLOBAL|DEFINED)) == GLOBAL)
+                                       esym = sy;
+                       }
+
+                       tdb = (WORD)(eattr & TDB);
+
+                       // If the expression is undefined and no external symbol is
+                       // involved, then it's an error.
+                       if (!(eattr & DEFINED) && esym == NULL)
+                       {
+                               error(undef_error);
+                               continue;
+                       }
+
+                       if (((w & 0x0F00) == FU_MOVEI) && esym)
+                               esym->sattre |= RISCSYM;
+
+                       // Do the fixup
+                       // 
+                       // If a PC-relative fixup is undefined, its value is *not* subtracted from the location
+                       // (that will happen in the linker when the external reference is resolved).
+                       // 
+                       // MWC expects PC-relative things to have the LOC subtracted from the value, if the 
+                       // value is external (that is, undefined at this point).
+                       // 
+                       // PC-relative fixups must be DEFINED and either in the same section (whereupon the 
+                       // subtraction takes place) or ABS (with no subtract).
+                       if (w & FU_PCREL)
+                       {
+                               if (eattr & DEFINED)
+                               {
+                                       if (tdb == sno)
+                                               eval -= (VALUE)loc;
+                                       else if (tdb)
+                                       {
+                                               error("PC-relative expr across sections");
+                                               continue;
+                                       }
+
+                                       if (sbra_flag && (w & FU_LBRA) && (eval + 0x80 < 0x100))
+                                               warn("unoptimized short branch");
+                               }
+                               else if (obj_format == MWC)
+                                       eval -= (VALUE)loc;
+
+                               tdb = 0;
+                               eattr &= ~TDB;
+                       }
+
+                       // Do fixup classes
+                       switch ((int)(w & FUMASK))
+                       {
+                       // FU_BBRA fixes up a one-byte branch offset.
+                       case FU_BBRA:
+                               if (!(eattr & DEFINED))
+                               {
+                                       error("external short branch");
+                                       continue;
+                               }
+
+                               eval -= 2;
+
+                               if (eval + 0x80 >= 0x100)
+                                       goto range;
+
+                               if (eval == 0)
+                               {
+                                       error("illegal bra.s with zero offset");
+                                       continue;
+                               }
+
+                               *++locp = (char)eval;
+                               break;
+                       // Fixup one-byte value at locp + 1.
+                       case FU_WBYTE:
+                               ++locp;
+                               // FALLTHROUGH
+                       // Fixup one-byte forward references
+                       case FU_BYTE:
+                               if (!(eattr & DEFINED))
+                               {
+                                       error("external byte reference");
+                                       continue;
+                               }
+
+                               if (tdb)
+                               {
+                                       error("non-absolute byte reference");
+                                       continue;
+                               }
+
+                               if ((w & FU_PCREL) && eval + 0x80 >= 0x100)
+                                       goto range;
+
+                               if (w & FU_SEXT)
+                               {
+                                       if (eval + 0x100 >= 0x200)
+                                               goto range;
+                               }
+                               else if (eval >= 0x100)
+                                       goto range;
+
+                               *locp = (char)eval;
+                               break;
+                       // Fixup WORD forward references; 
+                       // the word could be unaligned in the section buffer, so we have to be careful.
+                       case FU_WORD:
+                               if (((w & 0x0F00) == FU_JR) || ((w & 0x0F00) == FU_MJR))
+                               {
+                                       oaddr = *fup.lp++;
+
+                                       if (oaddr)
+                                       {
+                                               reg2 = (signed)((eval - (oaddr + 2)) / 2);// & 0x1F;
+                                       }
+                                       else
+                                       {
+                                               reg2 = (signed)((eval - (loc + 2)) / 2);// & 0x1F;
+                                       }
+
+                                       if ((w & 0x0F00) == FU_MJR)
+                                       {
+                                               // Main code destination alignment checking here for forward declared labels
+                                               address = (oaddr) ? oaddr : loc;
+
+                                               if (((address >= 0xF03000) && (address < 0xF04000)
+                                                       && (eval < 0xF03000)) || ((eval >= 0xF03000)
+                                                       && (eval < 0xF04000) && (address < 0xF03000)))
+                                               {
+                                                       warni("* \'jr\' at $%08X - cannot jump relative between "
+                                                               "main memory and local gpu ram", address);
+                                               }
+                                               else
+                                               {
+                                                       page_jump = (address & 0xFFFFFF00) - (eval & 0xFFFFFF00);
+
+                                                       if (page_jump)
+                                                       {
+                                                               // This jump is to a page outside of the current 256 byte page
+                                                               if (eval % 4)
+                                                               {
+                                                                       warni("* \'jr\' at $%08X - destination address not aligned for long page jump, insert a \'nop\' before the destination address", address);
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               // This jump is in the current 256 byte page
+                                                               if ((eval - 2) % 4)
+                                                               {
+                                                                       warni("* \'jr\' at $%08X - destination address not aligned for short page jump, insert a \'nop\' before the destination address", address);
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       if ((reg2 < -16) || (reg2 > 15))
+                                       {
+                                               error("relative jump out of range");
+                                               break;
+                                       }
+
+                                       *locp = (char)(*locp | ((reg2 >> 3) & 0x03));
+                                       locp++;
+                                       *locp = (char)(*locp | ((reg2 & 0x07) << 5));
+                                       break;
+                               }
+
+                               if ((w & 0x0F00) == FU_NUM15)
+                               {
+                                       if (eval < -16 || eval > 15)
+                                       {
+                                               error("constant out of range");
+                                               break;
+                                       }
+
+                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       locp++;
+                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       break;
+                               }
+
+                               if ((w & 0x0F00) == FU_NUM31)
+                               {
+                                       if (eval < 0 || eval > 31)
+                                       {
+                                               error("constant out of range");
+                                               break;
+                                       }
+
+                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       locp++;
+                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       break;
+                               }
+
+                               if ((w & 0x0F00) == FU_NUM32)
+                               {
+                                       if (eval < 1 || eval > 32)
+                                       {
+                                               error("constant out of range");
+                                               break;
+                                       }
+
+                                       if (w & FU_SUB32)
+                                               eval = (32 - eval);
+
+                                       eval = (eval == 32) ? 0 : eval;
+                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       locp++;
+                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       break;
+                               }
+
+                               if ((w & 0x0F00) == FU_REGONE)
+                               {
+                                       if (eval < 0 || eval > 31)
+                                       {
+                                               error("register value out of range");
+                                               break;
+                                       }
+
+                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       locp++;
+                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       break;
+                               }
+
+                               if ((w & 0x0F00) == FU_REGTWO)
+                               {
+                                       if (eval < 0 || eval > 31)
+                                       {
+                                               error("register value out of range");
+                                               break;
+                                       }
+
+                                       locp++;
+                                       *locp = (char)(*locp | (eval & 0x1F));
+                                       break;
+                               }
+
+                               if (!(eattr & DEFINED))
+                               {
+                                       if (w & FU_PCREL)
+                                               w = MPCREL | MWORD;
+                                       else
+                                               w = MWORD;
+
+                                       rmark(sno, loc, 0, w, esym);
+                               }
+                               else
+                               {
+                                       if (tdb)
+                                               rmark(sno, loc, tdb, MWORD, NULL);
+
+                                       if (w & FU_SEXT)
+                                       {
+                                               if (eval + 0x10000 >= 0x20000)
+                                                       goto range;
+                                       }
+                                       else
+                                       {
+                                               // Range-check BRA and DBRA
+                                               if (w & FU_ISBRA)
+                                               {
+                                                       if (eval + 0x8000 >= 0x10000)
+                                                       goto range;
+                                               }
+                                               else if (eval >= 0x10000)
+                                                       goto range;
+                                       }
+                               }
+
+                               *locp++ = (char)(eval >> 8);
+                               *locp = (char)eval;
+                               break;
+                       // Fixup LONG forward references;
+                       // the long could be unaligned in the section buffer, so be careful (again).
+                       case FU_LONG:
+                               if ((w & 0x0F00) == FU_MOVEI)
+                               {
+                                       address = loc + 4;
+
+                                       if (eattr & DEFINED)
+                                       {
+                                               for(j=0; j<fwindex; j++)
+                                               {
+                                                       if (fwdjump[j] == address)
+                                                       {
+                                                               page_jump = (address & 0xFFFFFF00) - (eval & 0xFFFFFF00);
+
+                                                               if (page_jump)
+                                                               {
+                                                                       if (eval % 4)
+                                                                       {
+                                                                               err_setup();
+                                                                               sprintf(buf, "* \'jump\' at $%08X - destination address not aligned for long page jump, insert a \'nop\' before the destination address", address);
+
+                                                                               if (listing > 0)
+                                                                                       ship_ln(buf);
+
+                                                                               if (err_flag)
+                                                                                       write(err_fd, buf, (LONG)strlen(buf));
+                                                                               else
+                                                                                       printf("%s\n", buf);
+                                                                       }          
+                                                               }
+                                                               else
+                                                               {
+                                                                       if (!(eval & 0x0000000F) || ((eval - 2) % 4))
+                                                                       {
+                                                                               err_setup();
+                                                                               sprintf(buf, "* \'jump\' at $%08X - destination address not aligned for short page jump, insert a \'nop\' before the destination address", address);
+
+                                                                               if (listing > 0)
+                                                                                       ship_ln(buf);
+
+                                                                               if (err_flag)
+                                                                                       write(err_fd, buf, (LONG)strlen(buf));
+                                                                               else
+                                                                                       printf("%s\n", buf);
+                                                                       }          
+                                                               }
+
+                                                               // Clear this jump as it has been checked
+                                                               fwdjump[j] = 0;
+                                                               j = fwindex;
+                                                       }
+                                               }
+                                       }
+
+                                       eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
+                                       flags = (MLONG|MMOVEI);
+                               }
+                               else
+                                       flags = MLONG;
+
+                               if (!(eattr & DEFINED))
+                               {
+                                       rmark(sno, loc, 0, flags, esym);
+                               }
+                               else if (tdb)
+                               {
+                                       rmark(sno, loc, tdb, flags, NULL);
+                               }
+
+                               *locp++ = (char)(eval >> 24);
+                               *locp++ = (char)(eval >> 16);
+                               *locp++ = (char)(eval >> 8);
+                               *locp = (char)eval;
+                               break;
+                       // Fixup a 3-bit "QUICK" reference in bits 9..1
+                       // (range of 1..8) in a word.  Really bits 1..3 in a byte.
+                       case FU_QUICK:
+                               if (!(eattr & DEFINED))
+                               {
+                                       error("External quick reference");
+                                       continue;
+                               }
+
+                               if (eval < 1 || eval > 8)
+                                       goto range;
+
+                               *locp |= (eval & 7) << 1;
+                               break;
+                       // Fix up 6502 funny branch
+                       case FU_6BRA:
+                               eval -= (loc + 1);
+
+                               if (eval + 0x80 >= 0x100)
+                                       goto range;
+
+                               *locp = (char)eval;
+                               break;
+                       default:
+                               interror(4);                                 // Bad fixup type
+                               // NOTREACHED
+                       }
+                       continue;
+range:
+                       error("expression out of range");
+               }
+
+               ch = ch->chnext;
+       }
+       while (ch != NULL);
+
+       return 0;
 }
diff --git a/sect.h b/sect.h
index 1322f52a7b4f9b88ed1881f179e7db15c6637876..764d2445c010b0c1160f7a1e5b21a18a707c45b1 100644 (file)
--- a/sect.h
+++ b/sect.h
 // Chunks are used to hold generated code and fixup records
 #define CHUNK  struct _chunk
 CHUNK {
-   CHUNK *chnext;                                           // Next, previous chunks in section
-   CHUNK *chprev;
+   CHUNK * chnext;                                          // Next, previous chunks in section
+   CHUNK * chprev;
    LONG chloc;                                              // Base addr of this chunk
    LONG challoc;                                            // #bytes allocated for chunk
    LONG ch_size;                                            // #bytes chunk actually uses
-   char *chptr;                                             // Data for this chunk
+   char * chptr;                                            // Data for this chunk
 };
 
 // Section descriptor
@@ -93,10 +93,10 @@ CHUNK {
 SECT {
    WORD scattr;                                             // Section attributes
    LONG sloc;                                               // Current loc-in / size-of section 
-   CHUNK *sfcode;                                           // First chunk in section
-   CHUNK *scode;                                            // Last chunk in section
-   CHUNK *sffix;                                            // First fixup chunk
-   CHUNK *sfix;                                             // Last fixup chunk
+   CHUNK * sfcode;                                          // First chunk in section
+   CHUNK * scode;                                           // Last chunk in section
+   CHUNK * sffix;                                           // First fixup chunk
+   CHUNK * sfix;                                            // Last fixup chunk
 };
 
 // A mark is of the form:
@@ -106,7 +106,7 @@ SECT {
 // .L    [symbol]      symbol involved in external reference
 #define MCHUNK struct _mchunk
 MCHUNK {
-   MCHUNK *mcnext;                                          // Next mark chunk
+   MCHUNK * mcnext;                                         // Next mark chunk
    PTR mcptr;                                               // Vector of marks
    LONG mcalloc;                                            // #marks allocted to mark block
    LONG mcused;                                             // #marks used in block
@@ -127,12 +127,12 @@ extern unsigned fwindex;
 // Globals, external etc
 extern LONG sloc;
 extern WORD scattr;
-extern char *chptr;
+extern char * chptr;
 extern LONG ch_size;
 extern int cursect;
 extern SECT sect[];
 extern LONG challoc;
-extern CHUNK *scode;
+extern CHUNK * scode;
 
 // Prototypes
 void init_sect(void);
index 747c5a7e7099d655437e00c17f3bc2466e422fb1..25829f41f7bbbdf5fc296a45fd28489f3afdcf49 100644 (file)
--- a/symbol.c
+++ b/symbol.c
 #include "procln.h"
 #include "error.h"
 
-static SYM *sytab[NBUCKETS];                                // User symbol-table header
+static SYM * sytab[NBUCKETS];                               // User symbol-table header
 int curenv;                                                 // Current enviroment number
-SYM *sorder;                                                // * -> Symbols, in order of reference
-SYM *sordtail;                                              // * -> Last symbol in sorder list
-SYM *sdecl;                                                 // * -> Symbols, in order of declaration
-SYM *sdecltail;                                             // * -> Last symbol in sdecl list
+SYM * sorder;                                               // * -> Symbols, in order of reference
+SYM * sordtail;                                             // * -> Last symbol in sorder list
+SYM * sdecl;                                                // * -> Symbols, in order of declaration
+SYM * sdecltail;                                            // * -> Last symbol in sdecl list
 
 // Tags for marking symbol spaces
 // a = absolute
@@ -28,354 +28,437 @@ static char tdb_text[8] = {
    'a', 't', 'd', '!', 'b', SPACE, SPACE, SPACE
 };
 
+
 //
-// --- Initialize Symbol Table ---------------------------------------------------------------------
+// Initialize Symbol Table
 //
-
-void init_sym(void) {
-   int i;                                                   // Iterator
-
-   for(i = 0; i < NBUCKETS; ++i)                            // Initialise symbol hash table
-      sytab[i] = NULL;
-
-   curenv = 1;                                              // Init local symbol enviroment
-   sorder = NULL;                                           // Init symbol-reference list
-   sordtail = NULL;
-   sdecl = NULL;                                            // Init symbol-decl list
-   sdecltail = NULL;
+void init_sym(void)
+{
+       int i;                                                   // Iterator
+
+       for(i=0; i<NBUCKETS; ++i)                            // Initialise symbol hash table
+               sytab[i] = NULL;
+
+       curenv = 1;                                              // Init local symbol enviroment
+       sorder = NULL;                                           // Init symbol-reference list
+       sordtail = NULL;
+       sdecl = NULL;                                            // Init symbol-decl list
+       sdecltail = NULL;
 }
 
+
 //
-// --- Allocate and Return Pointer to a Copy of a String -------------------------------------------
+// Allocate and Return Pointer to a Copy of a String
 //
+char * nstring(char * str)
+{
+       long i;
+       char * s, * d;
 
-char *nstring(char *str) {
-   long i;
-   char *s, *d;
-
-   for(i = 0; str[i]; ++i)
-      ;
-   s = d = amem(i + 1);
-   while(*str)
-      *d++ = *str++;
-   *d++ = '\0';
-   
-   return(s);
+       for(i=0; str[i]; ++i)
+               ;
+
+       s = d = amem(i + 1);
+
+       while (*str)
+               *d++ = *str++;
+
+       *d++ = '\0';
+       
+       return s;
 }
 
+
 //
-// --- Hash the Print Name and Enviroment Number ---------------------------------------------------
+// Hash the Print Name and Enviroment Number
 //
-int syhash(char *name, int envno) {
-   int sum, k;                                              // Hash calculation
-
-   k = 0;
-   for(sum = envno; *name; ++name) {
-      if(k++ == 1)
-         sum += *name << 2;
-      else
-         sum += *name;
-   }
-
-   return(sum & (NBUCKETS - 1));
+int syhash(char * name, int envno)
+{
+       int sum, k;                                              // Hash calculation
+       k = 0;
+
+       for(sum=envno; *name; ++name)
+       {
+               if (k++ == 1)
+                       sum += *name << 2;
+               else
+                       sum += *name;
+       }
+
+       return sum & (NBUCKETS - 1);
 }
 
+
 //
-// --- Make a new symbol of type `type' in enviroment `envno' --------------------------------------
+// Make a new symbol of type `type' in enviroment `envno'
 //
+SYM * newsym(char * name, int type, int envno)
+{
+       int hash;                                                // Symbol hash value
+       SYM * sy;                                                // Pointer to symbol
+
+       // Allocate the symbol
+       sy = (SYM *)amem((long)(sizeof(SYM)));
+
+       if (sy == NULL)
+       {
+               printf("SYMALLOC ERROR (%s)\n", name);
+               return NULL;
+       }
+
+       sy->sname = nstring(name);
+
+       // Fill-in the symbol
+       sy->stype  = (BYTE)type;
+       sy->senv   = (WORD)envno;
+       sy->sattr  = 0;
+
+       if (rgpu || rdsp)
+               sy->sattre = RISCSYM;
+       else
+               sy->sattre = 0;
+
+       sy->svalue = 0;
+
+       // Install symbol in symbol table
+       hash = syhash(name, envno);
+       sy->snext = sytab[hash];
+       sytab[hash] = sy;
 
-SYM *newsym(char *name, int type, int envno) {
-   int hash;                                                // Symbol hash value
-   SYM *sy;                                                 // Pointer to symbol
-
-   
-   // Allocate the symbol
-   sy = (SYM *)amem((long)(sizeof(SYM)));
-   if(sy == NULL) {
-      printf("SYMALLOC ERROR (%s)\n", name);
-      return(NULL);
-   }
-
-   sy->sname = nstring(name);
-
-   // Fill-in the symbol
-   sy->stype  = (BYTE)type;
-   sy->senv   = (WORD)envno;
-   sy->sattr  = 0;
-   if(rgpu || rdsp) sy->sattre = RISCSYM;
-   else sy->sattre = 0;
-   sy->svalue = 0;
-
-   // Install symbol in symbol table
-   hash = syhash(name, envno);
-   sy->snext = sytab[hash];
-   sytab[hash] = sy;
-
-   // Append symbol to symbol-order list
-   if(sorder == NULL)
-      sorder = sy;                                          // Add first symbol 
-   else
-      sordtail->sorder = sy;                                // Or append to tail of list
-
-   sy->sorder = NULL;
-   sordtail = sy;
-
-   return(sy);                                              // Return pointer to symbol
+       // Append symbol to symbol-order list
+       if (sorder == NULL)
+               sorder = sy;                                          // Add first symbol 
+       else
+               sordtail->sorder = sy;                                // Or append to tail of list
+
+       sy->sorder = NULL;
+       sordtail = sy;
+
+       return sy;                                              // Return pointer to symbol
 }
 
+
 //
-// --- Lookup the symbol `name', of the specified type, with the specified enviroment level --------
+// Lookup the symbol `name', of the specified type, with the specified
+// enviroment level
 //
-
-SYM *lookup(char *name, int type, int envno) {
-   SYM *sy;                                                 // Symbol record pointer
-   int k, sum;                                              // Hash bucket calculation
-   char *s;                                                 // String pointer
-
-   // Pick a hash-bucket (SAME algorithm as syhash())
-   k = 0;
-   s = name;
-   for(sum = envno; *s;) {
-      if(k++ == 1)
-         sum += *s++ << 2;
-      else sum += *s++;
-   }
-
-   sy = sytab[sum & (NBUCKETS-1)];
-
-   // Do linear-search for symbol in bucket
-   while(sy != NULL) {
-      if(sy->stype == type       &&                         // Type, envno and name must match
-         sy->senv  == envno      &&
-                       *name     == *sy->sname &&                         // Fast check for first character
+SYM * lookup(char * name, int type, int envno)
+{
+       SYM * sy;                                                // Symbol record pointer
+       int k, sum;                                              // Hash bucket calculation
+       char * s;                                                // String pointer
+
+       // Pick a hash-bucket (SAME algorithm as syhash())
+       k = 0;
+       s = name;
+
+       for(sum=envno; *s;)
+       {
+               if (k++ == 1)
+                       sum += *s++ << 2;
+               else
+                       sum += *s++;
+       }
+
+       sy = sytab[sum & (NBUCKETS-1)];
+
+       // Do linear-search for symbol in bucket
+       while (sy != NULL)
+       {
+               if (sy->stype == type &&                         // Type, envno and name must match
+                       sy->senv  == envno &&
+                       *name == *sy->sname &&                         // Fast check for first character
                        !strcmp(name, sy->sname))
-         break;
-      else sy = sy->snext;
-   }
+                       break;
+               else
+                       sy = sy->snext;
+       }
 
-   return(sy);                                              // Return NULL or matching symbol
+       return sy;                                              // Return NULL or matching symbol
 }
 
+
 //
-// --- Put symbol on "order-of-declaration" list of symbols ----------------------------------------
+// Put symbol on "order-of-declaration" list of symbols
 //
+void sym_decl(SYM * sym)
+{
+       if (sym->sattr & SDECLLIST)
+               return;                                                         // Already on list
 
-void sym_decl(SYM *sym) {
-   if(sym->sattr & SDECLLIST) return;                       // Already on list
-   sym->sattr |= SDECLLIST;                                 // Mark "already on list"
+       sym->sattr |= SDECLLIST;                                // Mark "already on list"
 
-   if(sdecl == NULL)
-      sdecl = sym;                                          // First on decl-list
-   else 
-      sdecltail->sdecl = sym;                               // Add to end of list
+       if (sdecl == NULL)
+               sdecl = sym;                                            // First on decl-list
+       else 
+               sdecltail->sdecl = sym;                         // Add to end of list
 
-   sym->sdecl = NULL;                                       // Fix up list's tail
-   sdecltail = sym;
+       sym->sdecl = NULL;                                              // Fix up list's tail
+       sdecltail = sym;
 }
 
+
 //
-// --- Make all referenced, undefined symbols global -----------------------------------------------
+// Make all referenced, undefined symbols global
 //
-
-int syg_fix(void) {
-   SYM *sy;
-
-   DEBUG printf("~syg_fix()\n");
-
-   // Scan through all symbols;
-   // If a symbol is REFERENCED but not DEFINED, then make it global.
-   for(sy = sorder; sy != NULL; sy = sy->sorder)
-      if(sy->stype == LABEL && sy->senv == 0 &&
-                       ((sy->sattr & (REFERENCED|DEFINED)) == REFERENCED))
-         sy->sattr |= GLOBAL;
-
-   return(0);
+int syg_fix(void)
+{
+       SYM * sy;
+
+       DEBUG printf("~syg_fix()\n");
+
+       // Scan through all symbols;
+       // If a symbol is REFERENCED but not DEFINED, then make it global.
+       for(sy = sorder; sy != NULL; sy = sy->sorder)
+       {
+               if (sy->stype == LABEL && sy->senv == 0
+                       && ((sy->sattr & (REFERENCED|DEFINED)) == REFERENCED))
+                       sy->sattr |= GLOBAL;
+       }
+
+       return 0;
 }
 
+
 //
-// --- Convert string to uppercase -----------------------------------------------------------------
+// Convert string to uppercase
 //
-
-int uc_string(char *s) {
-   for(; *s; ++s)
-      if(*s >= 'a' && *s <= 'z')
-         *s -= 32;
-   return(0);
+int uc_string(char * s)
+{
+       for(; *s; ++s)
+       {
+               if (*s >= 'a' && *s <= 'z')
+                       *s -= 32;
+       }
+
+       return 0;
 }
 
+
 //
-// -------------------------------------------------------------------------------------------------
-// Assign numbers to symbols that are to be exported or imported.  The symbol number is put in 
-// `.senv'. Return the number of symbols that will be in the symbol table.
-// -------------------------------------------------------------------------------------------------
+// Assign numbers to symbols that are to be exported or imported. The symbol
+// number is put in `.senv'. Return the number of symbols that will be in the
+// symbol table.
 //
-
-int sy_assign(char *buf, char *(*constr)()) {
-   SYM *sy;
-   int scount;
-   //int i;
-
-   scount = 0;
-
-   if(buf == NULL)
-      // Append all symbols not appearing on the .sdecl list to the end of the .sdecl list
-      for(sy = sorder; sy != NULL; sy = sy->sorder) {
-
-         // Essentially the same as 'sym_decl()' above:
-         if(sy->sattr & SDECLLIST) continue;                // Already on list 
-         sy->sattr |= SDECLLIST;                            // Mark "on the list"
-
-         if(sdecl == NULL) sdecl = sy;                      // First on decl-list 
-         else sdecltail->sdecl = sy;                        // Add to end of list
-
-         sy->sdecl = NULL;                                  // Fix up list's tail
-         sdecltail = sy;
-      }
-
-   // Run through all symbols (now on the .sdecl list) and assign numbers to them.  We also pick 
-   // which symbols should be global or not here.
-   for(sy = sdecl; sy != NULL; sy = sy->sdecl) {
-
-      if(sy->sattre & UNDEF_EQUR) continue;                 // Don't want undefined on our list
-      if(sy->sattre & UNDEF_CC) continue;                   
-      
-      // Export or import external references, and export COMMON blocks.
-      if((sy->stype == LABEL) &&
-         ((sy->sattr & (GLOBAL|DEFINED)) == (GLOBAL|DEFINED) ||
-         (sy->sattr & (GLOBAL|REFERENCED)) == (GLOBAL|REFERENCED)) ||
-         (sy->sattr & COMMON)) {
-         sy->senv = (WORD)scount++;
-         if(buf != NULL) buf = (*constr)(buf, sy, 1);
-      } else
-         // Export vanilla labels (but don't make them global). An exception is made for equates, 
-         // which are not exported unless they are referenced.
-         if(sy->stype == LABEL && lsym_flag &&
-            (sy->sattr & (DEFINED|REFERENCED)) != 0 &&
-            (!as68_flag || *sy->sname != 'L') ) {
-            sy->senv = (WORD)scount++;
-            if(buf != NULL) buf = (*constr)(buf, sy, 0);
-         }
-   }
-
-   return(scount);
+int sy_assign(char * buf, char *(*constr)())
+{
+       SYM * sy;
+       int scount;
+       //int i;
+
+       scount = 0;
+
+       if (buf == NULL)
+       {
+               // Append all symbols not appearing on the .sdecl list to the end of
+               // the .sdecl list
+               for(sy=sorder; sy!=NULL; sy=sy->sorder)
+               {
+                       // Essentially the same as 'sym_decl()' above:
+                       if (sy->sattr & SDECLLIST)
+                               continue;                // Already on list 
+
+                       sy->sattr |= SDECLLIST;                            // Mark "on the list"
+
+                       if (sdecl == NULL)
+                               sdecl = sy;                      // First on decl-list 
+                       else
+                               sdecltail->sdecl = sy;                        // Add to end of list
+
+                       sy->sdecl = NULL;                                  // Fix up list's tail
+                       sdecltail = sy;
+               }
+       }
+
+       // Run through all symbols (now on the .sdecl list) and assign numbers to
+       // them. We also pick which symbols should be global or not here.
+       for(sy=sdecl; sy!=NULL; sy=sy->sdecl)
+       {
+               if (sy->sattre & UNDEF_EQUR)
+                       continue;                 // Don't want undefined on our list
+
+               if (sy->sattre & UNDEF_CC)
+                       continue;                   
+               
+               // Export or import external references, and export COMMON blocks.
+               if ((sy->stype == LABEL)
+                       && ((sy->sattr & (GLOBAL|DEFINED)) == (GLOBAL|DEFINED)
+                       || (sy->sattr & (GLOBAL|REFERENCED)) == (GLOBAL|REFERENCED))
+                       || (sy->sattr & COMMON))
+               {
+                       sy->senv = (WORD)scount++;
+
+                       if (buf != NULL)
+                               buf = (*constr)(buf, sy, 1);
+               }
+               // Export vanilla labels (but don't make them global). An exception is
+               // made for equates, which are not exported unless they are referenced.
+               else if (sy->stype == LABEL && lsym_flag
+                       && (sy->sattr & (DEFINED|REFERENCED)) != 0
+                       && (!as68_flag || *sy->sname != 'L'))
+               {
+                       sy->senv = (WORD)scount++;
+                       if (buf != NULL) buf = (*constr)(buf, sy, 0);
+               }
+       }
+
+       return scount;
 }
 
+
 //
-// --- Generate symbol table for listing file ------------------------------------------------------
+// Generate symbol table for listing file
 //
-
-int symtable(void) {
-   int i;
-   int j;
-   SYM *q = NULL;
-   SYM *p;
-   SYM *r;
-   SYM *k;
-   SYM **sy;
-   SYM *colptr[4];
-   char ln[150];
-   char ln1[150];
-   char ln2[20];
-   char c, c1;
-   WORD w;
-   int ww;
-   int colhei;
-   extern int pagelen;
-
-   colhei = pagelen - 5;
-
-   // Allocate storage for list headers and partition all labels.  
-   // Throw away macros and macro arguments.
-   sy = (SYM **)amem((LONG)(128 * sizeof(LONG)));
-   for(i = 0; i < 128; ++i) sy[i] = NULL;
-
-   for(i = 0; i < NBUCKETS; ++i)
-      for(p = sytab[i]; p != NULL; p = k) {
-         k = p->snext;
-         j = *p->sname;
-         r = NULL;
-         if(p->stype != LABEL) continue;                    // Ignore non-labels
-         if(p->sattre & UNDEF_EQUR) continue;
-
-         for(q = sy[j]; q != NULL; q = q->snext)
-            if(strcmp(p->sname, q->sname) < 0)
-               break;
-            else r = q;
-
-         if(r == NULL) {                                    // Insert at front of list
-            p->snext = sy[j];
-            sy[j] = p;
-         } else {                                           // Insert in middle or append to list
-            p->snext = r->snext;
-            r->snext = p;
-         }
-      }
-
-   // Link all symbols onto one list again
-   p = NULL;
-   for(i = 0; i < 128; ++i)
-      if((r = sy[i]) != NULL) {
-         if(p == NULL)
-            q = r;
-         else q->snext = r;
-
-         while(q->snext != NULL)
-            q = q->snext;
-
-         if(p == NULL)
-            p = r;
-      }
-
-   eject();
-   strcpy(subttl, "Symbol Table");
-
-   while(p != NULL) {
-      for (i = 0; i < 4; ++i) {
-         colptr[i] = p;
-         for(j = 0; j < colhei; ++j)
-            if(p == NULL)
-               break;
-            else p = p->snext;
-      }
-
-      for(i = 0; i < colhei; ++i) {
-         *ln = EOS;
-         if(colptr[0] == NULL)
-            break;
-
-         for(j = 0; j < 4; ++j) {
-            if((q = colptr[j]) == NULL)
-               break;
-            colptr[j] = q->snext;
-            w = q->sattr;
-            ww = q->sattre;
-            // Pick a tag:
-            // c       common
-            // x       external reference
-            // g       global (export)
-            // space   nothing special
-            c1 = SPACE;
-            c = SPACE;
-
-            if(w & COMMON) c = 'c';
-            else if((w & (DEFINED|GLOBAL)) == GLOBAL) c = 'x';
-            else if(w & GLOBAL) c = 'g';
-
-            c1 = tdb_text[w & TDB];
-            if(c == 'x') strcpy(ln2, "external");
-            else {
-               sprintf(ln2, "%08ux", q->svalue);
-               uc_string(ln2);
-            }
-
-            sprintf(ln1, "  %16s %s %c%c%c", q->sname, ln2, (ww & EQUATEDREG) ? 'e' : SPACE, c1, c);
-
-            strcat(ln, ln1);
-         }
-         ship_ln(ln);
-      }
-      eject();
-   }
-
-   return(0);
+int symtable(void)
+{
+       int i;
+       int j;
+       SYM * q = NULL;
+       SYM * p;
+       SYM * r;
+       SYM * k;
+       SYM ** sy;
+       SYM * colptr[4];
+       char ln[150];
+       char ln1[150];
+       char ln2[20];
+       char c, c1;
+       WORD w;
+       int ww;
+       int colhei;
+       extern int pagelen;
+
+       colhei = pagelen - 5;
+
+       // Allocate storage for list headers and partition all labels.  
+       // Throw away macros and macro arguments.
+       sy = (SYM **)amem((LONG)(128 * sizeof(LONG)));
+
+       for(i=0; i<128; ++i)
+               sy[i] = NULL;
+
+       for(i=0; i<NBUCKETS; ++i)
+       {
+               for(p=sytab[i]; p!=NULL; p=k)
+               {
+                       k = p->snext;
+                       j = *p->sname;
+                       r = NULL;
+
+                       if (p->stype != LABEL)
+                               continue;                    // Ignore non-labels
+
+                       if (p->sattre & UNDEF_EQUR)
+                               continue;
+
+                       for(q=sy[j]; q!=NULL; q=q->snext)
+                       {
+                               if (strcmp(p->sname, q->sname) < 0)
+                                       break;
+                               else
+                                       r = q;
+                       }
+
+                       if (r == NULL)
+                       {                                    // Insert at front of list
+                               p->snext = sy[j];
+                               sy[j] = p;
+                       }
+                       else
+                       {                                           // Insert in middle or append to list
+                               p->snext = r->snext;
+                               r->snext = p;
+                       }
+               }
+       }
+
+       // Link all symbols onto one list again
+       p = NULL;
+
+       for(i=0; i<128; ++i)
+       {
+               if ((r = sy[i]) != NULL)
+               {
+                       if (p == NULL)
+                               q = r;
+                       else
+                               q->snext = r;
+
+                       while (q->snext != NULL)
+                               q = q->snext;
+
+                       if (p == NULL)
+                               p = r;
+               }
+       }
+
+       eject();
+       strcpy(subttl, "Symbol Table");
+
+       while (p != NULL)
+       {
+               for(i=0; i<4; ++i)
+               {
+                       colptr[i] = p;
+
+                       for(j=0; j<colhei; ++j)
+                       {
+                               if (p == NULL)
+                                       break;
+                               else
+                                       p = p->snext;
+                       }
+               }
+
+               for(i=0; i<colhei; ++i)
+               {
+                       *ln = EOS;
+
+                       if (colptr[0] == NULL)
+                               break;
+
+                       for(j=0; j<4; ++j)
+                       {
+                               if ((q = colptr[j]) == NULL)
+                                       break;
+
+                               colptr[j] = q->snext;
+                               w = q->sattr;
+                               ww = q->sattre;
+                               // Pick a tag:
+                               // c    common
+                               // x    external reference
+                               // g    global (export)
+                               // space        nothing special
+                               c1 = SPACE;
+                               c = SPACE;
+
+                               if (w & COMMON)
+                                       c = 'c';
+                               else if ((w & (DEFINED|GLOBAL)) == GLOBAL)
+                                       c = 'x';
+                               else if (w & GLOBAL)
+                                       c = 'g';
+
+                               c1 = tdb_text[w & TDB];
+
+                               if (c == 'x')
+                                       strcpy(ln2, "external");
+                               else
+                               {
+                                       sprintf(ln2, "%08ux", q->svalue);
+                                       uc_string(ln2);
+                               }
+
+                               sprintf(ln1, "  %16s %s %c%c%c", q->sname, ln2, (ww & EQUATEDREG) ? 'e' : SPACE, c1, c);
+                               strcat(ln, ln1);
+                       }
+
+                       ship_ln(ln);
+               }
+
+               eject();
+       }
+
+       return 0;
 }
index d94dd35ec65ea9a5dc075e3e33a34e66aae591d0..9da084326d85694cbc4de3396288cddb738dc6a8 100644 (file)
--- a/symbol.h
+++ b/symbol.h
@@ -12,7 +12,7 @@
 #include "rmac.h"
 
 // Macros
-#define NBUCKETS        256                                 // Number of hash buckets (power of 2)
+#define NBUCKETS        256                    // Number of hash buckets (power of 2)
 
 // Globals, externals etc
 extern int curenv;
diff --git a/token.c b/token.c
index 1bef56ed816c51e5cda0fab2e16123e9aad94202..4f812c234725e81ec527dda3af041d653a750471 100644 (file)
--- a/token.c
+++ b/token.c
@@ -209,16 +209,16 @@ int mexpand(char * src, char * dest, int destsiz)
 {
        char * s;
        char * d = NULL;
-       char * dst;                                               // Next dest slot
-       char * edst;                                              // End+1 of dest buffer
+       char * dst;                                                     // Next dest slot
+       char * edst;                                            // End+1 of dest buffer
        int i;
-       int questmark;                                           // \? for testing argument existence
+       int questmark;                                          // \? for testing argument existence
        TOKEN * tk;
-       char mname[128];                                         // Assume max size of a formal arg name
+       char mname[128];                                        // Assume max size of a formal arg name
        int macnum;
        SYM * arg;
        IMACRO * imacro;
-       char numbuf[20];                                         // Buffer for text of CONSTs
+       char numbuf[20];                                        // Buffer for text of CONSTs
 
        imacro = cur_inobj->inobj.imacro;
        macnum = (int)(imacro->im_macro->sattr);
diff --git a/token.h b/token.h
index 938e4b27ebf9e9aaee3aa68361b96cacd0b6fe92..be3c1e392ca4890490b46d873261588e0b3e05a9 100644 (file)
--- a/token.h
+++ b/token.h
@@ -13,9 +13,9 @@
 //#include "risca.h"
 
 // Include Files and Macros
-#define SRC_IFILE       0                                   // Input source is IFILE
-#define SRC_IMACRO      1                                   // Input source is IMACRO
-#define SRC_IREPT       2                                   // Input source is IREPT
+#define SRC_IFILE       0                                      // Input source is IFILE
+#define SRC_IMACRO      1                                      // Input source is IMACRO
+#define SRC_IREPT       2                                      // Input source is IREPT
 
 // Macros
 #define INOBJ           struct _inobj
 #define IFENT           struct _ifent
 
 // Tunable definitions
-#define LNSIZ           256                                 // Maximum size of a line of text
-#define TOKBUFSIZE      400                                 // Size of token-line buffer
-#define QUANTUM         4096L                               // #bytes to eat at a time from a file
-#define LNBUFSIZ        (QUANTUM*2)                         // Size of file's buffer
-#define KWSIZE          7                                   // Maximum size of keyword in kwtab.h
+#define LNSIZ           256                                    // Maximum size of a line of text
+#define TOKBUFSIZE      400                                    // Size of token-line buffer
+#define QUANTUM         4096L                          // #bytes to eat at a time from a file
+#define LNBUFSIZ        (QUANTUM*2)                    // Size of file's buffer
+#define KWSIZE          7                                      // Maximum size of keyword in kwtab.h
 
 // (Normally) non-printable tokens
-#define COLON           ':'                                 // : (grumble: GNUmacs hates ':')
-#define CONST           'a'                                 // CONST <value>
-#define ACONST          'A'                                 // ACONST <value> <attrib>
-#define STRING          'b'                                 // STRING <address>
-#define SYMBOL          'c'                                 // SYMBOL <address>
-#define EOL             'e'                                 // End of line
-#define TKEOF           'f'                                 // End of file (or macro)
-#define DEQUALS         'g'                                 // ==
-#define SET             149                                 // Set
-#define REG             'R'                                 // Reg
-#define DCOLON          'h'                                 // ::
-#define GE              'i'                                 // >= 
-#define LE              'j'                                 // <= 
-#define NE              'k'                                 // <> or != 
-#define SHR             'l'                                 // >> 
-#define SHL             'm'                                 // << 
-#define UNMINUS         'n'                                 // Unary '-' 
-#define DOTB            'B'                                 // .b or .B or .s or .S 
-#define DOTW            'W'                                 // .w or .W 
-#define DOTL            'L'                                 // .l or .L 
-#define DOTI            'I'                                 // .l or .L 
-#define ENDEXPR         'E'                                 // End of expression 
+#define COLON           ':'                                    // : (grumble: GNUmacs hates ':')
+#define CONST           'a'                                    // CONST <value>
+#define ACONST          'A'                                    // ACONST <value> <attrib>
+#define STRING          'b'                                    // STRING <address>
+#define SYMBOL          'c'                                    // SYMBOL <address>
+#define EOL             'e'                                    // End of line
+#define TKEOF           'f'                                    // End of file (or macro)
+#define DEQUALS         'g'                                    // ==
+#define SET             149                                    // Set
+#define REG             'R'                                    // Reg
+#define DCOLON          'h'                                    // ::
+#define GE              'i'                                    // >= 
+#define LE              'j'                                    // <= 
+#define NE              'k'                                    // <> or != 
+#define SHR             'l'                                    // >> 
+#define SHL             'm'                                    // << 
+#define UNMINUS         'n'                                    // Unary '-' 
+#define DOTB            'B'                                    // .b or .B or .s or .S 
+#define DOTW            'W'                                    // .w or .W 
+#define DOTL            'L'                                    // .l or .L 
+#define DOTI            'I'                                    // .l or .L 
+#define ENDEXPR         'E'                                    // End of expression 
 
 // ^^ operators
-#define CR_DEFINED      'p'                                 // ^^defined - is symbol defined?
-#define CR_REFERENCED   'q'                                 // ^^referenced - was symbol referenced?
-#define CR_STREQ        'v'                                 // ^^streq - compare two strings
-#define CR_MACDEF       'w'                                 // ^^macdef - is macro defined?
-#define CR_TIME         'x'                                 // ^^time - DOS format time
-#define CR_DATE         'y'                                 // ^^date - DOS format date
+#define CR_DEFINED      'p'                                    // ^^defined - is symbol defined?
+#define CR_REFERENCED   'q'                                    // ^^referenced - was symbol referenced?
+#define CR_STREQ        'v'                                    // ^^streq - compare two strings
+#define CR_MACDEF       'w'                                    // ^^macdef - is macro defined?
+#define CR_TIME         'x'                                    // ^^time - DOS format time
+#define CR_DATE         'y'                                    // ^^date - DOS format date
 
 // Character Attributes
-#define ILLEG           0                                   // Illegal character (unused)
-#define DIGIT           1                                   // 0-9
-#define HDIGIT          2                                   // A-F, a-f
-#define STSYM           4                                   // A-Z, a-z, _~.
-#define CTSYM           8                                   // A-Z, a-z, 0-9, _~$?
-#define SELF            16                                  // Single-character tokens: ( ) [ ] etc
-#define WHITE           32                                  // Whitespace (space, tab, etc.)
-#define MULTX           64                                  // Multiple-character tokens
-#define DOT             128                                 // [bwlsBWSL] for what follows a `.'
+#define ILLEG           0                                      // Illegal character (unused)
+#define DIGIT           1                                      // 0-9
+#define HDIGIT          2                                      // A-F, a-f
+#define STSYM           4                                      // A-Z, a-z, _~.
+#define CTSYM           8                                      // A-Z, a-z, 0-9, _~$?
+#define SELF            16                                     // Single-character tokens: ( ) [ ] etc
+#define WHITE           32                                     // Whitespace (space, tab, etc.)
+#define MULTX           64                                     // Multiple-character tokens
+#define DOT             128                                    // [bwlsBWSL] for what follows a `.'
 
 // Conditional assembly structures
 IFENT {
-   IFENT *if_prev;                                          // Ptr prev .if state block (or NULL)
-   WORD if_state;                                           // 0:enabled, 1:disabled
+       IFENT * if_prev;                // Ptr prev .if state block (or NULL)
+       WORD if_state;                  // 0:enabled, 1:disabled
 };
 
 // Pointer to IFILE or IMACRO
 IUNION {
-   IFILE *ifile;
-   IMACRO *imacro;
-   IREPT *irept;
+       IFILE * ifile;
+       IMACRO * imacro;
+       IREPT * irept;
 };
 
 // Ptr to IFILEs, IMACROs, and so on; back-ptr to previous input objects
 INOBJ {
-   WORD in_type;                                            // 0=IFILE, 1=IMACRO ...
-   IFENT *in_ifent;                                                // Pointer to .if context on entry
-   INOBJ *in_link;                                                 // Pointer to previous INOBJ
-   TOKEN *in_otok;                                                 // Old `tok' value
-   TOKEN *in_etok;                                                 // Old `etok' value
-   IUNION inobj;                                                           // IFILE or IMACRO ...
+       WORD in_type;                   // 0=IFILE, 1=IMACRO ...
+       IFENT * in_ifent;               // Pointer to .if context on entry
+       INOBJ * in_link;                // Pointer to previous INOBJ
+       TOKEN * in_otok;                // Old `tok' value
+       TOKEN * in_etok;                // Old `etok' value
+       IUNION inobj;                   // IFILE or IMACRO ...
 };
 
 // Information about a file
 IFILE {
-   IFILE *if_link;                                          // Pointer to ancient IFILEs
-   char *ifoldfname;                                        // Old file's name
-   int ifoldlineno;                                         // Old line number
-   int ifind;                                               // Position in file buffer
-   int ifcnt;                                               // #chars left in file buffer 
-   int ifhandle;                                            // File's descriptor
-   WORD ifno;                                               // File number
-   char ifbuf[LNBUFSIZ];                                    // Line buffer
+       IFILE * if_link;                // Pointer to ancient IFILEs
+       char * ifoldfname;              // Old file's name
+       int ifoldlineno;                // Old line number
+       int ifind;                              // Position in file buffer
+       int ifcnt;                              // #chars left in file buffer 
+       int ifhandle;                   // File's descriptor
+       WORD ifno;                              // File number
+       char ifbuf[LNBUFSIZ];   // Line buffer
 };
 
 // Information about a macro invocation
 IMACRO {
-   IMACRO *im_link;                                         // Pointer to ancient IMACROs
-   LONG *im_nextln;                                         // Next line to include
-   WORD im_nargs;                                           // # of arguments supplied on invocation
-   WORD im_siz;                                             // Size suffix supplied on invocation
-   LONG im_olduniq;                                         // Old value of 'macuniq'
-   SYM *im_macro;                                           // Pointer to macro we're in
-   char im_lnbuf[LNSIZ];                                    // Line buffer
+       IMACRO * im_link;               // Pointer to ancient IMACROs
+       LONG * im_nextln;               // Next line to include
+       WORD im_nargs;                  // # of arguments supplied on invocation
+       WORD im_siz;                    // Size suffix supplied on invocation
+       LONG im_olduniq;                // Old value of 'macuniq'
+       SYM * im_macro;                 // Pointer to macro we're in
+       char im_lnbuf[LNSIZ];   // Line buffer
 };
 
 // Information about a .rept invocation
 IREPT {
-   LONG *ir_firstln;                                        // Pointer to first line
-   LONG *ir_nextln;                                         // Pointer to next line
-   VALUE ir_count;                                          // Repeat count (decrements)
+       LONG * ir_firstln;              // Pointer to first line
+       LONG * ir_nextln;               // Pointer to next line
+       VALUE ir_count;                 // Repeat count (decrements)
 };
 
 // Globals, externals etc
 extern int lnsave;
 extern int curlineno;
-extern char *curfname;
+extern char * curfname;
 extern WORD cfileno;
-extern TOKEN *tok;
+extern TOKEN * tok;
 extern char lnbuf[];
 extern char lntag;
 extern char tolowertab[];
-extern INOBJ *cur_inobj;
+extern INOBJ * cur_inobj;
 extern unsigned orgactive;
 extern unsigned orgaddr;
 extern LONG sloc;
@@ -151,6 +151,6 @@ int tokln(void);
 int fpop(void);
 //int d_goto(WORD);
 int d_goto(void);
-INOBJ *a_inobj(int);
+INOBJ * a_inobj(int);
 
 #endif // __TOKEN_H__