]> git.sur5r.net Git - cc65/blobdiff - src/da65/handler.c
Revert "atari5200: fix COLOR defines' names"
[cc65] / src / da65 / handler.c
index 0806301fe8471ac74338469969b8ba46d12ece8c..f8a778b22bba32140566d7bf84ff6d5085f9c6d7 100644 (file)
@@ -36,6 +36,7 @@
 #include <stdarg.h>
 
 /* common */
+#include "xmalloc.h"
 #include "xsprintf.h"
 
 /* da65 */
@@ -50,6 +51,8 @@
 
 
 
+static unsigned short SubroutineParamSize[0x10000];
+
 /*****************************************************************************/
 /*                             Helper functions                              */
 /*****************************************************************************/
@@ -226,6 +229,13 @@ void OH_Immediate (const OpcDesc* D)
 
 
 
+void OH_ImmediateWord (const OpcDesc* D)
+{
+    OneLine (D, "#$%04X", GetCodeWord (PC+1));
+}
+
+
+
 void OH_Direct (const OpcDesc* D)
 {
     /* Get the operand */
@@ -348,6 +358,23 @@ void OH_RelativeLong (const OpcDesc* D attribute ((unused)))
 
 
 
+void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused)))
+{
+    /* Get the operand */
+    signed short Offs = GetCodeWord (PC+1);
+
+    /* Calculate the target address */
+    unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF;
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
+    /* Output the line */
+    OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
+}
+
+
+
 void OH_DirectIndirect (const OpcDesc* D)
 {
     /* Get the operand */
@@ -376,6 +403,20 @@ void OH_DirectIndirectY (const OpcDesc* D)
 
 
 
+void OH_DirectIndirectZ (const OpcDesc* D)
+{
+    /* Get the operand */
+    unsigned Addr = GetCodeByte (PC+1);
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
+    /* Output the line */
+    OneLine (D, "(%s),z", GetAddrArg (D->Flags, Addr));
+}
+
+
+
 void OH_DirectXIndirect (const OpcDesc* D)
 {
     /* Get the operand */
@@ -406,6 +447,8 @@ void OH_AbsoluteIndirect (const OpcDesc* D)
 
 void OH_BitBranch (const OpcDesc* D)
 {
+    char* BranchLabel;
+
     /* Get the operands */
     unsigned char TestAddr   = GetCodeByte (PC+1);
     signed char   BranchOffs = GetCodeByte (PC+2);
@@ -421,8 +464,16 @@ void OH_BitBranch (const OpcDesc* D)
     GenerateLabel (D->Flags, TestAddr);
     GenerateLabel (flLabel, BranchAddr);
 
+    /* Make a copy of an operand, so that
+    ** the other operand can't overwrite it.
+    ** [GetAddrArg() uses a statically-stored buffer.]
+    */
+    BranchLabel = xstrdup (GetAddrArg (flLabel, BranchAddr));
+
     /* Output the line */
-    OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), GetAddrArg (flLabel, BranchAddr));
+    OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), BranchLabel);
+
+    xfree (BranchLabel);
 }
 
 
@@ -499,7 +550,16 @@ void OH_DirectIndirectLongX (const OpcDesc* D attribute ((unused)))
 
 void OH_StackRelativeIndirectY (const OpcDesc* D attribute ((unused)))
 {
-    Error ("Not implemented");
+    /* Output the line */
+    OneLine (D, "($%02X,s),y", GetCodeByte (PC+1));
+}
+
+
+
+void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused)))
+{
+    /* Output the line */
+    OneLine (D, "($%02X,sp),y", GetCodeByte (PC+1));
 }
 
 
@@ -518,8 +578,10 @@ void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
 
 
 
-void OH_BlockMove (const OpcDesc* D attribute ((unused)))
+void OH_BlockMove (const OpcDesc* D)
 {
+    char* DstLabel;
+
     /* Get source operand */
     unsigned Src = GetCodeWord (PC+1);
     /* Get destination operand */
@@ -529,11 +591,19 @@ void OH_BlockMove (const OpcDesc* D attribute ((unused)))
     GenerateLabel (D->Flags, Src);
     GenerateLabel (D->Flags, Dst);
 
+    /* Make a copy of an operand, so that
+    ** the other operand can't overwrite it.
+    ** [GetAddrArg() uses a statically-stored buffer.]
+    */
+    DstLabel = xstrdup (GetAddrArg (D->Flags, Dst));
+
     /* Output the line */
-    OneLine (D, "%s%s,%s%s,#$%02X",
+    OneLine (D, "%s%s,%s%s,$%04X",
              GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src),
-             GetAbsOverride (D->Flags, Dst), GetAddrArg (D->Flags, Dst),
+             GetAbsOverride (D->Flags, Dst), DstLabel,
              GetCodeWord (PC+5));
+
+    xfree (DstLabel);
 }
 
 
@@ -662,3 +732,46 @@ void OH_JmpAbsoluteIndirect (const OpcDesc* D)
     }
     SeparatorLine ();
 }
+
+
+
+void OH_JmpAbsoluteXIndirect (const OpcDesc* D)
+{
+    OH_AbsoluteXIndirect (D);
+    if (NewlineAfterJMP) {
+        LineFeed ();
+    }
+    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;
+}