]> git.sur5r.net Git - cc65/commitdiff
Allow registers in sweet16 mode also to be specified as constant numbers
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 30 Jul 2009 13:05:41 +0000 (13:05 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 30 Jul 2009 13:05:41 +0000 (13:05 +0000)
instead of Rx. Suggestion and sample code by Gabriele Galeotti.

git-svn-id: svn://svn.cc65.org/cc65/trunk@3983 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/easw16.c

index 979eb29afa5aa521cb329faa0de85c033a7212aa..95a9587cf9bf727b6c0bf89a7d55236c2254c525 100644 (file)
 
 
 
+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;
@@ -64,15 +86,18 @@ void GetSweet16EA (EffAddr* A)
 
     } else if (Tok == TOK_AT) {
 
-       /* @reg */
+               /* @reg or @regnumber */
        A->AddrModeSet = AMSW16_IND;
        NextTok ();
-        if (Tok != TOK_REG) {
-            ErrorSkip ("Register expected");
-            A->Reg = 0;
-        } else {
+        if (Tok == TOK_REG) {
             A->Reg = (unsigned) 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) {
@@ -82,7 +107,7 @@ void GetSweet16EA (EffAddr* A)
 
         if (Tok == TOK_COMMA) {
 
-            /* Rx, Constant */
+            /* Rx, constant */
             NextTok ();
             A->Expr = Expression ();
 
@@ -96,10 +121,28 @@ 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 (Tok == TOK_COMMA) {
+                NextTok ();
+                A->Expr = Expression ();
+                A->AddrModeSet = AMSW16_IMM;
+            } else {
+                A->Expr = 0;
+                A->AddrModeSet |= AMSW16_REG;
+            }
+        }
+
     }
 }