Added new .cstruct construct. Thanks to GroovyBee for the suggestion!
authorShamus Hammons <jlhamm@acm.org>
Wed, 13 Feb 2013 18:51:43 +0000 (12:51 -0600)
committerShamus Hammons <jlhamm@acm.org>
Wed, 13 Feb 2013 18:51:43 +0000 (12:51 -0600)
direct.c
direct.h
mntab

index b1c368a4d2c8bd5b91ae3303fa60d97d3bc7c487..3471742ea179a28ca817d232b46501e5887ac41b 100644 (file)
--- a/direct.c
+++ b/direct.c
@@ -79,6 +79,7 @@ int (*dirtab[])() = {
    d_equrundef,                        // 50 .equrundef/.regundef
    d_ccundef,                  // 51 .ccundef
    d_print,                            // 52 .print
+   d_cstruct,                  // 53 .cstruct
 };
 
 
@@ -1278,7 +1279,8 @@ int d_dsp(void)
 //
 int d_cargs(void)
 {
-       VALUE eval;
+       VALUE eval = 4;         // Default to 4 if no offset specified (to account for
+                                               // return address)
        WORD rlist;
        SYM * symbol;
        char * p;
@@ -1299,9 +1301,6 @@ int d_cargs(void)
                if (*tok == ',')
                        tok++;
        }
-       else 
-               // Default to 4 if not specified (because PC is on stack according to GroovyBee)
-               eval = 4;
 
        for(;;)
        {
@@ -1391,6 +1390,139 @@ int d_cargs(void)
 }
 
 
+//
+// .cstruct [#offset], symbol[.size], ...
+// 
+// Lists of registers may also be mentioned; they just take up space. Good for
+// "documentation" purposes:
+// 
+// .cstruct a6, .arg1, .arg2, .arg3...
+// 
+// Symbols thus created are ABS and EQUATED. Note that this is for
+// compatibility with VBCC and the Remover's library. Thanks to GroovyBee for
+// the suggestion.
+//
+int d_cstruct(void)
+{
+       VALUE eval = 0;         // Default, if no offset specified, is zero
+       WORD rlist;
+       SYM * symbol;
+       char * symbolName;
+       int env;
+       int i;
+
+       if (rgpu || rdsp)
+               return error("directive forbidden in gpu/dsp mode");
+
+       if (*tok == '#')
+       {
+               tok++;
+
+               if (abs_expr(&eval) != OK)
+                       return 0;
+
+               // Eat the comma, if it's there
+               if (*tok == ',')
+                       tok++;
+       }
+
+       for(;;)
+       {
+               if (*tok == SYMBOL)
+               {
+                       symbolName = string[tok[1]];
+
+                       // Set env to either local (dot prefixed) or global scope
+                       env = (symbolName[0] == '.' ? curenv : 0);
+                       symbol = lookup(symbolName, LABEL, env);
+
+                       // If the symbol wasn't found, then define it. Otherwise, throw an
+                       // error.
+                       if (symbol == NULL)
+                       {
+                               symbol = NewSymbol(symbolName, LABEL, env);
+                               symbol->sattr = 0;
+                       }
+                       else if (symbol->sattr & DEFINED)
+                               return errors("multiply-defined label '%s'", symbolName);
+
+                       // Put symbol in "order of definition" list
+                       if (!(symbol->sattr & SDECLLIST))
+                               sym_decl(symbol);
+
+                       tok += 2;
+
+                       // Adjust label start address if it's a word or a long, as a byte
+                       // label might have left us on an odd address.
+                       switch ((int)*tok)
+                       {
+                       case DOTW:
+                       case DOTL:
+                               eval += eval & 0x01;
+                       }
+
+                       symbol->sattr |= (ABS | DEFINED | EQUATED);
+                       symbol->svalue = eval;
+
+                       // Check for dot suffixes and adjust space accordingly (longs and
+                       // words on an odd boundary get bumped to the next word aligned
+                       // address). If no suffix, then throw an error.
+                       switch ((int)*tok)
+                       {
+                       case DOTL:
+                               eval += 4;
+                               break;
+                       case DOTW:
+                               eval += 2;
+                               break;
+                       case DOTB:
+                               eval += 1;
+                               break;
+                       default:
+                               return error("Symbol missing dot suffix in .cstruct construct");
+                       }
+
+                       tok++;
+               }
+               else if (*tok >= KW_D0 && *tok <= KW_A7)
+               {
+                       if (reglist(&rlist) < 0)
+                               return 0;
+
+                       for(i=0; i<16; i++, rlist>>=1)
+                       {
+                               if (rlist & 1)
+                                       eval += 4;
+                       }
+               }
+               else
+               {
+                       switch ((int)*tok)
+                       {
+                       case KW_USP:
+                       case KW_SSP:
+                       case KW_PC:
+                               eval += 2;
+                               // FALLTHROUGH
+                       case KW_SR:
+                       case KW_CCR:
+                               eval += 2;
+                               tok++;
+                               break;
+                       case EOL:
+                               return 0;
+                       default:
+                               return error(".cstruct syntax");
+                       }
+               }
+
+               // Eat commas in between each argument, if they exist
+               if (*tok == ',')
+                       tok++;
+       }
+}
+
+
 //
 // Undefine a macro - .undefmac macname [, macname...]
 //
index 6da4c3e2c77e69cb3419f49f96e528b3b6e26b4c..adbf7868121e0ba6a1bcb7363730066c0dfae70a 100644 (file)
--- a/direct.h
+++ b/direct.h
@@ -68,5 +68,6 @@ int d_nojpad(void);
 int d_fail(void);
 int symlist(int(*)());
 int abs_expr(VALUE *);
+int d_cstruct(void);
 
 #endif // __DIRECT_H__
diff --git a/mntab b/mntab
index 812c882ab1e7ddd5e073d23d8d9535976f47d686..fbceb879201c9881f85be7b74cca4c6d196b6590 100644 (file)
--- a/mntab
+++ b/mntab
@@ -87,6 +87,8 @@ regundef 50
 ccundef  51
 .print 52
 print  52
+.cstruct       53
+cstruct        53
 .if    500
 if     500
 .else  501