]> git.sur5r.net Git - cc65/commitdiff
Merge pull request #681 from shinra-jp/voperand
authorOliver Schmidt <ol.sc@web.de>
Wed, 13 Jun 2018 12:41:24 +0000 (14:41 +0200)
committerGitHub <noreply@github.com>
Wed, 13 Jun 2018 12:41:24 +0000 (14:41 +0200)
Support for "inline parameters" of subroutines

doc/da65.sgml
src/da65/handler.c
src/da65/handler.h
src/da65/infofile.c
src/da65/opc6502.c
src/da65/opc65816.c
src/da65/opc65c02.c
src/da65/opc65sc02.c
src/da65/scanner.h

index a8e32e1c851aab07b74061d70a0b875a9b60dbce..54a3416157d4aa035756e939756c4c2312142687 100644 (file)
@@ -542,6 +542,18 @@ code. The following attributes are recognized:
   range, where <tt/label/ is the label name given with the <tt/NAME/
   attribute, and <tt/offs/ is the offset within the data.
 
+  <tag><tt>PARAMSIZE</tt></tag>
+  This optional attribute is followed by a numerical value. It tells the
+  assembler that subroutine calls to this label are followed by
+  "inline parameters" with the given number of bytes, like this:
+
+<tscreen><verb>
+        JSR     LabelWithParamSize2
+        .byte   $00, $10
+        (return here)
+        code...
+</verb></tscreen>
+
 </descrip>
 
 
index 6249523630005ed7c6a252e1e57f128730240d8f..f8a778b22bba32140566d7bf84ff6d5085f9c6d7 100644 (file)
@@ -51,6 +51,8 @@
 
 
 
+static unsigned short SubroutineParamSize[0x10000];
+
 /*****************************************************************************/
 /*                             Helper functions                              */
 /*****************************************************************************/
@@ -741,3 +743,35 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D)
     }
     SeparatorLine ();
 }
+
+
+
+void OH_JsrAbsolute (const OpcDesc* D)
+{
+    unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)];
+    OH_Absolute (D);
+    if (ParamSize > 0) {
+        unsigned RemainingBytes;
+        unsigned BytesLeft;
+        PC += D->Size;
+        RemainingBytes = GetRemainingBytes ();
+        if (RemainingBytes < ParamSize) {
+            ParamSize = RemainingBytes;
+        }
+        BytesLeft = ParamSize;
+        while (BytesLeft > 0) {
+            unsigned Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft;
+            DataByteLine (Chunk);
+            BytesLeft -= Chunk;
+            PC        += Chunk;
+        }
+        PC -= D->Size;
+    }
+}
+
+
+
+void SetSubroutineParamSize (unsigned Addr, unsigned Size)
+{
+    SubroutineParamSize[Addr] = Size;
+}
index c0fa68e56a7874b4d1e639dbf4a298e9f42650cc..eaa66e7fd896410dd9e602a417670c6268f145e6 100644 (file)
@@ -104,7 +104,9 @@ void OH_Rts (const OpcDesc*);
 void OH_JmpAbsolute (const OpcDesc*);
 void OH_JmpAbsoluteIndirect (const OpcDesc* D);
 void OH_JmpAbsoluteXIndirect (const OpcDesc* D);
+void OH_JsrAbsolute (const OpcDesc*);
 
+void SetSubroutineParamSize (unsigned Addr, unsigned Size);
 
 
 /* End of handler.h */
index e8ce66cf7b52a91e602c4b8d1d8226f7e3066819..6db82cb362c1f8ac86ac02497aded79370896b2a 100644 (file)
@@ -59,6 +59,7 @@
 #include "opctable.h"
 #include "scanner.h"
 #include "segment.h"
+#include "handler.h"
 
 
 
@@ -376,17 +377,19 @@ static void LabelSection (void)
 /* Parse a label section */
 {
     static const IdentTok LabelDefs[] = {
-        {   "COMMENT",  INFOTOK_COMMENT },
-        {   "ADDR",     INFOTOK_ADDR    },
-        {   "NAME",     INFOTOK_NAME    },
-        {   "SIZE",     INFOTOK_SIZE    },
+        {   "COMMENT",      INFOTOK_COMMENT     },
+        {   "ADDR",         INFOTOK_ADDR        },
+        {   "NAME",         INFOTOK_NAME        },
+        {   "SIZE",         INFOTOK_SIZE        },
+        {   "PARAMSIZE",    INFOTOK_PARAMSIZE   },
     };
 
     /* Locals - initialize to avoid gcc warnings */
-    char* Name    = 0;
-    char* Comment = 0;
-    long Value    = -1;
-    long Size     = -1;
+    char* Name      = 0;
+    char* Comment   = 0;
+    long Value      = -1;
+    long Size       = -1;
+    long ParamSize  = -1;
 
     /* Skip the token */
     InfoNextTok ();
@@ -448,6 +451,17 @@ static void LabelSection (void)
                 InfoNextTok ();
                 break;
 
+            case INFOTOK_PARAMSIZE:
+                InfoNextTok ();
+                if (ParamSize >= 0) {
+                    InfoError ("ParamSize already given");
+                }
+                InfoAssureInt ();
+                InfoRangeCheck (1, 0x10000);
+                ParamSize = InfoIVal;
+                InfoNextTok ();
+                break;
+
             default:
                 Internal ("Unexpected token: %u", InfoTok);
         }
