]> git.sur5r.net Git - cc65/commitdiff
Completed the coding of da65's SEGMENT feature.
authorGreg King <gregdk@users.sf.net>
Sun, 23 Nov 2014 20:29:16 +0000 (15:29 -0500)
committerGreg King <gregdk@users.sf.net>
Sun, 23 Nov 2014 20:29:16 +0000 (15:29 -0500)
Before this commit, we could define segment ranges; but, the disassembler wouldn't do anything with those definitions.  Now, da65 will put ".segment" directives into its output.

Fixed da65's document.

doc/da65.sgml
src/da65/attrtab.c
src/da65/attrtab.h
src/da65/data.c
src/da65/infofile.c
src/da65/main.c
src/da65/output.c
src/da65/output.h
src/da65/segment.c
src/da65/segment.h

index 2b8cdb2a39914362c8b8ce7a9685769564f3fcf4..df8cd777293817fff8d59abe317c748df80cd6ee 100644 (file)
@@ -2,12 +2,14 @@
 
 <article>
 <title>da65 Users Guide
-<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
-<date>2003-08-08
+<author>
+<url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
+<url url="mailto:greg.king5@verizon.net" name="Greg King">
+<date>2014-11-23
 
 <abstract>
-da65 is a 6502/65C02 disassembler that is able to read user supplied
-information about its input data for better results. The output is ready for
+da65 is a 6502/65C02 disassembler that is able to read user-supplied
+information about its input data, for better results. The output is ready for
 feeding into ca65, the macro assembler supplied with the cc65 C compiler.
 </abstract>
 
@@ -23,7 +25,7 @@ the cc65 C compiler and generates output that is suitable for the ca65
 macro assembler.
 
 Besides generating output for ca65, one of the design goals was that the user
-is able to feed additional information about the code into the disassembler
+is able to feed additional information about the code into the disassembler,
 for improved results. This information may include the location and size of
 tables, and their format.
 
@@ -106,11 +108,16 @@ Here is a description of all the command line options:
   <tag><tt>--cpu type</tt></tag>
 
   Set the CPU type. The option takes a parameter, which may be one of
+  <itemize>
+  <item>6502
+  <item>6502x
+  <item>65sc02
+  <item>65c02
+  <item>huc6280
+  </itemize>
 
-               6502, 6502x, 65sc02, 65c02, huc6280
-
-  6502x is the NMOS 6502 with illegal opcodes. huc6280 is the CPU of the PC
-  engine. Support for the 65816 is currently not available.
+  6502x is for the NMOS 6502 with unofficial opcodes. huc6280 is the CPU of
+  the PC engine. Support for the 65816 currently is not available.
 
 
   <label id="option--formfeeds">
@@ -125,7 +132,7 @@ Here is a description of all the command line options:
   <tag><tt>-g, --debug-info</tt></tag>
 
   This option adds the <tt/.DEBUGINFO/ command to the output file, so the
-  assembler will generate debug information when reassembling the generated
+  assembler will generate debug information when re-assembling the generated
   output.
 
 
@@ -241,7 +248,7 @@ unsupported.
 The disassembler works by creating an attribute map for the whole address
 space ($0000 - $FFFF). Initially, all attributes are cleared. Then, an
 external info file (if given) is read. Disassembly is done in several passes.
-In all passes with the exception of the last one, information about the
+In all passes, with the exception of the last one, information about the
 disassembled code is gathered and added to the symbol and attribute maps. The
 last pass generates output using the information from the maps.
 
@@ -275,19 +282,19 @@ braces. Attributes have a name followed by a value. The syntax of the value
 depends on the type of the attribute. String attributes are places in double
 quotes, numeric attributes may be specified as decimal numbers or hexadecimal
 with a leading dollar sign. There are also attributes where the attribute
