]> git.sur5r.net Git - cc65/blobdiff - src/da65/handler.c
Fixed some bugs in da65's HuC6280 section.
[cc65] / src / da65 / handler.c
index f7412ff7780e0de56412bc2f858c16bee778f8b9..c034aed1406364a9810fe841c3c2e06cb7280785 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                handler.c                                 */
+/*                                 handler.c                                 */
 /*                                                                           */
-/*              Opcode handler functions for the disassembler               */
+/*               Opcode handler functions for the disassembler               */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2004 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -36,6 +36,7 @@
 #include <stdarg.h>
 
 /* common */
+#include "xmalloc.h"
 #include "xsprintf.h"
 
 /* da65 */
@@ -51,7 +52,7 @@
 
 
 /*****************************************************************************/
-/*                            Helper functions                              */
+/*                             Helper functions                              */
 /*****************************************************************************/
 
 
@@ -80,7 +81,7 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...)
     xvsprintf (Buf, sizeof (Buf), Arg, ap);
     va_end (ap);
     Indent (ACol);
-    Output (Buf);
+    Output ("%s", Buf);
 
     /* Add the code stuff as comment */
     LineComment (PC, D->Size);
@@ -93,8 +94,8 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...)
 
 static const char* GetAbsOverride (unsigned Flags, unsigned Addr)
 /* If the instruction requires an abs override modifier, return the necessary
- * string, otherwise return the empty string.
- */
+** string, otherwise return the empty string.
+*/
 {
     if ((Flags & flAbsOverride) != 0 && Addr < 0x100) {
         return "a:";
@@ -110,18 +111,18 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr)
 {
     const char* Label = 0;
     if (Flags & flUseLabel) {
-               Label = GetLabel (Addr, PC);
+        Label = GetLabel (Addr, PC);
     }
     if (Label) {
-               return Label;
+        return Label;
     } else {
-               static char Buf [32];
-               if (Addr < 0x100) {
-                   xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
-               } else {
-                   xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
-               }
-               return Buf;
+        static char Buf [32];
+        if (Addr < 0x100) {
+            xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
+        } else {
+            xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
+        }
+        return Buf;
     }
 }
 
@@ -132,66 +133,66 @@ static void GenerateLabel (unsigned Flags, unsigned Addr)
 {
     /* Generate labels in pass #1, and only if we don't have a label already */
     if (Pass == 1 && !HaveLabel (Addr) &&
-       /* Check if we must create a label */
-               ((Flags & flGenLabel) != 0 ||
-                ((Flags & flUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd))) {
-
-       /* As a special case, handle ranges with tables or similar. Within
-        * such a range with a granularity > 1, do only generate dependent
-        * labels for all addresses but the first one. Be sure to generate
-        * a label for the start of the range, however.
-        */
-       attr_t Style         = GetStyleAttr (Addr);
-       unsigned Granularity = GetGranularity (Style);
-
-       if (Granularity == 1) {
-           /* Just add the label */
-           AddIntLabel (Addr);
-       } else {
+        /* Check if we must create a label */
+        ((Flags & flGenLabel) != 0 ||
+         ((Flags & flUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd))) {
+
+        /* As a special case, handle ranges with tables or similar. Within
+        ** such a range with a granularity > 1, do only generate dependent
+        ** labels for all addresses but the first one. Be sure to generate
+        ** a label for the start of the range, however.
+        */
+        attr_t Style         = GetStyleAttr (Addr);
+        unsigned Granularity = GetGranularity (Style);
+
+        if (Granularity == 1) {
+            /* Just add the label */
+            AddIntLabel (Addr);
+        } else {
 
             /* THIS CODE IS A MESS AND WILL FAIL ON SEVERAL CONDITIONS! ### */
 
 
-           /* Search for the start of the range or the last non dependent
-            * label in the range.
-            */
-           unsigned Offs;
-           attr_t LabelAttr;
-           unsigned LabelAddr = Addr;
-           while (LabelAddr > CodeStart) {
-
-               if (Style != GetStyleAttr (LabelAddr-1)) {
-                   /* End of range reached */
-                   break;
-               }
-               --LabelAddr;
-               LabelAttr = GetLabelAttr (LabelAddr);
-               if ((LabelAttr & (atIntLabel|atExtLabel)) != 0) {
-                   /* The address has an internal or external label */
-                   break;
-               }
-           }
-
-           /* If the proposed label address doesn't have a label, define one */
-           if ((GetLabelAttr (LabelAddr) & (atIntLabel|atExtLabel)) == 0) {
-               AddIntLabel (LabelAddr);
-           }
-
-           /* Create the label */
-           Offs = Addr - LabelAddr;
-           if (Offs == 0) {
-               AddIntLabel (Addr);
-           } else {
-               AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs);
-           }
-       }
+            /* Search for the start of the range or the last non dependent
+            ** label in the range.
+            */
+            unsigned Offs;
+            attr_t LabelAttr;
+            unsigned LabelAddr = Addr;
+            while (LabelAddr > CodeStart) {
+
+                if (Style != GetStyleAttr (LabelAddr-1)) {
+                    /* End of range reached */
+                    break;
+                }
+                --LabelAddr;
+                LabelAttr = GetLabelAttr (LabelAddr);
+                if ((LabelAttr & (atIntLabel|atExtLabel)) != 0) {
+                    /* The address has an internal or external label */
+                    break;
+                }
+            }
+
+            /* If the proposed label address doesn't have a label, define one */
+            if ((GetLabelAttr (LabelAddr) & (atIntLabel|atExtLabel)) == 0) {
+                AddIntLabel (LabelAddr);
+            }
+
+            /* Create the label */
+            Offs = Addr - LabelAddr;
+            if (Offs == 0) {
+                AddIntLabel (Addr);
+            } else {
+                AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs);
+            }
+        }
     }
 }
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -219,7 +220,7 @@ void OH_Implicit (const OpcDesc* D)
 
 
 
-void OH_Immidiate (const OpcDesc* D)
+void OH_Immediate (const OpcDesc* D)
 {
     OneLine (D, "#$%02X", GetCodeByte (PC+1));
 }
@@ -406,6 +407,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);
@@ -414,15 +417,79 @@ void OH_BitBranch (const OpcDesc* D)
     unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
 
     /* Generate labels in pass 1. The bit branch codes are special in that
-     * they don't really match the remainder of the 6502 instruction set (they
-     * are a Rockwell addon), so we must pass additional flags as direct
-     * value to the second GenerateLabel call.
-     */
+    ** they don't really match the remainder of the 6502 instruction set (they
+    ** are a Rockwell addon), so we must pass additional flags as direct
+    ** value to the second GenerateLabel call.
+    */
     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), BranchLabel);
