}
}
return 0;
-}
+}
+
+
+
+int HaveSegmentChange (unsigned Addr)
+/* Return true if the segment change attribute is set for the given address */
+{
+ /* Check the given address */
+ AddrCheck (Addr);
+
+ /* Return the attribute */
+ return (AttrTab[Addr] & atSegmentChange) != 0;
+}
+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 */
{
/* Segment */
atSegment = 0x0100, /* Code is in a segment */
+ atSegmentChange = 0x0200, /* Either segment start or segment end */
} attr_t;
int SegmentDefined (unsigned Start, unsigned End);
/* Return true if the atSegment bit is set somewhere in the given range */
+int HaveSegmentChange (unsigned Addr);
+/* Return true if the segment change attribute is set for the given address */
+
unsigned GetGranularity (attr_t Style);
/* Get the granularity for the given style */
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 */
/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2000-2007 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
unsigned RemainingBytes = GetRemainingBytes ();
/* Count how many bytes are available. This number is limited by the
- * number of remaining bytes, a label, or the end of the given Style
- * attribute.
+ * number of remaining bytes, a label, a segment change, or the end of
+ * the given Style attribute.
*/
unsigned Count = 1;
while (Count < RemainingBytes) {
- if (MustDefLabel(PC+Count) || GetStyleAttr (PC+Count) != Style) {
+ attr_t Attr;
+ if (MustDefLabel(PC+Count)) {
break;
- }
+ }
+ Attr = GetAttr (PC+Count);
+ if ((Attr & atStyleMask) != Style) {
+ break;
+ }
+ if ((Attr & atSegmentChange)) {
+ break;
+ }
++Count;
}
/* */
/* */
/* */
-/* (C) 2006 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2006-2007 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
case atIntLabel:
case atExtLabel:
- DefineConst (SymTab[Addr], GetComment (Addr), Addr);
+ DefConst (SymTab[Addr], GetComment (Addr), Addr);
break;
case atUnnamedLabel:
/* */
/* */
/* */
-/* (C) 1998-2006 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 1998-2007 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
} else {
unsigned I;
for (I = 1; I < D->Size; ++I) {
- if (HaveLabel (PC+I)) {
+ if (HaveLabel (PC+I) || HaveSegmentChange (PC+I)) {
Style = atIllegal;
MarkAddr (PC, Style);
break;
/* */
/* */
/* */
-/* (C) 2000-2006 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2000-2007 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#include <errno.h>
/* common */
+#include "addrsize.h"
#include "cpu.h"
#include "version.h"
-void DefineConst (const char* Name, const char* Comment, unsigned Addr)
+void DefConst (const char* Name, const char* Comment, unsigned Addr)
/* Define an address constant */
{
if (Pass == PassCount) {
+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 */
{
/* */
/* */
/* */
-/* (C) 2000-2003 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2000-2007 Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
void DefLabel (const char* Name);
/* Define a label with the given name */
-void DefForward (const char* Name, const char* Comment, unsigned Offs);
+void DefForward (const char* Name, const char* Comment, unsigned Offs);
/* Define a label as "* + x", where x is the offset relative to the
* current PC.
*/
-void DefineConst (const char* Name, const char* Comment, unsigned Addr);
+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 */
/* Hash definitions */
-#define HASH_SIZE 64 /* Must be power of two */
-#define HASH_MASK (HASH_SIZE-1)
+#define HASH_SIZE 53
/* Segment definition */
typedef struct Segment Segment;
memcpy (S->Name, Name, Len + 1);
/* Insert the segment into the hash tables */
- S->NextStart = StartTab[Start & HASH_MASK];
- StartTab[Start & HASH_MASK] = S;
- S->NextEnd = EndTab[End & HASH_MASK];
- EndTab[End & HASH_MASK] = S;
+ 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);
/* Mark the addresses within the segment */
MarkRange (Start, End, atSegment);