-value is a keyword, in this case the keyword is given as is (without quotes or
+value is a keyword; in this case, the keyword is given as-is (without quotes or
 anything). Each attribute is terminated by a semicolon.
 
 <tscreen><verb>
-               group-name { attribute1 attribute-value; attribute2 attribute-value; }
+        group-name { attribute1 attribute-value; attribute2 attribute-value; }
 </verb></tscreen>
 
 
 <sect1>Comments<p>
 
-Comments start with a hash mark (<tt/#/)  and extend from the position of
+Comments start with a hash mark (<tt/#/); and, extend from the position of
 the mark to the end of the current line. Hash marks inside of strings will
-of course <em/not/ start a comment.
+<em/not/ start a comment, of course.
 
 
 <sect1>Specifying global options<label id="global-options"><p>
@@ -543,18 +550,17 @@ disassembled code. The following attributes are recognized:
 
   <tag><tt>END</tt></tag>
   Followed by a numerical value. Specifies the end address of the segment. The
-  end address is last the address that is part of the segment.
+  end address is the last address that is a part of the segment.
 
   <tag><tt>NAME</tt></tag>
   The attribute is followed by a string value which gives the name of the
   segment.
 </descrip>
 
-All attributes are mandatory. Segments may not overlap. Since there is no
-explicit "end this segment" pseudo op, the disassembler cannot notify the
-assembler that one segment has ended. This may lead to errors if you don't
-define your segments carefully. As a rule of thumb, if you're using segments,
-your should define segments for all disassembled code.
+All attributes are mandatory. Segments must not overlap. The disassembler will
+change back to the (default) <tt/.code/ segment after the end of each defined
+segment. That might not be what you want. As a rule of thumb, if you're using
+segments, you should define segments for all disassembled code.
 
 
 <sect1>Specifying Assembler Includes<label id="infofile-asminc"><p>
@@ -563,8 +569,8 @@ The <tt/ASMINC/ directive is used to give the names of input files containing
 symbol assignments in assembler syntax:
 
 <tscreen><verb>
-               Name = value
-       Name := value
+        Name = value
+        Name := value
 </verb></tscreen>
 
 The usual conventions apply for symbol names. Values may be specified as hex
@@ -613,48 +619,46 @@ directives explained above:
         };
 
         # One segment for the whole stuff
-        SEGMENT { START $E000;  END   $FFFF; NAME kernal; };
+        SEGMENT { START $E000;  END   $FFFF; NAME "kernal"; };
 
-        RANGE {        START $E612;    END   $E631; TYPE Code;      };
-        RANGE {        START $E632;    END   $E640; TYPE ByteTable; };
-        RANGE {        START $EA51;    END   $EA84; TYPE RtsTable;  };
-        RANGE { START $EC6C;   END   $ECAB; TYPE RtsTable;  };
-        RANGE {        START $ED08;    END   $ED11; TYPE AddrTable; };
+        RANGE { START $E612;    END   $E631; TYPE Code;      };
+        RANGE { START $E632;    END   $E640; TYPE ByteTable; };
+        RANGE { START $EA51;    END   $EA84; TYPE RtsTable;  };
+        RANGE { START $EC6C;    END   $ECAB; TYPE RtsTable;  };
+        RANGE { START $ED08;    END   $ED11; TYPE AddrTable; };
 
-        # Zero page variables
-        LABEL { NAME "fnadr";          ADDR  $90;   SIZE 3;    };
-        LABEL { NAME "sal";    ADDR  $93;   };
-        LABEL { NAME "sah";    ADDR  $94;   };
-        LABEL { NAME "sas";    ADDR  $95;   };
+        # Zero-page variables
+        LABEL { NAME "fnadr";   ADDR  $90;   SIZE 3;    };
+        LABEL { NAME "sal";     ADDR  $93;   };
+        LABEL { NAME "sah";     ADDR  $94;   };
+        LABEL { NAME "sas";     ADDR  $95;   };
 
         # Stack
-        LABEL { NAME "stack";          ADDR  $100;  SIZE 255;  };
+        LABEL { NAME "stack";   ADDR  $100;  SIZE 255;  };
 
         # Indirect vectors
-        LABEL { NAME "cinv";           ADDR  $300;  SIZE 2;    };      # IRQ
-        LABEL { NAME "cbinv";          ADDR  $302;  SIZE 2;    };      # BRK
-        LABEL { NAME "nminv";          ADDR  $304;  SIZE 2;    };      # NMI
+        LABEL { NAME "cinv";    ADDR  $300;  SIZE 2;    };      # IRQ
+        LABEL { NAME "cbinv";   ADDR  $302;  SIZE 2;    };      # BRK
+        LABEL { NAME "nminv";   ADDR  $304;  SIZE 2;    };      # NMI
 
         # Jump table at end of kernal ROM
-        LABEL { NAME "kscrorg";        ADDR  $FFED; };
-        LABEL { NAME "kplot";          ADDR  $FFF0; };
-        LABEL { NAME "kiobase";        ADDR  $FFF3; };
-        LABEL { NAME "kgbye";  ADDR  $FFF6; };
+        LABEL { NAME "kscrorg"; ADDR  $FFED; };
+        LABEL { NAME "kplot";   ADDR  $FFF0; };
+        LABEL { NAME "kiobase"; ADDR  $FFF3; };
+        LABEL { NAME "kgbye";   ADDR  $FFF6; };
 
         # Hardware vectors
-        LABEL { NAME "hanmi";          ADDR  $FFFA; };
-        LABEL { NAME "hares";          ADDR  $FFFC; };
-        LABEL { NAME "hairq";          ADDR  $FFFE; };
+        LABEL { NAME "hanmi";   ADDR  $FFFA; };
+        LABEL { NAME "hares";   ADDR  $FFFC; };
+        LABEL { NAME "hairq";   ADDR  $FFFE; };
 </verb></tscreen>
 
 
 
-
-
 <sect>Copyright<p>
 
-da65 (and all cc65 binutils) are (C) Copyright 1998-2007 Ullrich von
-Bassewitz. For usage of the binaries and/or sources the following
+da65 (and all cc65 binutils) is (C) Copyright 1998-2011, Ullrich von
+Bassewitz. For usage of the binaries and/or sources, the following
 conditions do apply:
 
 This software is provided 'as-is', without any expressed or implied
@@ -666,20 +670,16 @@ including commercial applications, and to alter it and redistribute it
 freely, subject to the following restrictions:
 
 <enum>
-<item>         The origin of this software must not be misrepresented; you must not
-               claim that you wrote the original software. If you use this software
-               in a product, an acknowledgment in the product documentation would be
-       appreciated but is not required.
-<item> Altered source versions must be plainly marked as such, and must not
-       be misrepresented as being the original software.
-<item> This notice may not be removed or altered from any source
-       distribution.
+<item>  The origin of this software must not be misrepresented; you must not
+        claim that you wrote the original software. If you use this software
+        in a product, an acknowledgment in the product documentation would be
+        appreciated but is not required.
+<item>  Altered source versions must be plainly marked as such, and must not
+        be misrepresented as being the original software.
+<item>  This notice may not be removed or altered from any source
+        distribution.
 </enum>
 
 
 
 </article>
-
-
-
-
index 1cfb5ba455b8ccdac391a1c17770b199feebb64d..d288d1298e5f0b9c5ac9abbdf2cfde35a06b1023 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2006 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2014, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -66,6 +66,18 @@ void AddrCheck (unsigned Addr)
 
 
 
+attr_t GetAttr (unsigned Addr)
+/* Return the attribute for the given address */
+{
+    /* Check the given address */
+    AddrCheck (Addr);
+
+    /* Return the attribute */
+    return AttrTab[Addr];
+}
+
+
+
 int SegmentDefined (unsigned Start, unsigned End)
 /* Return true if the atSegment bit is set somewhere in the given range */
 {
@@ -79,14 +91,26 @@ int SegmentDefined (unsigned Start, unsigned End)
 
 
 
-int HaveSegmentChange (unsigned Addr)
-/* Return true if the segment change attribute is set for the given address */
+int IsSegmentEnd (unsigned Addr)
+/* Return true if a segment ends at the given address */
 {
-    /* Check the given address */
-    AddrCheck (Addr);
+    return (GetAttr (Addr) & atSegmentEnd) != 0x0000;
+}
 
-    /* Return the attribute */
-    return (AttrTab[Addr] & atSegmentChange) != 0;
+
+
+int IsSegmentStart (unsigned Addr)
+/* Return true if a segment starts at the given address */
+{
+    return (GetAttr (Addr) & atSegmentStart) != 0x0000;
+}
+
+
+
+int HaveSegmentChange (unsigned Addr)
+/* Return true if the segment change attributes are set for the given address */
+{
+    return (GetAttr (Addr) & (atSegmentStart | atSegmentEnd)) != 0x0000;
 }
 
 
@@ -145,18 +169,6 @@ void MarkAddr (unsigned Addr, attr_t Attr)
 
 
 
-attr_t GetAttr (unsigned Addr)
-/* Return the attribute for the given address */
-{
-    /* Check the given address */
-    AddrCheck (Addr);
-
-    /* Return the attribute */
-    return AttrTab[Addr];
-}
-
-
-
 attr_t GetStyleAttr (unsigned Addr)
 /* Return the style attribute for the given address */
 {
index c9fb9c35fde0f98a18234914c7ba6e1a761da175..b2dc6c45543594006b84134dcef68522d8b0e62c 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2006 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2014, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 typedef enum attr_t {
 
     /* Styles */
-    atDefault       = 0x0000,   /* Default style */
-    atCode          = 0x0001,
-    atIllegal       = 0x0002,
-    atByteTab       = 0x0003,   /* Same as illegal */
-    atDByteTab      = 0x0004,
-    atWordTab       = 0x0005,
-    atDWordTab      = 0x0006,
-    atAddrTab       = 0x0007,
-    atRtsTab        = 0x0008,
-    atTextTab       = 0x0009,
-    atSkip          = 0x000A,   /* Skip code completely */
+    atDefault      = 0x0000,    /* Default style */
+    atCode         = 0x0001,
+    atIllegal      = 0x0002,
+    atByteTab      = 0x0003,    /* Same as illegal */
+    atDByteTab     = 0x0004,
+    atWordTab      = 0x0005,
+    atDWordTab     = 0x0006,
+    atAddrTab      = 0x0007,
+    atRtsTab       = 0x0008,
+    atTextTab      = 0x0009,
+    atSkip         = 0x000A,    /* Skip code completely */
 
     /* Label flags */
-    atNoLabel       = 0x0000,   /* No label for this address */
-    atExtLabel      = 0x0010,   /* External label */
-    atIntLabel      = 0x0020,   /* Internally generated label */
-    atDepLabel      = 0x0040,   /* Dependent label */
-    atUnnamedLabel  = 0x0080,   /* Unnamed label */
+    atNoLabel      = 0x0000,    /* No label for this address */
+    atExtLabel     = 0x0010,    /* External label */
+    atIntLabel     = 0x0020,    /* Internally generated label */
+    atDepLabel     = 0x0040,    /* Dependent label */
+    atUnnamedLabel = 0x0080,    /* Unnamed label */
 
-    atLabelDefined  = 0x0100,   /* True if we defined the label */
+    atLabelDefined = 0x0100,    /* True if we defined the label */
 
-    atStyleMask     = 0x000F,   /* Output style */
-    atLabelMask     = 0x00F0,   /* Label information */
+    atStyleMask    = 0x000F,    /* Output style */
+    atLabelMask    = 0x00F0,    /* Label information */
 
     /* Segment */
-    atSegment       = 0x0100,   /* Code is in a segment */
-    atSegmentChange = 0x0200,   /* Either segment start or segment end */
+    atSegment      = 0x0100,    /* Code is in a segment */
+    atSegmentEnd   = 0x0200,    /* Segment end */
+    atSegmentStart = 0x0400,    /* Segment start */
 } attr_t;
 
 
@@ -87,11 +88,20 @@ typedef enum attr_t {
 void AddrCheck (unsigned Addr);
 /* Check if the given address has a valid range */
 
+attr_t GetAttr (unsigned Addr);
+/* Return the attribute for the given address */
+
 int SegmentDefined (unsigned Start, unsigned End);
 /* Return true if the atSegment bit is set somewhere in the given range */
 
+int IsSegmentEnd (unsigned Addr);
+/* Return true if a segment ends at the given address */
+
+int IsSegmentStart (unsigned Addr);
+/* Return true if a segment starts at the given address */
+
 int HaveSegmentChange (unsigned Addr);
-/* Return true if the segment change attribute is set for the given address */
+/* Return true if the segment change attributes are set for the given address */
 
 unsigned GetGranularity (attr_t Style);
 /* Get the granularity for the given style */
@@ -102,9 +112,6 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr);
 void MarkAddr (unsigned Addr, attr_t Attr);
 /* Mark an address with an attribute */
 
-attr_t GetAttr (unsigned Addr);
-/* Return the attribute for the given address */
-
 attr_t GetStyleAttr (unsigned Addr);
 /* Return the style attribute for the given address */
 
@@ -114,5 +121,4 @@ attr_t GetLabelAttr (unsigned Addr);
 
 
 /* End of attrtab.h */
-
 #endif
index f4c37818fa94ef85d5265af1d706f25d39048ad8..7355e60d17c75ba01549372bfb35c15b543f930b 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2014, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -65,12 +65,12 @@ static unsigned GetSpan (attr_t Style)
         attr_t Attr;
         if (MustDefLabel(PC+Count)) {
             break;
-        }           
+        }
         Attr = GetAttr (PC+Count);
         if ((Attr & atStyleMask) != Style) {
             break;
         }
-        if ((Attr & atSegmentChange)) {
+        if ((Attr & (atSegmentStart | atSegmentEnd))) {
             break;
         }
         ++Count;
index 4ee1ffd79c5de7f2aa51ff9cd1943c39d21ddffd..7d8e6938426030a0a24824bf32a3047b2fe1b0d5 100644 (file)
@@ -748,9 +748,6 @@ static void SegmentSection (void)
     if (Start < 0) {
         InfoError ("Start address is missing");
     }
-    if (Start == End) {
-        InfoError ("Segment is empty");
-    }
     if (Start > End) {
         InfoError ("Start address of segment is greater than end address");
     }
index a819f977194bcf36fcf400c8b027492370d068a8..05c4a7bfd6884fa34fd30f0b05ecd3ebcc0fb2aa 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/* (C) 1998-2014, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -60,6 +60,7 @@
 #include "opctable.h"
 #include "output.h"
 #include "scanner.h"
+#include "segment.h"
 
 
 
@@ -356,6 +357,14 @@ static void OneOpcode (unsigned RemainingBytes)
     /* Get the output style for the current PC */
     attr_t Style = GetStyleAttr (PC);
 
+    /* If a segment begins here, then name that segment.
+    ** Note that the segment is named even if its code is being skipped,
+    ** because some of its later code might not be skipped.
+    */
+    if (IsSegmentStart (PC)) {
+        StartSegment (GetSegmentStartName (PC), GetSegmentAddrSize (PC));
+    }
+
     /* If we have a label at this address, output the label and an attached
     ** comment, provided that we aren't in a skip area.
     */
@@ -371,7 +380,7 @@ static void OneOpcode (unsigned RemainingBytes)
     **   - ...if we have enough bytes remaining for the code at this address.
     **   - ...if the current instruction is valid for the given CPU.
     **   - ...if there is no label somewhere between the instruction bytes.
-    ** If any of these conditions is false, switch to data mode.
+    ** If any of those conditions is false, switch to data mode.
     */
     if (Style == atDefault) {
         if (D->Size > RemainingBytes) {
@@ -383,7 +392,14 @@ static void OneOpcode (unsigned RemainingBytes)
         } else {
             unsigned I;
             for (I = 1; I < D->Size; ++I) {
-                if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) {
+                if (HaveLabel (PC+I)) {
+                    Style = atIllegal;
+                    MarkAddr (PC, Style);
+                    break;
+                }
+            }
+            for (I = 1; I < D->Size - 1u; ++I) {
+                if (HaveSegmentChange (PC+I)) {
                     Style = atIllegal;
                     MarkAddr (PC, Style);
                     break;
@@ -455,6 +471,10 @@ static void OneOpcode (unsigned RemainingBytes)
             break;
 
     }
+
+    if (IsSegmentEnd (PC - 1)) {
+        EndSegment ();
+    }
 }
 
 
index 9098d7d3766c55c8b3464fe665fbcaa7a5b0c9ce..4daacb1ee5222f813dc6f6f82f27d3f7af2d1c0c 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2009, Ullrich von Bassewitz                                      */
+/* (C) 2000-2014, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -63,6 +63,8 @@ static unsigned Col     = 1;            /* Current column */
 static unsigned Line    = 0;            /* Current line on page */
 static unsigned Page    = 1;            /* Current output page */
 
+static const char* SegmentName = 0;     /* Name of current segment */
+
 
 
 /*****************************************************************************/
@@ -223,23 +225,6 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr)
 
 
 
-void StartSegment (const char* Name, unsigned AddrSize)
-/* Start a segment */
-{
-    if (Pass == PassCount) {
-        Output (".segment");
-        Indent (ACol);
-        if (AddrSize == ADDR_SIZE_DEFAULT) {
-            Output ("\"%s\"", Name);
-        } else {
-            Output ("\"%s\": %s", Name, AddrSizeToStr (AddrSize));
-        }
-        LineFeed ();
-    }
-}
-
-
-
 void DataByteLine (unsigned ByteCount)
 /* Output a line with bytes */
 {
@@ -335,6 +320,39 @@ void SeparatorLine (void)
 
 
 
+void StartSegment (const char* Name, unsigned AddrSize)
+/* Start a segment */
+{
+    if (Pass == PassCount) {
+        LineFeed ();
+        Output (".segment");
+        Indent (ACol);
+        SegmentName = Name;
+        Output ("\"%s\"", Name);
+        if (AddrSize != ADDR_SIZE_DEFAULT) {
+            Output (": %s", AddrSizeToStr (AddrSize));
+        }
+        LineFeed ();
+        LineFeed ();
+    }
+}
+
+
+
+void EndSegment (void)
+/* End a segment */
+{
+    LineFeed ();
+    Output ("; End of \"%s\" segment", SegmentName);
+    LineFeed ();
+    SeparatorLine ();
+    Output (".code");
+    LineFeed ();
+    LineFeed ();
+}
+
+
+
 void UserComment (const char* Comment)
 /* Output a comment line */
 {
index ad5f8d34e29a0fd5444578fdb6610c77816b52fd..13ea0cc859645e0c8cfc53d1b13a10d015c9be32 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2014, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -74,12 +74,6 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs);
 
 void DefConst (const char* Name, const char* Comment, unsigned Addr);
 /* Define an address constant */
-        
-void StartSegment (const char* Name, unsigned AddrSize);
-/* Start a segment */
-
-void EndSegment (void);
-/* End a segment */
 
 void OneDataByte (void);
 /* Output a .byte line with the current code byte */
@@ -99,6 +93,12 @@ void DataDWordLine (unsigned ByteCount);
 void SeparatorLine (void);
 /* Print a separator line */
 
+void StartSegment (const char* Name, unsigned AddrSize);
+/* Start a segment */
+
+void EndSegment (void);
+/* End a segment */
+
 void UserComment (const char* Comment);
 /* Output a comment line */
 
@@ -111,5 +111,4 @@ void OutputSettings (void);
 
 
 /* End of output.h */
-
 #endif
index cad2096ff9ede24825da369f6bd6bb4bffe8ebde..12d4cf65699dc428f408d11838d6b6540b2c58e7 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2007      Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2007-2014, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 typedef struct Segment Segment;
 struct Segment {
     Segment*            NextStart;      /* Pointer to next segment */
-    Segment*            NextEnd;        /* Pointer to next segment */
     unsigned long       Start;
-    unsigned long       End;
     unsigned            AddrSize;
     char                Name[1];        /* Name, dynamically allocated */
 };
 
-/* Tables containing the segments. A segment is inserted using it's hash
-** value. Collision is done by single linked lists.
+/* Table containing the segments. A segment is inserted using its hash
+** value. Collisions are handled by single-linked lists.
 */
 static Segment* StartTab[HASH_SIZE];    /* Table containing segment starts */
-static Segment* EndTab[HASH_SIZE];      /* Table containing segment ends */
 
 
 
@@ -90,20 +87,53 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name)
 
     /* Fill in the data */
     S->Start    = Start;
-    S->End      = End;
     S->AddrSize = ADDR_SIZE_ABS;
     memcpy (S->Name, Name, Len + 1);
 
-    /* Insert the segment into the hash tables */
+    /* Insert the segment into the hash table */
     S->NextStart = StartTab[Start % HASH_SIZE];
     StartTab[Start % HASH_SIZE] = S;
-    S->NextEnd = EndTab[End % HASH_SIZE];
-    EndTab[End % HASH_SIZE] = S;
 
     /* Mark start and end of the segment */
-    MarkAddr (Start, atSegmentChange);
-    MarkAddr (End, atSegmentChange);
+    MarkAddr (Start, atSegmentStart);
+    MarkAddr (End, atSegmentEnd);
 
     /* Mark the addresses within the segment */
     MarkRange (Start, End, atSegment);
 }
+
+
+
+char* GetSegmentStartName (unsigned Addr)
+/* Return the name of the segment which starts at the given address */
+{
+    Segment* S = StartTab[Addr % HASH_SIZE];
+
+    /* Search the collision list for the exact address */
+    while (S != 0) {
+        if (S->Start == Addr) {
+            return S->Name;
+        }
+        S = S->NextStart;
+    }
+
+    return 0;
+}
+
+
+
+unsigned GetSegmentAddrSize (unsigned Addr)
+/* Return the address size of the segment which starts at the given address */
+{
+    Segment* S = StartTab[Addr % HASH_SIZE];
+
+    /* Search the collision list for the exact address */
+    while (S != 0) {
+        if (S->Start == Addr) {
+            return S->AddrSize;
+        }
+        S = S->NextStart;
+    }
+
+    return 0;
+}
index 14700ba99f8258ee31c7e7103822f796247709f0..b1423bb41a3bcfa5ed43e135dc188fe4949bdad7 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2007      Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2007-2014, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 void AddAbsSegment (unsigned Start, unsigned End, const char* Name);
 /* Add an absolute segment to the segment table */
 
+char* GetSegmentStartName (unsigned Addr);
+/* Return the name of the segment which starts at the given address */
+
+unsigned GetSegmentAddrSize (unsigned Addr);
+/* Return the address size of the segment which starts at the given address */
 
 
-/* End of segment.h */
 
+/* End of segment.h */
 #endif