@@ -484,6 +498,9 @@ static void LabelSection (void)
     } else {
         AddExtLabelRange ((unsigned) Value, Name, Size);
     }
+    if (ParamSize >= 0) {
+        SetSubroutineParamSize ((unsigned) Value, (unsigned) ParamSize);
+    }
 
     /* Define the comment */
     if (Comment) {
index 27f734d564e930a49b045ea12c330d17b0af2b33..8fc6f6aea011ce295a92ec3ea73233252c332cc9 100644 (file)
@@ -79,7 +79,7 @@ const OpcDesc OpcTable_6502[256] = {
     {   "ora",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1d */
     {   "asl",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1e */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $1f */
-    {   "jsr",  3,  flLabel,                  OH_Absolute              }, /* $20 */
+    {   "jsr",  3,  flLabel,                  OH_JsrAbsolute           }, /* $20 */
     {   "and",  2,  flUseLabel,               OH_DirectXIndirect       }, /* $21 */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $22 */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $23 */
index 2cd2aaee85591f9eb8718935e2915f4334a11330..b7775d2e26fcdc7ae693be6fb4792244a784b0da 100644 (file)
@@ -79,7 +79,7 @@ const OpcDesc OpcTable_65816[256] = {
     {   "ora",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1d */
     {   "asl",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1e */
     {   "ora",  4,  flUseLabel,               OH_AbsoluteLongX         }, /* $1f */
-    {   "jsr",  3,  flLabel,                  OH_Absolute              }, /* $20 */
+    {   "jsr",  3,  flLabel,                  OH_JsrAbsolute           }, /* $20 */
     {   "and",  2,  flUseLabel,               OH_DirectXIndirect       }, /* $21 */
     {   "jsl",  3,  flLabel,                  OH_AbsoluteLong          }, /* $22 */
     {   "and",  2,  flNone,                   OH_StackRelative         }, /* $23 */
index 8133bccae1ab0f60c261cf33ba23f783eff9472d..b69558f2ad802984f33f79262d751424d4cf51b1 100644 (file)
@@ -79,7 +79,7 @@ const OpcDesc OpcTable_65C02[256] = {
     {   "ora",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1d */
     {   "asl",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1e */
     {   "bbr1", 3,  flUseLabel,               OH_BitBranch             }, /* $1f */
-    {   "jsr",  3,  flLabel,                  OH_Absolute              }, /* $20 */
+    {   "jsr",  3,  flLabel,                  OH_JsrAbsolute           }, /* $20 */
     {   "and",  2,  flUseLabel,               OH_DirectXIndirect       }, /* $21 */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $22 */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $23 */
index 90549d00f5434a9dcc284bb9ecdc9ba1c2f1d8be..82e10bd96db0f0f40c5fb873bd3b63510e341cb5 100644 (file)
@@ -79,7 +79,7 @@ const OpcDesc OpcTable_65SC02[256] = {
     {   "ora",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1d */
     {   "asl",  3,  flUseLabel|flAbsOverride, OH_AbsoluteX             }, /* $1e */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $1f */
-    {   "jsr",  3,  flLabel,                  OH_Absolute              }, /* $20 */
+    {   "jsr",  3,  flLabel,                  OH_JsrAbsolute           }, /* $20 */
     {   "and",  2,  flUseLabel,               OH_DirectXIndirect       }, /* $21 */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $22 */
     {   "",     1,  flIllegal,                OH_Illegal,              }, /* $23 */
index f7f090fad4ab56426c6307a096f4f39bcaa5b860..d4e38177b3e77a17131b10260211cf02b536292c 100644 (file)
@@ -105,6 +105,7 @@ typedef enum token_t {
     INFOTOK_COMMENT,
     INFOTOK_ADDR,
     INFOTOK_SIZE,
+    INFOTOK_PARAMSIZE,
 
     /* ASMINC section */
     INFOTOK_FILE,