+
+    xfree (BranchLabel);
+}
+
+
+
+void OH_ImmediateDirect (const OpcDesc* D)
+{
+    /* Get the operand */
+    unsigned Addr = GetCodeByte (PC+2);
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
+    /* Output the line */
+    OneLine (D, "#$%02X,%s", GetCodeByte (PC+1), GetAddrArg (D->Flags, Addr));
+}
+
+
+
+void OH_ImmediateDirectX (const OpcDesc* D)
+{
+    /* Get the operand */
+    unsigned Addr = GetCodeByte (PC+2);
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
     /* Output the line */
-    OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), GetAddrArg (flLabel, BranchAddr));
+    OneLine (D, "#$%02X,%s,x", GetCodeByte (PC+1), GetAddrArg (D->Flags, Addr));
+}
+
+
+
+void OH_ImmediateAbsolute (const OpcDesc* D)
+{
+    /* Get the operand */
+    unsigned Addr = GetCodeWord (PC+2);
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
+    /* Output the line */
+    OneLine (D, "#$%02X,%s%s", GetCodeByte (PC+1), GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
+}
+
+
+
+void OH_ImmediateAbsoluteX (const OpcDesc* D)
+{
+    /* Get the operand */
+    unsigned Addr = GetCodeWord (PC+2);
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
+    /* Output the line */
+    OneLine (D, "#$%02X,%s%s,x", GetCodeByte (PC+1), GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
 }
 
 
@@ -462,9 +529,32 @@ void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
 
 
 
-void OH_BlockMove (const OpcDesc* D attribute ((unused)))
+void OH_BlockMove (const OpcDesc* D)
 {
-    Error ("Not implemented");
+    char* DstLabel;
+
+    /* Get source operand */
+    unsigned Src = GetCodeWord (PC+1);
+    /* Get destination operand */
+    unsigned Dst = GetCodeWord (PC+3);
+
+    /* Generate a label in pass 1 */
+    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,$%04X",
+             GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src),
+             GetAbsOverride (D->Flags, Dst), DstLabel,
+             GetCodeWord (PC+5));
+
+    xfree (DstLabel);
 }
 
 
