]> git.sur5r.net Git - cc65/blobdiff - src/ca65/easw16.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / ca65 / easw16.c
index 979eb29afa5aa521cb329faa0de85c033a7212aa..6b3fe4f4c73f93774f6b553fe34a7b0a173fc827 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                easw16.c                                  */
+/*                                 easw16.c                                  */
 /*                                                                           */
 /*       SWEET16 effective address parsing for the ca65 macroassembler       */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2004      Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2004-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
+static long RegNum ()
+/* Try to read a register number specified not as a register (Rx) but as a
+ * numeric value between 0 and 15. Return the register number or -1 on
+ * failure.
+ */
+{
+    long Val;
+    ExprNode* Expr = Expression ();
+    if (!IsConstExpr (Expr, &Val) || Val < 0 || Val > 15) {
+        /* Invalid register */
+        Val = -1L;
+    }
+
+    /* Free the expression and return the register number */
+    FreeExpr (Expr);
+    return Val;
+}
+
+
+
 void GetSweet16EA (EffAddr* A)
 /* Parse an effective address, return the result in A */
 {
+    long Reg;
+
     /* Clear the output struct */
     A->AddrModeSet = 0;
     A->Expr = 0;
     A->Reg  = 0;
 
     /* Parse the effective address */
-    if (TokIsSep (Tok)) {
+    if (TokIsSep (CurTok.Tok)) {
 
-               A->AddrModeSet = AMSW16_IMP;
+        A->AddrModeSet = AMSW16_IMP;
 
-    } else if (Tok == TOK_AT) {
+    } else if (CurTok.Tok == TOK_AT) {
 
-       /* @reg */
-       A->AddrModeSet = AMSW16_IND;
-       NextTok ();
-        if (Tok != TOK_REG) {
-            ErrorSkip ("Register expected");
-            A->Reg = 0;
-        } else {
-            A->Reg = (unsigned) IVal;
+        /* @reg or @regnumber */
+        A->AddrModeSet = AMSW16_IND;
+        NextTok ();
+        if (CurTok.Tok == TOK_REG) {
+            A->Reg = (unsigned) CurTok.IVal;
             NextTok ();
+        } else if ((Reg = RegNum ()) >= 0) {
+            /* Register number */
+            A->Reg = (unsigned) Reg;
+        } else {
+            ErrorSkip ("Register or register number expected");
+            A->Reg = 0;
         }
 
-    } else if (Tok == TOK_REG) {
+    } else if (CurTok.Tok == TOK_REG) {
 
-        A->Reg = (unsigned) IVal;
+        A->Reg = (unsigned) CurTok.IVal;
         NextTok ();
 
-        if (Tok == TOK_COMMA) {
+        if (CurTok.Tok == TOK_COMMA) {
 
-            /* Rx, Constant */
+            /* Rx, constant */
             NextTok ();
             A->Expr = Expression ();
 
@@ -96,12 +121,30 @@ void GetSweet16EA (EffAddr* A)
 
     } else {
 
-        /* OPC  ea */
+        /* OPC ea  or: OPC regnum, constant */
         A->Expr = Expression ();
         A->AddrModeSet = AMSW16_BRA;
 
+        /* If the value is a constant between 0 and 15, it may also be a
+         * register number.
+         */
+        if (IsConstExpr (A->Expr, &Reg) && Reg >= 0 && Reg <= 15) {
+            FreeExpr (A->Expr);
+            A->Reg = (unsigned) Reg;
+
+            /* If a comma follows, it is: OPC Rx, constant */
+            if (CurTok.Tok == TOK_COMMA) {
+                NextTok ();
+                A->Expr = Expression ();
+                A->AddrModeSet = AMSW16_IMM;
+            } else {
+                A->Expr = 0;
+                A->AddrModeSet |= AMSW16_REG;
+            }
+        }
+
     }
 }
 
 
-
+