]> git.sur5r.net Git - cc65/commitdiff
Support for "virtual operands" of subroutines like this:
authorAIDA Shinra <shinra@j10n.org>
Sun, 10 Jun 2018 09:09:11 +0000 (18:09 +0900)
committerAIDA Shinra <shinra@j10n.org>
Sun, 10 Jun 2018 09:09:11 +0000 (18:09 +0900)
jsr SomeProc
.byte $00, $01 ; argument to SomeProc
; return here from SomeProc
bit $3F

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..c2d87ac928b5c30270cd987a028a00cad1407825 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>VOPERAND</tt></tag>
+  This optional attribute is followed by a numerical value. It tells the
+  assembler that subroutine calls to this label follow "virtual operands"
+  of the given bytes like this:
+
+<tscreen><verb>
+               JSR     LabelWith2BytesOfVoperand
+       .byte   $00, $10    ; virtual operands
+       ; return here
+       BIT     $0F
+</verb></tscreen>
+
 </descrip>
 
 
index 6249523630005ed7c6a252e1e57f128730240d8f..19b8946de6aadfa795d4a0ec2cc7abf22e562164 100644 (file)
@@ -51,6 +51,8 @@
 
 
 
+static unsigned short SubroutineVOperandSize[0x10000];
+
 /*****************************************************************************/
 /*                             Helper functions                              */
 /*****************************************************************************/
@@ -741,3 +743,31 @@ void OH_JmpAbsoluteXIndirect (const OpcDesc* D)
     }
     SeparatorLine ();
 }
+
+
+
+void OH_JsrAbsolute (const OpcDesc* D)
+{
+    unsigned VOperandSize = SubroutineVOperandSize[GetCodeWord(PC+1)];
+    OH_Absolute (D);
+    if (VOperandSize > 0) {
+        unsigned RemainingBytes;
+        PC += D->Size;
+        RemainingBytes = GetRemainingBytes();
+        if (RemainingBytes < VOperandSize) {
+            VOperandSize = RemainingBytes;
+        }
+        if (VOperandSize > 0) {
+            DataByteLine (VOperandSize); /* FIXME: follow BytesPerLine */
+            PC += VOperandSize;
+        }
+        PC -= D->Size;
+    }
+}
+
+
+
+void SetSubroutineVOperand (unsigned Addr, unsigned Size)
+{
+    SubroutineVOperandSize[Addr] = Size;
+}
index c0fa68e56a7874b4d1e639dbf4a298e9f42650cc..96b73f2c74b9a0eabc3cc812177bfaed6465a2bc 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 SetSubroutineVOperand (unsigned Addr, unsigned Size);
 
 
 /* End of handler.h */
index e8ce66cf7b52a91e602c4b8d1d8226f7e3066819..3bfa15f51bbde17a8fdd010516d422731d393aaf 100644 (file)
@@ -59,6 +59,7 @@
 #include "opctable.h"
 #include "scanner.h"
 #include "segment.h"
+#include "handler.h"
 
 
 
@@ -380,6 +381,7 @@ static void LabelSection (void)
         {   "ADDR",     INFOTOK_ADDR    },
         {   "NAME",     INFOTOK_NAME    },
         {   "SIZE",     INFOTOK_SIZE    },
+        {   "VOPERAND", INFOTOK_VOPERAND },
     };
 
     /* Locals - initialize to avoid gcc warnings */
@@ -387,6 +389,7 @@ static void LabelSection (void)
     char* Comment = 0;
     long Value    = -1;
     long Size     = -1;
+    long VOperand = -1;
 
     /* Skip the token */
     InfoNextTok ();
@@ -448,6 +451,17 @@ static void LabelSection (void)
                 InfoNextTok ();
                 break;
 
+            case INFOTOK_VOPERAND:
+                InfoNextTok ();
+                if (VOperand >= 0) {
+                    InfoError ("VOperand already given");
+                }
+                InfoAssureInt ();
+                InfoRangeCheck (1, 0x10000);
+                VOperand = InfoIVal;
+                InfoNextTok ();
+                break;
+
             default:
                 Internal ("Unexpected token: %u", InfoTok);
         }
@@ -484,6 +498,9 @@ static void LabelSection (void)
     } else {
         AddExtLabelRange ((unsigned) Value, Name, Size);
     }
+    if (VOperand >= 0) {
+        SetSubroutineVOperand ((unsigned) Value, (unsigned) VOperand);
+    }
 
     /* 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..14a3ef679c58fa4e3962bf138f56231c74df9734 100644 (file)
@@ -105,6 +105,7 @@ typedef enum token_t {
     INFOTOK_COMMENT,
     INFOTOK_ADDR,
     INFOTOK_SIZE,
+    INFOTOK_VOPERAND,
 
     /* ASMINC section */
     INFOTOK_FILE,