@@ -483,9 +573,92 @@ void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
 
 
 
+void OH_DirectImmediate (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, #$%02X", GetAddrArg (D->Flags, Addr), GetCodeByte (PC+2));
+}
+
+
+
+void OH_ZeroPageBit (const OpcDesc* D)
+{
+    unsigned Bit = GetCodeByte (PC) >> 5;
+    unsigned Addr = GetCodeByte (PC+1);
+
+    /* Generate a label in pass 1 */
+    GenerateLabel (D->Flags, Addr);
+
+    /* Output the line */
+    OneLine (D, "%01X,%s", Bit, GetAddrArg (D->Flags, Addr));
+}
+
+
+
+void OH_AccumulatorBit (const OpcDesc* D)
+{
+    unsigned Bit = GetCodeByte (PC) >> 5;
+
+    /* Output the line */
+    OneLine (D, "%01X,a", Bit);
+}
+
+
+
+void OH_AccumulatorBitBranch (const OpcDesc* D)
+{
+    unsigned Bit = GetCodeByte (PC) >> 5;
+    signed char BranchOffs = GetCodeByte (PC+1);
+
+    /* Calculate the target address for the branch */
+    unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF;
+
+    /* Generate labels in pass 1 */
+    GenerateLabel (flLabel, BranchAddr);
+
+    /* Output the line */
+    OneLine (D, "%01X,a,%s", Bit, GetAddrArg (flLabel, BranchAddr));
+}
+
+
+
+void OH_JmpDirectIndirect (const OpcDesc* D)
+{
+    OH_DirectIndirect (D);
+    if (NewlineAfterJMP) {
+        LineFeed ();
+    }
+    SeparatorLine ();
+}
+
+
+
+void OH_SpecialPage (const OpcDesc* D)
+{
+  /* Get the operand */
+  unsigned Addr = 0xFF00 + GetCodeByte (PC+1);
+
+  /* Generate a label in pass 1 */
+  GenerateLabel (D->Flags, Addr);
+
+  /* OneLine (D, "$FF%02X", (CodeByte (PC+1)); */
+  OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
+}
+
+
+
 void OH_Rts (const OpcDesc* D)
 {
     OH_Implicit (D);
+    if (NewlineAfterRTS) {
+        LineFeed ();
+    }
     SeparatorLine();
 }
 
@@ -494,6 +667,9 @@ void OH_Rts (const OpcDesc* D)
 void OH_JmpAbsolute (const OpcDesc* D)
 {
     OH_Absolute (D);
+    if (NewlineAfterJMP) {
+        LineFeed ();
+    }
     SeparatorLine ();
 }
 
@@ -502,8 +678,19 @@ void OH_JmpAbsolute (const OpcDesc* D)
 void OH_JmpAbsoluteIndirect (const OpcDesc* D)
 {
     OH_AbsoluteIndirect (D);
+    if (NewlineAfterJMP) {
+        LineFeed ();
+    }
     SeparatorLine ();
 }
 
 
 
+void OH_JmpAbsoluteXIndirect (const OpcDesc* D)
+{
+    OH_AbsoluteXIndirect (D);
+    if (NewlineAfterJMP) {
+        LineFeed ();
+    }
+    SeparatorLine ();
+}