From b9a703749cb77c0d0be0d7222ffec68a02f88a60 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 22 Jun 2025 11:50:47 +0200 Subject: [PATCH 1/3] Replace all tables by hash tables. This allows to remove the ugly special casing of "long addresses" and prepares the code base for use with the full address range of the 65816. Use fixed size data types for addresses and target data words of known size. Many other minor improvements. --- src/da65/attrtab.c | 173 ++++++++++++++++---------- src/da65/attrtab.h | 24 ++-- src/da65/code.c | 41 +++--- src/da65/code.h | 24 ++-- src/da65/comments.c | 124 +++++++++++------- src/da65/comments.h | 7 +- src/da65/data.c | 46 +++---- src/da65/data.h | 14 +-- src/da65/global.c | 3 +- src/da65/global.h | 7 +- src/da65/handler.c | 120 +++++++++--------- src/da65/handler.h | 4 +- src/da65/infofile.c | 50 ++++---- src/da65/labels.c | 297 ++++++++++++++++++++++++++------------------ src/da65/labels.h | 23 ++-- src/da65/main.c | 11 +- src/da65/output.c | 41 +++--- src/da65/output.h | 10 +- src/da65/scanner.c | 4 +- src/da65/scanner.h | 2 +- src/da65/segment.c | 8 +- src/da65/segment.h | 6 +- 22 files changed, 604 insertions(+), 435 deletions(-) diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 002965dff0..1ba694038b 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -33,6 +33,11 @@ +#include + +/* common */ +#include "xmalloc.h" + /* da65 */ #include "cpu.h" #include "error.h" @@ -46,68 +51,124 @@ -/* Attribute table */ -static unsigned short AttrTab[0x10000]; +/* Attribute structure how it is found in the attribute table */ +typedef struct Attribute Attribute; +struct Attribute { + struct Attribute* Next; /* Next entry in linked list */ + uint32_t Addr; /* The full address */ + attr_t Attr; /* Actual attribute */ +}; -/* 65816 attribute table */ -#define MAX_LONG_ATTRS 256 -static unsigned short LongAttrVal[MAX_LONG_ATTRS]; -static unsigned LongAttrAddr[MAX_LONG_ATTRS]; -static unsigned LongAttrsUsed; +/* Attributes use a hash table and a linear list for collision resolution. The +** hash function is easy and effective. It evaluates just the lower bits of +** the address. +*/ +#define ATTR_HASH_SIZE 8192u /* Must be power of two */ +static Attribute* AttributeTab[ATTR_HASH_SIZE]; /*****************************************************************************/ -/* Code */ +/* struct Attribute */ /*****************************************************************************/ -void AddrCheck (unsigned Addr) -/* Check if the given address has a valid range */ +static Attribute* NewAttribute (uint32_t Addr, attr_t Attr) +/* Create a new attribute structure and return it */ { - if (Addr >= 0x10000 && CPU != CPU_65816) { - Error ("Address out of range: %08X", Addr); + /* Create a new attribute */ + Attribute* A = xmalloc (sizeof (Attribute)); + + /* Fill in the data */ + A->Next = 0; + A->Addr = Addr; + A->Attr = Attr; + + /* Return the attribute just created */ + return A; +} + + + +static uint32_t GetAttributeHash (uint32_t Addr) +/* Get the hash for an attribute at the given address */ +{ + return (Addr & (ATTR_HASH_SIZE - 1)); +} + + + +static Attribute* FindAttribute (uint32_t Addr) +/* Search for an attribute for the given address and return it. Returns NULL +** if no attribute exists for the address. +*/ +{ + Attribute* A = AttributeTab[GetAttributeHash (Addr)]; + while (A) { + if (A->Addr == Addr) { + break; + } + A = A->Next; } + return A; } -unsigned char IsLongAddr (unsigned Addr) -/* Is it 24-bit? */ + +static void InsertAttribute (Attribute* A) +/* Insert an attribute into the hash table */ { - return Addr >= 0x10000 && CPU == CPU_65816; + uint32_t Hash = GetAttributeHash (A->Addr); + A->Next = AttributeTab[Hash]; + AttributeTab[Hash] = A; } -attr_t GetAttr (unsigned Addr) -/* Return the attribute for the given address */ +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void AddrCheck (uint32_t Addr) +/* Check if the given address has a valid range */ { - /* Check the given address */ - AddrCheck (Addr); + if (Addr >= 0x10000 && CPU != CPU_65816) { + Error ("Address out of range: $%04" PRIX32, Addr); + } +} + - if (IsLongAddr (Addr)) { - unsigned i; - for (i = 0; i < LongAttrsUsed; i++) { - if (LongAttrAddr[i] == Addr) { - return LongAttrVal[i]; - } - } - return 0; +attr_t GetAttr (uint32_t Addr) +/* Return the attribute for the given address */ +{ + /* As a small optimization we cache the last used attribute so when the + ** function is called several times with the same address we do already + ** know it. + */ + static const Attribute* A = 0; + if (A != 0 && A->Addr == Addr) { + return A->Attr; } + /* Check the given address */ + AddrCheck (Addr); + /* Return the attribute */ - return AttrTab[Addr]; + A = FindAttribute (Addr); + return A? A->Attr : atDefault; } -int SegmentDefined (unsigned Start, unsigned End) +int SegmentDefined (uint32_t Start, uint32_t End) /* Return true if the atSegment bit is set somewhere in the given range */ { while (Start <= End) { - if (AttrTab[Start++] & atSegment) { + if (GetAttr (Start++) & atSegment) { return 1; } } @@ -116,7 +177,7 @@ int SegmentDefined (unsigned Start, unsigned End) -int IsSegmentEnd (unsigned Addr) +int IsSegmentEnd (uint32_t Addr) /* Return true if a segment ends at the given address */ { return (GetAttr (Addr) & atSegmentEnd) != 0x0000; @@ -124,7 +185,7 @@ int IsSegmentEnd (unsigned Addr) -int IsSegmentStart (unsigned Addr) +int IsSegmentStart (uint32_t Addr) /* Return true if a segment starts at the given address */ { return (GetAttr (Addr) & atSegmentStart) != 0x0000; @@ -155,7 +216,7 @@ unsigned GetGranularity (attr_t Style) -void MarkRange (unsigned Start, unsigned End, attr_t Attr) +void MarkRange (uint32_t Start, uint32_t End, attr_t Attr) /* Mark a range with the given attribute */ { /* Do it easy here... */ @@ -166,53 +227,33 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr) -void MarkAddr (unsigned Addr, attr_t Attr) +void MarkAddr (uint32_t Addr, attr_t Attr) /* Mark an address with an attribute */ { /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - unsigned i; - for (i = 0; i < LongAttrsUsed; i++) { - if (LongAttrAddr[i] == Addr) { - - /* We must not have more than one style bit */ - if (Attr & atStyleMask) { - if (LongAttrVal[i] & atStyleMask) { - Error ("Duplicate style for long address %06X", Addr); - } - } - LongAttrVal[i] |= Attr; - - return; - } - } - - if (LongAttrsUsed >= MAX_LONG_ATTRS) { - Error ("Too many long addresses"); - } - LongAttrVal[LongAttrsUsed] |= Attr; - LongAttrAddr[LongAttrsUsed] = Addr; - LongAttrsUsed++; - - return; - } + /* Get an existing attribute entry */ + Attribute* A = FindAttribute (Addr); /* We must not have more than one style bit */ - if (Attr & atStyleMask) { - if (AttrTab[Addr] & atStyleMask) { - Error ("Duplicate style for address %04X", Addr); + if (A != 0 && (Attr & atStyleMask) != 0) { + if ((A->Attr & atStyleMask) != 0) { + Error ("Duplicate style for address %04" PRIX32, Addr); } } /* Set the style */ - AttrTab[Addr] |= Attr; + if (A) { + A->Attr |= Attr; + } else { + InsertAttribute (NewAttribute (Addr, Attr)); + } } -attr_t GetStyleAttr (unsigned Addr) +attr_t GetStyleAttr (uint32_t Addr) /* Return the style attribute for the given address */ { /* Check the given address */ @@ -224,7 +265,7 @@ attr_t GetStyleAttr (unsigned Addr) -attr_t GetLabelAttr (unsigned Addr) +attr_t GetLabelAttr (uint32_t Addr) /* Return the label attribute for the given address */ { /* Check the given address */ diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index 4a0ea8225b..ec44fd3b33 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -38,6 +38,10 @@ +#include + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -95,37 +99,37 @@ typedef enum attr_t { -void AddrCheck (unsigned Addr); +void AddrCheck (uint32_t Addr); /* Check if the given address has a valid range */ -unsigned char IsLongAddr (unsigned Addr); +unsigned char IsLongAddr (uint32_t Addr); /* Check if the given address is 24-bit */ -attr_t GetAttr (unsigned Addr); +attr_t GetAttr (uint32_t Addr); /* Return the attribute for the given address */ -int SegmentDefined (unsigned Start, unsigned End); +int SegmentDefined (uint32_t Start, unsigned End); /* Return true if the atSegment bit is set somewhere in the given range */ -int IsSegmentEnd (unsigned Addr); +int IsSegmentEnd (uint32_t Addr); /* Return true if a segment ends at the given address */ -int IsSegmentStart (unsigned Addr); +int IsSegmentStart (uint32_t Addr); /* Return true if a segment starts at the given address */ unsigned GetGranularity (attr_t Style); /* Get the granularity for the given style */ -void MarkRange (unsigned Start, unsigned End, attr_t Attr); +void MarkRange (uint32_t Start, uint32_t End, attr_t Attr); /* Mark a range with the given attribute */ -void MarkAddr (unsigned Addr, attr_t Attr); +void MarkAddr (uint32_t Addr, attr_t Attr); /* Mark an address with an attribute */ -attr_t GetStyleAttr (unsigned Addr); +attr_t GetStyleAttr (uint32_t Addr); /* Return the style attribute for the given address */ -attr_t GetLabelAttr (unsigned Addr); +attr_t GetLabelAttr (uint32_t Addr); /* Return the label attribute for the given address */ diff --git a/src/da65/code.c b/src/da65/code.c index a162e64823..6045e83c57 100644 --- a/src/da65/code.c +++ b/src/da65/code.c @@ -53,10 +53,10 @@ -unsigned char CodeBuf [0x10000]; /* Code buffer */ -unsigned long CodeStart; /* Start address */ -unsigned long CodeEnd; /* End address */ -unsigned long PC; /* Current PC */ +uint8_t CodeBuf[0x10000]; /* Code buffer */ +uint32_t CodeStart; /* Start address */ +uint32_t CodeEnd; /* End address */ +uint32_t PC; /* Current PC */ @@ -117,12 +117,13 @@ void LoadCode (void) ** 0x10000 - Size. This is a reasonable default assuming that the file ** is a ROM that contains the hardware vectors at $FFFA. */ - if (StartAddr < 0) { + if (!HaveStartAddr) { if (Size > 0x10000) { StartAddr = 0; } else { StartAddr = 0x10000 - Size; } + HaveStartAddr = 1; } /* Calculate the maximum code size */ @@ -155,7 +156,7 @@ void LoadCode (void) -unsigned char GetCodeByte (unsigned Addr) +uint8_t GetCodeByte (uint32_t Addr) /* Get a byte from the given address */ { PRECONDITION (Addr <= CodeEnd); @@ -164,48 +165,48 @@ unsigned char GetCodeByte (unsigned Addr) -unsigned GetCodeDByte (unsigned Addr) +uint16_t GetCodeDByte (uint32_t Addr) /* Get a dbyte from the given address */ { - unsigned Lo = GetCodeByte (Addr); - unsigned Hi = GetCodeByte (Addr+1); + uint16_t Lo = GetCodeByte (Addr); + uint16_t Hi = GetCodeByte (Addr+1); return (Lo <<8) | Hi; } -unsigned GetCodeWord (unsigned Addr) +uint16_t GetCodeWord (uint32_t Addr) /* Get a word from the given address */ { - unsigned Lo = GetCodeByte (Addr); - unsigned Hi = GetCodeByte (Addr+1); + uint16_t Lo = GetCodeByte (Addr); + uint16_t Hi = GetCodeByte (Addr+1); return Lo | (Hi << 8); } -unsigned long GetCodeDWord (unsigned Addr) +uint32_t GetCodeDWord (uint32_t Addr) /* Get a dword from the given address */ { - unsigned long Lo = GetCodeWord (Addr); - unsigned long Hi = GetCodeWord (Addr+2); + uint32_t Lo = GetCodeWord (Addr); + uint32_t Hi = GetCodeWord (Addr+2); return Lo | (Hi << 16); } -unsigned GetCodeLongAddr (unsigned Addr) +uint32_t GetCodeLongAddr (uint32_t Addr) /* Get a word from the given address */ { - unsigned Lo = GetCodeByte (Addr); - unsigned Mid = GetCodeByte (Addr+1); - unsigned Hi = GetCodeByte (Addr+2); + uint32_t Lo = GetCodeByte (Addr); + uint32_t Mid = GetCodeByte (Addr+1); + uint32_t Hi = GetCodeByte (Addr+2); return Lo | (Mid << 8) | (Hi << 16); } -unsigned GetRemainingBytes (void) +uint32_t GetRemainingBytes (void) /* Return the number of remaining code bytes */ { if (CodeEnd >= PC) { diff --git a/src/da65/code.h b/src/da65/code.h index aa3c6a2904..1a4cce2c87 100644 --- a/src/da65/code.h +++ b/src/da65/code.h @@ -38,16 +38,20 @@ +#include + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ -extern unsigned char CodeBuf [0x10000]; /* Code buffer */ -extern unsigned long CodeStart; /* Start address */ -extern unsigned long CodeEnd; /* End address */ -extern unsigned long PC; /* Current PC */ +extern uint8_t CodeBuf[0x10000]; /* Code buffer */ +extern uint32_t CodeStart; /* Start address */ +extern uint32_t CodeEnd; /* End address */ +extern uint32_t PC; /* Current PC */ @@ -60,22 +64,22 @@ extern unsigned long PC; /* Current PC */ void LoadCode (void); /* Load the code from the given file */ -unsigned char GetCodeByte (unsigned Addr); +uint8_t GetCodeByte (uint32_t Addr); /* Get a byte from the given address */ -unsigned GetCodeDByte (unsigned Addr); +uint16_t GetCodeDByte (uint32_t Addr); /* Get a dbyte from the given address */ -unsigned GetCodeWord (unsigned Addr); +uint16_t GetCodeWord (uint32_t Addr); /* Get a word from the given address */ -unsigned long GetCodeDWord (unsigned Addr); +uint32_t GetCodeDWord (uint32_t Addr); /* Get a dword from the given address */ -unsigned GetCodeLongAddr (unsigned Addr); +uint32_t GetCodeLongAddr (uint32_t Addr); /* Get a 24-bit address from the given address */ -unsigned GetRemainingBytes (void); +uint32_t GetRemainingBytes (void); /* Return the number of remaining code bytes */ int CodeLeft (void); diff --git a/src/da65/comments.c b/src/da65/comments.c index f136ae3d20..f1295d486c 100644 --- a/src/da65/comments.c +++ b/src/da65/comments.c @@ -33,6 +33,9 @@ +#include +#include + /* common */ #include "xmalloc.h" @@ -49,78 +52,115 @@ -/* Comment table */ -static const char* CommentTab[0x10000]; +/* Comment structure how it is found in the comment table */ +typedef struct Comment Comment; +struct Comment { + struct Comment* Next; /* Next entry in linked list */ + uint32_t Addr; /* The full address */ + char Text[1]; /* Text, dynamically allocated */ +}; -#define MAX_LONG_COMMENTS 256 -static const char* LongCommentVal[MAX_LONG_COMMENTS]; -static unsigned LongCommentAddr[MAX_LONG_COMMENTS]; -static unsigned LongCommentsUsed; +/* Comments use a hash table and a linear list for collision resolution. The +** hash function is easy and effective. It evaluates just the lower bits of +** the address. Since we don't expect many comments, we can keep the table +** small. +*/ +#define COMMENT_HASH_SIZE 256u /* Must be power of two */ +static Comment* CommentTab[COMMENT_HASH_SIZE]; /*****************************************************************************/ -/* Code */ +/* struct Comment */ /*****************************************************************************/ -static unsigned FindLongIndex (unsigned Addr) +static Comment* NewComment (uint32_t Addr, const char* Text) +/* Create a new comment structure and return it */ +{ + /* Get the length of the text */ + unsigned Len = strlen (Text); + + /* Create a new comment */ + Comment* C = xmalloc (sizeof (Comment) + Len); + + /* Fill in the data */ + C->Next = 0; + C->Addr = Addr; + memcpy (C->Text, Text, Len + 1); + + /* Return the comment just created */ + return C; +} + + + +static uint32_t GetCommentHash (uint32_t Addr) +/* Get the hash for a comment at the given address */ +{ + return (Addr & (COMMENT_HASH_SIZE - 1)); +} + + + +static Comment* FindComment (uint32_t Addr) +/* Search for a comment for the given address and return it. Returns NULL if +** no comment exists for the address. +*/ { - unsigned i; - for (i = 0; i < LongCommentsUsed; i++) { - if (LongCommentAddr[i] == Addr) { - return i; + Comment* C = CommentTab[GetCommentHash (Addr)]; + while (C) { + if (C->Addr == Addr) { + break; } + C = C->Next; } - return -1; + return C; } -void SetComment (unsigned Addr, const char* Comment) +static void InsertComment (Comment* C) +/* Insert a comment into the hash table */ +{ + uint32_t Hash = GetCommentHash (C->Addr); + C->Next = CommentTab[Hash]; + CommentTab[Hash] = C; +} + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void SetComment (uint32_t Addr, const char* Text) /* Set a comment for the given address */ { /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - if (FindLongIndex (Addr)) { - Warning ("Duplicate comment for address $%06X", Addr); - } else { - if (LongCommentsUsed >= MAX_LONG_COMMENTS) { - Error("Too many long-address comments"); - } - LongCommentVal[LongCommentsUsed] = xstrdup (Comment); - LongCommentAddr[LongCommentsUsed] = Addr; - LongCommentsUsed++; - } + /* If we do already have a comment, warn and ignore the new one */ + Comment* C = FindComment (Addr); + if (C) { + Warning ("Duplicate comment for address $%04" PRIX32, Addr); } else { - /* If we do already have a comment, warn and ignore the new one */ - if (CommentTab[Addr]) { - Warning ("Duplicate comment for address $%04X", Addr); - } else { - CommentTab[Addr] = xstrdup (Comment); - } + InsertComment (NewComment (Addr, Text)); } } -const char* GetComment (unsigned Addr) +const char* GetComment (uint32_t Addr) /* Return the comment for an address */ { /* Check the given address */ AddrCheck (Addr); - if (IsLongAddr (Addr)) { - const unsigned i = FindLongIndex (Addr); - if (i < LongCommentsUsed) { - return LongCommentVal[i]; - } - return NULL; - } - - /* Return the label if any */ - return CommentTab[Addr]; + /* Check for a comment and return it */ + const Comment* C = FindComment (Addr); + return C? C->Text : 0; } diff --git a/src/da65/comments.h b/src/da65/comments.h index 1d95111a9c..dfa1654ab2 100644 --- a/src/da65/comments.h +++ b/src/da65/comments.h @@ -38,6 +38,9 @@ +#include + +/* da65 */ #include "attrtab.h" @@ -48,10 +51,10 @@ -void SetComment (unsigned Addr, const char* Comment); +void SetComment (uint32_t Addr, const char* Text); /* Set a comment for the given address */ -const char* GetComment (unsigned Addr); +const char* GetComment (uint32_t Addr); /* Return the comment for an address */ diff --git a/src/da65/data.c b/src/da65/data.c index f85cd327de..a7389ca5ab 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -50,17 +50,17 @@ -static unsigned GetSpan (attr_t Style) +static uint32_t GetSpan (attr_t Style) /* Get the number of bytes for a given style */ { /* Get the number of bytes still available */ - unsigned RemainingBytes = GetRemainingBytes (); + uint32_t RemainingBytes = GetRemainingBytes (); /* Count how many bytes are available. This number is limited by the ** number of remaining bytes, a label, a segment change, or the end of ** the given Style attribute. */ - unsigned Count = 1; + uint32_t Count = 1; while (Count < RemainingBytes) { attr_t Attr; if (MustDefLabel(PC+Count)) { @@ -85,10 +85,10 @@ static unsigned GetSpan (attr_t Style) static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (unsigned)) /* Output a table of bytes */ { - unsigned BytesLeft; + uint32_t BytesLeft; /* Count how many bytes may be output. */ - unsigned Count = GetSpan (Style); + uint32_t Count = GetSpan (Style); /* If the count is less than the member size, print a row of Count data ** bytes. We assume here that there is no member with a size that is less @@ -108,7 +108,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u while (BytesLeft > 0) { /* Calculate the number of bytes for the next line */ - unsigned Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft; + uint32_t Chunk = (BytesLeft > BytesPerLine)? BytesPerLine : BytesLeft; /* Output a line with these bytes */ TableFunc (Chunk); @@ -129,7 +129,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u -unsigned ByteTable (void) +uint32_t ByteTable (void) /* Output a table of bytes */ { /* Call the low level function */ @@ -138,7 +138,7 @@ unsigned ByteTable (void) -unsigned DByteTable (void) +uint32_t DByteTable (void) /* Output a table of dbytes */ { /* Call the low level function */ @@ -147,7 +147,7 @@ unsigned DByteTable (void) -unsigned WordTable (void) +uint32_t WordTable (void) /* Output a table of words */ { /* Call the low level function */ @@ -156,7 +156,7 @@ unsigned WordTable (void) -unsigned DWordTable (void) +uint32_t DWordTable (void) /* Output a table of double words */ { /* Call the low level function */ @@ -165,18 +165,18 @@ unsigned DWordTable (void) -unsigned AddrTable (void) +uint32_t AddrTable (void) /* Output a table of addresses */ { - unsigned long BytesLeft = GetRemainingBytes (); - unsigned long Start = PC; + uint32_t BytesLeft = GetRemainingBytes (); + uint32_t Start = PC; /* Loop while table bytes left and we don't need to create a label at the ** current position. */ while (BytesLeft && GetStyleAttr (PC) == atAddrTab) { - unsigned Addr; + uint32_t Addr; /* If just one byte is left, define it and bail out */ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atAddrTab) { @@ -231,18 +231,18 @@ unsigned AddrTable (void) -unsigned RtsTable (void) +uint32_t RtsTable (void) /* Output a table of RTS addresses (address - 1) */ { - unsigned long BytesLeft = GetRemainingBytes (); - unsigned long Start = PC; + uint32_t BytesLeft = GetRemainingBytes (); + uint32_t Start = PC; /* Loop while table bytes left and we don't need to create a label at the ** current position. */ while (BytesLeft && GetStyleAttr (PC) == atRtsTab) { - unsigned Addr; + uint32_t Addr; /* If just one byte is left, define it and bail out */ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atRtsTab) { @@ -297,14 +297,14 @@ unsigned RtsTable (void) -unsigned TextTable (void) +uint32_t TextTable (void) /* Output a table of text messages */ { /* Count how many bytes may be output. */ - unsigned ByteCount = GetSpan (atTextTab); + uint32_t ByteCount = GetSpan (atTextTab); /* Output as many data bytes lines as needed. */ - unsigned BytesLeft = ByteCount; + uint32_t BytesLeft = ByteCount; while (BytesLeft > 0) { unsigned I; @@ -312,7 +312,7 @@ unsigned TextTable (void) /* Count the number of characters that can be output as such */ unsigned Count = 0; while (Count < BytesLeft && Count < BytesPerLine*4-1) { - unsigned char C = GetCodeByte (PC + Count); + uint8_t C = GetCodeByte (PC + Count); if (C >= 0x20 && C <= 0x7E && C != '\"') { ++Count; } else { @@ -348,7 +348,7 @@ unsigned TextTable (void) /* Count the number of bytes that must be output as bytes */ Count = 0; while (Count < BytesLeft && Count < BytesPerLine) { - unsigned char C = GetCodeByte (PC + Count); + uint8_t C = GetCodeByte (PC + Count); if (C < 0x20 || C > 0x7E || C == '\"') { ++Count; } else { diff --git a/src/da65/data.h b/src/da65/data.h index 4cec14a03e..d9885b7800 100644 --- a/src/da65/data.h +++ b/src/da65/data.h @@ -44,25 +44,25 @@ -unsigned ByteTable (void); +uint32_t ByteTable (void); /* Output a table of bytes */ -unsigned DByteTable (void); +uint32_t DByteTable (void); /* Output a table of dbytes */ -unsigned WordTable (void); +uint32_t WordTable (void); /* Output a table of words */ -unsigned DWordTable (void); +uint32_t DWordTable (void); /* Output a table of double words */ -unsigned AddrTable (void); +uint32_t AddrTable (void); /* Output a table of addresses */ -unsigned RtsTable (void); +uint32_t RtsTable (void); /* Output a table of RTS addresses (address - 1) */ -unsigned TextTable (void); +uint32_t TextTable (void); /* Output a table of text messages */ diff --git a/src/da65/global.c b/src/da65/global.c index e258aecddb..7e5cabf545 100644 --- a/src/da65/global.c +++ b/src/da65/global.c @@ -58,7 +58,8 @@ unsigned char UseHexOffs = 0; /* Use hexadecimal label offsets */ unsigned char PassCount = 2; /* How many passed do we do? */ signed char NewlineAfterJMP = -1; /* Add a newline after a JMP insn? */ signed char NewlineAfterRTS = -1; /* Add a newline after a RTS insn? */ -long StartAddr = -1L; /* Start/load address of the program */ +unsigned char HaveStartAddr = 0; /* Flag for start address given */ +uint32_t StartAddr = 0; /* Start/load address of the program */ unsigned char SyncLines = 0; /* Accept line markers in the info file */ long InputOffs = -1L; /* Offset into input file */ long InputSize = -1L; /* Number of bytes to read from input */ diff --git a/src/da65/global.h b/src/da65/global.h index c85c7a79e4..2e558d6a91 100644 --- a/src/da65/global.h +++ b/src/da65/global.h @@ -38,6 +38,10 @@ +#include + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -59,7 +63,8 @@ extern unsigned char UseHexOffs; /* Use hexadecimal label offsets */ extern unsigned char PassCount; /* How many passed do we do? */ extern signed char NewlineAfterJMP;/* Add a newline after a JMP insn? */ extern signed char NewlineAfterRTS;/* Add a newline after a RTS insn? */ -extern long StartAddr; /* Start/load address of the program */ +extern unsigned char HaveStartAddr; /* Flag for start address given */ +extern uint32_t StartAddr; /* Start/load address of the program */ extern unsigned char SyncLines; /* Accept line markers in the info file */ extern long InputOffs; /* Offset into input file */ extern long InputSize; /* Number of bytes to read from input */ diff --git a/src/da65/handler.c b/src/da65/handler.c index 84229594f0..836dc28845 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -33,6 +33,7 @@ +#include #include /* common */ @@ -95,7 +96,7 @@ static void OneLine (const OpcDesc* D, const char* Arg, ...) -static const char* GetAbsOverride (unsigned Flags, unsigned Addr) +static const char* GetAbsOverride (unsigned Flags, uint32_t Addr) /* If the instruction requires an abs override modifier, return the necessary ** string, otherwise return the empty string. */ @@ -111,7 +112,7 @@ static const char* GetAbsOverride (unsigned Flags, unsigned Addr) -static const char* GetAddrArg (unsigned Flags, unsigned Addr) +static const char* GetAddrArg (unsigned Flags, uint32_t Addr) /* Return an address argument - a label if we have one, or the address itself */ { const char* Label = 0; @@ -123,11 +124,11 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr) } else { static char Buf [32]; if (Addr < 0x100) { - xsprintf (Buf, sizeof (Buf), "$%02X", Addr); + xsprintf (Buf, sizeof (Buf), "$%02" PRIX32, Addr); } else if (Addr < 0x10000) { - xsprintf (Buf, sizeof (Buf), "$%04X", Addr); + xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr); } else { - xsprintf (Buf, sizeof (Buf), "$%06X", Addr); + xsprintf (Buf, sizeof (Buf), "$%06" PRIX32, Addr); } return Buf; } @@ -135,7 +136,7 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr) -static void GenerateLabel (unsigned Flags, unsigned Addr) +static void GenerateLabel (unsigned Flags, uint32_t Addr) /* Generate a label in pass one if requested */ { /* Generate labels in pass #1, and only if we don't have a label already */ @@ -305,7 +306,7 @@ void OH_Implicit_42_45GS02 (const OpcDesc* D) void OH_Immediate (const OpcDesc* D) { - OneLine (D, "#$%02X", GetCodeByte (PC+1)); + OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1)); } @@ -313,9 +314,9 @@ void OH_Immediate (const OpcDesc* D) void OH_Immediate65816M (const OpcDesc* D) { if (GetAttr (PC) & atMem16) { - OneLine (D, "#$%04X", GetCodeWord (PC+1)); + OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1)); } else { - OneLine (D, "#$%02X", GetCodeByte (PC+1)); + OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1)); } } @@ -324,9 +325,9 @@ void OH_Immediate65816M (const OpcDesc* D) void OH_Immediate65816X (const OpcDesc* D) { if (GetAttr (PC) & atIdx16) { - OneLine (D, "#$%04X", GetCodeWord (PC+1)); + OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1)); } else { - OneLine (D, "#$%02X", GetCodeByte (PC+1)); + OneLine (D, "#$%02" PRIX8, GetCodeByte (PC+1)); } } @@ -334,7 +335,7 @@ void OH_Immediate65816X (const OpcDesc* D) void OH_ImmediateWord (const OpcDesc* D) { - OneLine (D, "#$%04X", GetCodeWord (PC+1)); + OneLine (D, "#$%04" PRIX16, GetCodeWord (PC+1)); } @@ -342,7 +343,7 @@ void OH_ImmediateWord (const OpcDesc* D) void OH_Direct (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -370,7 +371,7 @@ void OH_Direct_Q (const OpcDesc* D) void OH_DirectX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -398,7 +399,7 @@ void OH_DirectX_Q (const OpcDesc* D) void OH_DirectY (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -412,7 +413,7 @@ void OH_DirectY (const OpcDesc* D) void OH_Absolute (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -440,7 +441,7 @@ void OH_Absolute_Q (const OpcDesc* D) void OH_AbsoluteX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -468,7 +469,7 @@ void OH_AbsoluteX_Q (const OpcDesc* D) void OH_AbsoluteY (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -482,7 +483,7 @@ void OH_AbsoluteY (const OpcDesc* D) void OH_AbsoluteLong (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeLongAddr (PC+1); + uint32_t Addr = GetCodeLongAddr (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -496,7 +497,7 @@ void OH_AbsoluteLong (const OpcDesc* D attribute ((unused))) void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeLongAddr (PC+1); + uint32_t Addr = GetCodeLongAddr (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -513,7 +514,7 @@ void OH_Relative (const OpcDesc* D) signed char Offs = GetCodeByte (PC+1); /* Calculate the target address */ - unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF; + uint32_t Addr = (((int) PC+2) + Offs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -535,7 +536,7 @@ void OH_RelativeLong (const OpcDesc* D attribute ((unused))) signed short Offs = GetCodeWord (PC+1); /* Calculate the target address */ - unsigned Addr = (((int) PC+3) + Offs) & 0xFFFF; + uint32_t Addr = (((int) PC+3) + Offs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -552,7 +553,7 @@ void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused))) signed short Offs = GetCodeWord (PC+1); /* Calculate the target address */ - unsigned Addr = (((int) PC+2) + Offs) & 0xFFFF; + uint32_t Addr = (((int) PC+2) + Offs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -566,7 +567,7 @@ void OH_RelativeLong4510 (const OpcDesc* D attribute ((unused))) void OH_DirectIndirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -580,7 +581,7 @@ void OH_DirectIndirect (const OpcDesc* D) void OH_DirectIndirectY (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -594,7 +595,7 @@ void OH_DirectIndirectY (const OpcDesc* D) void OH_DirectIndirectZ (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -622,7 +623,7 @@ void OH_DirectIndirectZ_Q (const OpcDesc* D) void OH_DirectXIndirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -636,7 +637,7 @@ void OH_DirectXIndirect (const OpcDesc* D) void OH_AbsoluteIndirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -652,11 +653,11 @@ void OH_BitBranch (const OpcDesc* D) char* BranchLabel; /* Get the operands */ - unsigned char TestAddr = GetCodeByte (PC+1); - signed char BranchOffs = GetCodeByte (PC+2); + uint32_t TestAddr = GetCodeByte (PC+1); + int8_t BranchOffs = GetCodeByte (PC+2); /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + uint32_t 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 @@ -686,11 +687,11 @@ void OH_BitBranch_m740 (const OpcDesc* D) */ { /* unsigned Bit = GetCodeByte (PC) >> 5; */ - unsigned Addr = GetCodeByte (PC+1); - signed char BranchOffs = GetCodeByte (PC+2); + uint32_t Addr = GetCodeByte (PC+1); + int8_t BranchOffs = (int8_t) GetCodeByte (PC+2); /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -700,10 +701,12 @@ void OH_BitBranch_m740 (const OpcDesc* D) OneLine (D, "%s, %s", GetAddrArg (D->Flags, Addr), GetAddrArg (flLabel, BranchAddr)); } + + void OH_ImmediateDirect (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+2); + uint32_t Addr = GetCodeByte (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -717,7 +720,7 @@ void OH_ImmediateDirect (const OpcDesc* D) void OH_ImmediateDirectX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+2); + uint32_t Addr = GetCodeByte (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -731,7 +734,7 @@ void OH_ImmediateDirectX (const OpcDesc* D) void OH_ImmediateAbsolute (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+2); + uint32_t Addr = GetCodeWord (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -745,7 +748,7 @@ void OH_ImmediateAbsolute (const OpcDesc* D) void OH_ImmediateAbsoluteX (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+2); + uint32_t Addr = GetCodeWord (PC+2); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -790,7 +793,7 @@ void OH_StackRelativeIndirectY4510 (const OpcDesc* D attribute ((unused))) void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -804,7 +807,7 @@ void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused))) void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -820,9 +823,9 @@ void OH_BlockMove (const OpcDesc* D) char* DstLabel; /* Get source operand */ - unsigned Src = GetCodeWord (PC+1); + uint32_t Src = GetCodeWord (PC+1); /* Get destination operand */ - unsigned Dst = GetCodeWord (PC+3); + uint32_t Dst = GetCodeWord (PC+3); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Src); @@ -835,7 +838,7 @@ void OH_BlockMove (const OpcDesc* D) DstLabel = xstrdup (GetAddrArg (D->Flags, Dst)); /* Output the line */ - OneLine (D, "%s%s,%s%s,$%04X", + OneLine (D, "%s%s,%s%s,$%04" PRIX16, GetAbsOverride (D->Flags, Src), GetAddrArg (D->Flags, Src), GetAbsOverride (D->Flags, Dst), DstLabel, GetCodeWord (PC+5)); @@ -848,12 +851,12 @@ void OH_BlockMove (const OpcDesc* D) void OH_BlockMove65816 (const OpcDesc* D) { /* Get source operand */ - unsigned Src = GetCodeByte (PC+2); + uint8_t Src = GetCodeByte (PC+2); /* Get destination operand */ - unsigned Dst = GetCodeByte (PC+1); + uint8_t Dst = GetCodeByte (PC+1); /* Output the line */ - OneLine (D, "#$%02X, #$%02X", Src, Dst); + OneLine (D, "#$%02" PRIX8 ", #$%02" PRIX8, Src, Dst); } @@ -861,7 +864,7 @@ void OH_BlockMove65816 (const OpcDesc* D) void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused))) { /* Get the operand */ - unsigned Addr = GetCodeWord (PC+1); + uint32_t Addr = GetCodeWord (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -875,7 +878,7 @@ void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused))) void OH_DirectImmediate (const OpcDesc* D) { /* Get the operand */ - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -891,7 +894,7 @@ void OH_ZeroPageBit (const OpcDesc* D) ** NOTE: currently is part of the instruction */ { - unsigned Addr = GetCodeByte (PC+1); + uint32_t Addr = GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -917,10 +920,10 @@ void OH_AccumulatorBitBranch (const OpcDesc* D) ** NOTE: currently is part of the instruction */ { - signed char BranchOffs = GetCodeByte (PC+1); + int8_t BranchOffs = GetCodeByte (PC+1); /* Calculate the target address for the branch */ - unsigned BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; + uint32_t BranchAddr = (((int) PC+3) + BranchOffs) & 0xFFFF; /* Generate labels in pass 1 */ GenerateLabel (flLabel, BranchAddr); @@ -945,7 +948,7 @@ void OH_SpecialPage (const OpcDesc* D) /* m740 "special page" address mode */ { /* Get the operand */ - unsigned Addr = 0xFF00 + GetCodeByte (PC+1); + uint32_t Addr = 0xFF00 + GetCodeByte (PC+1); /* Generate a label in pass 1 */ GenerateLabel (D->Flags, Addr); @@ -1004,16 +1007,13 @@ void OH_JsrAbsolute (const OpcDesc* D) unsigned ParamSize = SubroutineParamSize[GetCodeWord (PC+1)]; OH_Absolute (D); if (ParamSize > 0) { - unsigned RemainingBytes; - unsigned BytesLeft; + uint32_t RemainingBytes; + uint32_t BytesLeft; PC += D->Size; RemainingBytes = GetRemainingBytes (); - if (RemainingBytes < ParamSize) { - ParamSize = RemainingBytes; - } - BytesLeft = ParamSize; + BytesLeft = (RemainingBytes < ParamSize)? RemainingBytes : ParamSize; while (BytesLeft > 0) { - unsigned Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft; + uint32_t Chunk = (BytesLeft > BytesPerLine) ? BytesPerLine : BytesLeft; DataByteLine (Chunk); BytesLeft -= Chunk; PC += Chunk; @@ -1024,7 +1024,7 @@ void OH_JsrAbsolute (const OpcDesc* D) -void SetSubroutineParamSize (unsigned Addr, unsigned Size) +void SetSubroutineParamSize (uint32_t Addr, unsigned Size) { SubroutineParamSize[Addr] = Size; } diff --git a/src/da65/handler.h b/src/da65/handler.h index fc82595c67..91c1562cd1 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -38,6 +38,8 @@ +#include + /* common */ #include "attrib.h" @@ -119,7 +121,7 @@ void OH_JmpAbsoluteIndirect (const OpcDesc* D); void OH_JmpAbsoluteXIndirect (const OpcDesc* D); void OH_JsrAbsolute (const OpcDesc*); -void SetSubroutineParamSize (unsigned Addr, unsigned Size); +void SetSubroutineParamSize (uint32_t Addr, unsigned Size); /* End of handler.h */ diff --git a/src/da65/infofile.c b/src/da65/infofile.c index fbf367cc99..67e7df1d9f 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -219,7 +219,7 @@ static void GlobalSection (void) case INFOTOK_ARGUMENT_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_ACOL, MAX_ACOL); + InfoRangeCheck ("ARGUMENTCOLUMN", MIN_ACOL, MAX_ACOL); ACol = InfoIVal; InfoNextTok (); break; @@ -227,7 +227,7 @@ static void GlobalSection (void) case INFOTOK_COMMENT_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_CCOL, MAX_CCOL); + InfoRangeCheck ("COMMENTCOLUMN", MIN_CCOL, MAX_CCOL); CCol = InfoIVal; InfoNextTok (); break; @@ -235,7 +235,7 @@ static void GlobalSection (void) case INFOTOK_COMMENTS: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS); + InfoRangeCheck ("COMMENTS", MIN_COMMENTS, MAX_COMMENTS); Comments = InfoIVal; InfoNextTok (); break; @@ -281,7 +281,7 @@ static void GlobalSection (void) case INFOTOK_INPUTSIZE: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (1, 0x10000); + InfoRangeCheck ("INPUTSIZE", 1, 0x10000); InputSize = InfoIVal; InfoNextTok (); break; @@ -289,7 +289,7 @@ static void GlobalSection (void) case INFOTOK_LABELBREAK: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0, UCHAR_MAX); + InfoRangeCheck ("LABELBREAK", 0, UCHAR_MAX); LBreak = (unsigned char) InfoIVal; InfoNextTok (); break; @@ -297,7 +297,7 @@ static void GlobalSection (void) case INFOTOK_MNEMONIC_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_MCOL, MAX_MCOL); + InfoRangeCheck ("MNEMONICCOLUMN", MIN_MCOL, MAX_MCOL); MCol = InfoIVal; InfoNextTok (); break; @@ -336,7 +336,7 @@ static void GlobalSection (void) InfoNextTok (); InfoAssureInt (); if (InfoIVal != 0) { - InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN); + InfoRangeCheck ("PAGELENGTH", MIN_PAGE_LEN, MAX_PAGE_LEN); } PageLength = InfoIVal; InfoNextTok (); @@ -345,15 +345,16 @@ static void GlobalSection (void) case INFOTOK_STARTADDR: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0x0000, 0xFFFF); + InfoRangeCheck ("STARTADDR", 0x0000, 0xFFFF); StartAddr = InfoIVal; + HaveStartAddr = 1; InfoNextTok (); break; case INFOTOK_TEXT_COLUMN: InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (MIN_TCOL, MAX_TCOL); + InfoRangeCheck ("TEXTCOLUMN", MIN_TCOL, MAX_TCOL); TCol = InfoIVal; InfoNextTok (); break; @@ -413,7 +414,7 @@ static void LabelSection (void) InfoError ("Value already given"); } InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); + InfoRangeCheck ("ADDR", 0, 0xFFFF); Value = InfoIVal; InfoNextTok (); break; @@ -447,7 +448,7 @@ static void LabelSection (void) InfoError ("Size already given"); } InfoAssureInt (); - InfoRangeCheck (1, 0x10000); + InfoRangeCheck ("SIZE", 1, 0x10000); Size = InfoIVal; InfoNextTok (); break; @@ -458,7 +459,7 @@ static void LabelSection (void) InfoError ("ParamSize already given"); } InfoAssureInt (); - InfoRangeCheck (1, 0x10000); + InfoRangeCheck ("PARAMSIZE", 1, 0x10000); ParamSize = InfoIVal; InfoNextTok (); break; @@ -554,13 +555,13 @@ static void RangeSection (void) tComment = 0x10, tAddrMode = 0x20, tUnit = 0x40, - tNeeded = (tStart | tEnd | tType) + tNeeded = (tStart | tEnd | tType) }; unsigned Attributes = tNone; /* Locals - initialize to avoid gcc warnings */ - unsigned Start = 0; - unsigned End = 0; + uint32_t Start = 0; + uint32_t End = 0; unsigned char Type = 0; unsigned AddrMode = 0; char* Name = 0; @@ -599,17 +600,18 @@ static void RangeSection (void) case INFOTOK_END: AddAttr ("END", &Attributes, tEnd); InfoNextTok (); - if (InfoTok == INFOTOK_OFFSET_INTCON) { - InfoRangeCheck (0x0000, 0xFFFF); - if (!(Attributes & tStart)) + InfoRangeCheck ("END", 0x0000, 0xFFFF); + if ((Attributes & tStart) == 0) { InfoError ("When using End with an offset, Start must be specified before"); + } End = Start + InfoIVal - 1; - if (End > 0xFFFF) + if (End > 0xFFFF) { InfoError ("Range error"); + } } else { InfoAssureInt (); - InfoRangeCheck (0x0000, 0xFFFF); + InfoRangeCheck ("END", 0x0000, 0xFFFF); End = InfoIVal; } InfoNextTok (); @@ -631,7 +633,7 @@ static void RangeSection (void) AddAttr ("START", &Attributes, tStart); InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0x0000, 0xFFFF); + InfoRangeCheck ("START", 0x0000, 0xFFFF); Start = InfoIVal; InfoNextTok (); break; @@ -689,7 +691,7 @@ static void RangeSection (void) AddAttr ("UNIT", &Attributes, tUnit); InfoNextTok (); InfoAssureInt (); - InfoRangeCheck (0x0002, 0xFFFF); + InfoRangeCheck ("UNIT", 0x0002, 0xFFFF); Unit = InfoIVal; InfoNextTok (); break; @@ -807,7 +809,7 @@ static void SegmentSection (void) InfoError ("Value already given"); } InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); + InfoRangeCheck ("END", 0, 0xFFFF); End = InfoIVal; InfoNextTok (); break; @@ -828,7 +830,7 @@ static void SegmentSection (void) InfoError ("Value already given"); } InfoAssureInt (); - InfoRangeCheck (0, 0xFFFF); + InfoRangeCheck ("START", 0, 0xFFFF); Start = InfoIVal; InfoNextTok (); break; diff --git a/src/da65/labels.c b/src/da65/labels.c index 4cae0316a7..3a4cdd2d7f 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -33,15 +33,17 @@ +#include #include #include /* common */ +#include "coll.h" +#include "strbuf.h" #include "xmalloc.h" #include "xsprintf.h" /* da65 */ -#include "attrtab.h" #include "code.h" #include "comments.h" #include "error.h" @@ -57,51 +59,104 @@ -/* Symbol table */ -static const char* SymTab[0x10000]; +/* Label structure how it is found in the label table */ +typedef struct Label Label; +struct Label { + struct Label* Next; /* Next entry in linked list */ + uint32_t Addr; /* The full address */ + char Name[1]; /* Symbol name, dynamically allocated */ +}; -/* 65816 symbol table */ -#define MAX_LONG_LABELS 256 -static const char* LongSymVal[MAX_LONG_LABELS]; -static unsigned LongSymAddr[MAX_LONG_LABELS]; -static unsigned LongLabelsUsed; +/* Labels use a hash table and a linear list for collision resolution. The +** hash function is easy and effective. It evaluates just the lower bits of +** the address. +*/ +#define LABEL_HASH_SIZE 4096u /* Must be power of two */ +static Label* LabelTab[LABEL_HASH_SIZE]; /*****************************************************************************/ -/* Code */ +/* struct Label */ /*****************************************************************************/ -static const char* MakeLabelName (unsigned Addr) -/* Make the default label name from the given address and return it in a -** static buffer. -*/ +static Label* NewLabel (uint32_t Addr, const char* Name) +/* Create a new label structure and return it */ { - static char LabelBuf [32]; - xsprintf (LabelBuf, sizeof (LabelBuf), - IsLongAddr (Addr) ? "L%06X" : "L%04X", Addr); - return LabelBuf; + /* Get the length of the name */ + unsigned Len = strlen (Name); + + /* Create a new label */ + Label* L = xmalloc (sizeof (Label) + Len); + + /* Fill in the data */ + L->Next = 0; + L->Addr = Addr; + memcpy (L->Name, Name, Len + 1); + + /* Return the label just created */ + return L; } -static unsigned FindLongIndex (unsigned Addr) +static uint32_t GetLabelHash (uint32_t Addr) +/* Get the hash for a label at the given address */ { - unsigned i; - for (i = 0; i < LongLabelsUsed; i++) { - if (LongSymAddr[i] == Addr) { - return i; + return (Addr & (LABEL_HASH_SIZE - 1)); +} + + + +static Label* FindLabel (uint32_t Addr) +/* Search for a label for the given address and return it. Returns NULL if +** no label exists for the address. +*/ +{ + Label* L = LabelTab[GetLabelHash (Addr)]; + while (L) { + if (L->Addr == Addr) { + break; } + L = L->Next; } + return L; +} + - return -1; + +static void InsertLabel (Label* L) +/* Insert a label into the tables */ +{ + /* Insert into hash table */ + uint32_t Hash = GetLabelHash (L->Addr); + L->Next = LabelTab[Hash]; + LabelTab[Hash] = L; } -static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +static const char* MakeLabelName (uint32_t Addr) +/* Make the default label name from the given address and return it in a +** static buffer. +*/ +{ + static char LabelBuf [32]; + xsprintf (LabelBuf, sizeof (LabelBuf), "L%04" PRIX32, Addr); + return LabelBuf; +} + + + +static void AddLabel (uint32_t Addr, attr_t Attr, const char* Name) /* Add a label */ { /* Get an existing label attribute */ @@ -109,43 +164,25 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) /* Must not have two symbols for one address */ if (ExistingAttr != atNoLabel) { - /* Allow redefinition if identical. Beware: Unnamed labels don't - ** have a name (you guessed that, didn't you?). + /* Allow redefinition if identical. Beware: Unnamed labels do not + ** have an entry in the label table. */ - if (IsLongAddr (Addr)) { - const unsigned i = FindLongIndex (Addr); - if (ExistingAttr == Attr && - ((Name == 0 && LongSymVal[i] == 0) || - (Name != 0 && LongSymVal[i] != 0 && - strcmp (LongSymVal[i], Name) == 0))) { - return; - } - Error ("Duplicate label for address $%06X (%s): '%s'", Addr, - LongSymVal[i] == 0 ? "" : LongSymVal[i], - Name == 0 ? "" : Name); - } else { - if (ExistingAttr == Attr && - ((Name == 0 && SymTab[Addr] == 0) || - (Name != 0 && SymTab[Addr] != 0 && - strcmp (SymTab[Addr], Name) == 0))) { - return; - } - Error ("Duplicate label for address $%04X (%s): '%s'", Addr, - SymTab[Addr] == 0 ? "" : SymTab[Addr], - Name == 0 ? "" : Name); + Label* L = FindLabel (Addr); + if (ExistingAttr == Attr && + ((Name == 0 && L == 0) || + (Name != 0 && L != 0 && strcmp (Name, L->Name) == 0))) { + return; } + Error ("Duplicate label for address $%04X (%s): '%s'", Addr, + L? L->Name : "", + Name? Name : ""); } - /* Create a new label (xstrdup will return NULL if input NULL) */ - if (IsLongAddr (Addr)) { - if (LongLabelsUsed >= MAX_LONG_LABELS) { - Error ("Too many long labels"); - } - LongSymAddr[LongLabelsUsed] = Addr; - LongSymVal[LongLabelsUsed] = xstrdup (Name); - LongLabelsUsed++; - } else { - SymTab[Addr] = xstrdup (Name); + /* If this is not an unnamed label, create a new label entry and + ** insert it. + */ + if (Name != 0) { + InsertLabel (NewLabel (Addr, Name)); } /* Remember the attribute */ @@ -154,7 +191,7 @@ static void AddLabel (unsigned Addr, attr_t Attr, const char* Name) -void AddIntLabel (unsigned Addr) +void AddIntLabel (uint32_t Addr) /* Add an internal label using the address to generate the name. */ { AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); @@ -162,7 +199,7 @@ void AddIntLabel (unsigned Addr) -void AddExtLabel (unsigned Addr, const char* Name) +void AddExtLabel (uint32_t Addr, const char* Name) /* Add an external label */ { AddLabel (Addr, atExtLabel, Name); @@ -170,7 +207,7 @@ void AddExtLabel (unsigned Addr, const char* Name) -void AddUnnamedLabel (unsigned Addr) +void AddUnnamedLabel (uint32_t Addr) /* Add an unnamed label */ { AddLabel (Addr, atUnnamedLabel, 0); @@ -178,11 +215,27 @@ void AddUnnamedLabel (unsigned Addr) -void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs) +void AddDepLabel (uint32_t Addr, attr_t Attr, const char* BaseName, unsigned Offs) /* Add a dependent label at the given address using "basename+Offs" as the new ** name. */ { + /* Create the new name in the buffer */ + StrBuf Name = AUTO_STRBUF_INITIALIZER; + if (UseHexOffs) { + SB_Printf (&Name, "%s+$%02X", BaseName, Offs); + } else { + SB_Printf (&Name, "%s+%u", BaseName, Offs); + } + + /* Define the labels */ + AddLabel (Addr, Attr | atDepLabel, SB_GetConstBuf (&Name)); + + /* Free the name buffer */ + SB_Done (&Name); + + + /* Allocate memory for the dependent label name */ unsigned NameLen = strlen (BaseName); char* DepName = xmalloc (NameLen + 7); /* "+$ABCD\0" */ @@ -203,7 +256,7 @@ void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Off -static void AddLabelRange (unsigned Addr, attr_t Attr, +static void AddLabelRange (uint32_t Addr, attr_t Attr, const char* Name, unsigned Count) /* Add a label for a range. The first entry gets the label "Name" while the ** others get "Name+offs". @@ -241,7 +294,7 @@ static void AddLabelRange (unsigned Addr, attr_t Attr, -void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count) +void AddIntLabelRange (uint32_t Addr, const char* Name, unsigned Count) /* Add an internal label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ @@ -252,7 +305,7 @@ void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count) -void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count) +void AddExtLabelRange (uint32_t Addr, const char* Name, unsigned Count) /* Add an external label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ @@ -263,7 +316,7 @@ void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count) -int HaveLabel (unsigned Addr) +int HaveLabel (uint32_t Addr) /* Check if there is a label for the given address */ { /* Check for a label */ @@ -272,7 +325,7 @@ int HaveLabel (unsigned Addr) -int MustDefLabel (unsigned Addr) +int MustDefLabel (uint32_t Addr) /* Return true if we must define a label for this address, that is, if there ** is a label at this address, and it is an external or internal label. */ @@ -286,7 +339,7 @@ int MustDefLabel (unsigned Addr) -const char* GetLabelName (unsigned Addr) +const char* GetLabelName (uint32_t Addr) /* Return the label name for an address */ { /* Get the label attribute */ @@ -297,19 +350,16 @@ const char* GetLabelName (unsigned Addr) */ if (A == atUnnamedLabel) { return ""; - } else if (IsLongAddr (Addr)) { - /* Return the label if any */ - const unsigned i = FindLongIndex (Addr); - return i < LongLabelsUsed ? LongSymVal[i] : NULL; } else { /* Return the label if any */ - return SymTab[Addr]; + const Label* L = FindLabel (Addr); + return L? L->Name : 0; } } -const char* GetLabel (unsigned Addr, unsigned RefFrom) +const char* GetLabel (uint32_t Addr, uint32_t RefFrom) /* Return the label name for an address, as it is used in a label reference. ** RefFrom is the address the label is referenced from. This is needed in case ** of unnamed labels, to determine the name. @@ -339,7 +389,7 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) */ if (Addr <= RefFrom) { /* Search backwards */ - unsigned I = RefFrom; + uint32_t I = RefFrom; while (Addr < I) { --I; A = GetLabelAttr (I); @@ -357,7 +407,7 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) } else { /* Search forwards */ - unsigned I = RefFrom; + uint32_t I = RefFrom; while (Addr > I) { ++I; A = GetLabelAttr (I); @@ -373,26 +423,22 @@ const char* GetLabel (unsigned Addr, unsigned RefFrom) /* Return the label name */ return FwdLabels[Count-1]; } - - } else if (IsLongAddr (Addr)) { - /* Return the label if any */ - const unsigned i = FindLongIndex (Addr); - return i < LongLabelsUsed ? LongSymVal[i] : NULL; } else { /* Return the label if any */ - return SymTab[Addr]; + const Label* L = FindLabel (Addr); + return L? L->Name : 0; } } -void ForwardLabel (unsigned Offs) +void ForwardLabel (uint32_t Offs) /* If necessary, output a forward label, one that is within the next few ** bytes and is therefore output as "label = * + x". */ { /* Calculate the actual address */ - unsigned long Addr = PC + Offs; + uint32_t Addr = PC + Offs; /* Get the type of the label */ attr_t A = GetLabelAttr (Addr); @@ -406,7 +452,7 @@ void ForwardLabel (unsigned Offs) ** an error. */ if (A == atUnnamedLabel) { - Error ("Cannot define unnamed label at address $%04lX", Addr); + Error ("Cannot define unnamed label at address $%04" PRIX32, Addr); } /* Output the label */ @@ -415,24 +461,33 @@ void ForwardLabel (unsigned Offs) -static void DefOutOfRangeLabel (unsigned long Addr) +static int CompareLabels (void* Data attribute ((unused)), + const void* L1, const void* L2) +/* Compare functions for sorting the out-of-range labels */ +{ + if (((const Label*) L1)->Addr < ((const Label*) L2)->Addr) { + return -1; + } else if (((const Label*) L1)->Addr > ((const Label*) L2)->Addr) { + return 1; + } else { + return 0; + } +} + + + +static void DefOutOfRangeLabel (const Label* L) /* Define one label that is outside code range. */ { - switch (GetLabelAttr (Addr)) { + switch (GetLabelAttr (L->Addr)) { case atIntLabel: case atExtLabel: - if (IsLongAddr (Addr)) { - const unsigned i = FindLongIndex (Addr); - DefConst (i < LongLabelsUsed ? LongSymVal[i] : NULL, - GetComment (Addr), Addr); - } else { - DefConst (SymTab[Addr], GetComment (Addr), Addr); - } + DefConst (L->Name, GetComment (L->Addr), L->Addr); break; case atUnnamedLabel: - Error ("Cannot define unnamed label at address $%04lX", Addr); + Error ("Cannot define unnamed label at address $%04" PRIX32, L->Addr); break; default: @@ -446,34 +501,40 @@ static void DefOutOfRangeLabel (unsigned long Addr) void DefOutOfRangeLabels (void) /* Output any labels that are out of the loaded code range */ { - unsigned long Addr; - unsigned i; - - SeparatorLine (); - - /* Low range */ - Addr = 0; - while (Addr < CodeStart) { - DefOutOfRangeLabel (Addr++); - } - - /* Skip areas in code range */ - while (Addr <= CodeEnd) { - if (GetStyleAttr (Addr) == atSkip) { - DefOutOfRangeLabel (Addr); + unsigned I; + + /* This requires somewhat more effort since the labels output should be + ** sorted by address for better readability. This is not directly + ** possible when using a hash table, so an intermediate data structure + ** is required. It is not possible to collect out-of-range labels while + ** generating them, since they may come from an info file and where added + ** while no input file was read. Which means it cannot be determined at + ** that point if they're out-of-range or not. + */ + Collection Labels = AUTO_COLLECTION_INITIALIZER; + CollGrow (&Labels, 128); + + /* Walk over the hash and copy all out-of-range labels */ + for (I = 0; I < LABEL_HASH_SIZE; ++I) { + Label* L = LabelTab[I]; + while (L) { + if (L->Addr < CodeStart || L->Addr > CodeEnd) { + CollAppend (&Labels, L); + } + L = L->Next; } - ++Addr; } - /* High range */ - while (Addr < 0x10000) { - DefOutOfRangeLabel (Addr++); - } + /* Sort the out-of-range labels by address */ + CollSort (&Labels, CompareLabels, 0); - /* 65816 long range */ - for (i = 0; i < LongLabelsUsed; i++) { - DefOutOfRangeLabel (LongSymAddr[i]); + /* Output the labels */ + SeparatorLine (); + for (I = 0; I < CollCount (&Labels); ++I) { + DefOutOfRangeLabel (CollConstAt (&Labels, I)); } - SeparatorLine (); + + /* Free allocated storage */ + DoneCollection (&Labels); } diff --git a/src/da65/labels.h b/src/da65/labels.h index c4b52774ae..37f2daeab9 100644 --- a/src/da65/labels.h +++ b/src/da65/labels.h @@ -38,6 +38,9 @@ +#include + +/* da65 */ #include "attrtab.h" @@ -48,42 +51,42 @@ -void AddIntLabel (unsigned Addr); +void AddIntLabel (uint32_t Addr); /* Add an internal label using the address to generate the name. */ -void AddExtLabel (unsigned Addr, const char* Name); +void AddExtLabel (uint32_t Addr, const char* Name); /* Add an external label */ -void AddUnnamedLabel (unsigned Addr); +void AddUnnamedLabel (uint32_t Addr); /* Add an unnamed label */ -void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs); +void AddDepLabel (uint32_t Addr, attr_t Attr, const char* BaseName, unsigned Offs); /* Add a dependent label at the given address using "base name+Offs" as the new ** name. */ -void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count); +void AddIntLabelRange (uint32_t Addr, const char* Name, unsigned Count); /* Add an internal label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ -void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count); +void AddExtLabelRange (uint32_t Addr, const char* Name, unsigned Count); /* Add an external label for a range. The first entry gets the label "Name" ** while the others get "Name+offs". */ -int HaveLabel (unsigned Addr); +int HaveLabel (uint32_t Addr); /* Check if there is a label for the given address */ -int MustDefLabel (unsigned Addr); +int MustDefLabel (uint32_t Addr); /* Return true if we must define a label for this address, that is, if there ** is a label at this address, and it is an external or internal label. */ -const char* GetLabelName (unsigned Addr); +const char* GetLabelName (uint32_t Addr); /* Return the label name for an address */ -const char* GetLabel (unsigned Addr, unsigned RefFrom); +const char* GetLabel (uint32_t Addr, uint32_t RefFrom); /* Return the label name for an address, as it is used in a label reference. ** RefFrom is the address the label is referenced from. This is needed in case ** of unnamed labels, to determine the name. diff --git a/src/da65/main.c b/src/da65/main.c index 545cc657b6..91eecd94fe 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -313,7 +313,8 @@ static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg static void OptStartAddr (const char* Opt, const char* Arg) /* Set the default start address */ { - StartAddr = CvtNumber (Opt, Arg); + StartAddr = (uint32_t) CvtNumber (Opt, Arg); + HaveStartAddr = 1; } @@ -409,11 +410,11 @@ static unsigned HandleChangedLength(const OpcDesc* D, unsigned PC) static void OneOpcode (unsigned RemainingBytes) /* Disassemble one opcode */ { - unsigned I; - unsigned OldPC = PC; + uint32_t I; + uint32_t OldPC = PC; /* Get the opcode from the current address */ - unsigned char OPC = GetCodeByte (PC); + uint8_t OPC = GetCodeByte (PC); /* Get the opcode description for the opcode byte */ const OpcDesc* D = &OpcTable[OPC]; @@ -574,7 +575,7 @@ static void OneOpcode (unsigned RemainingBytes) static void OnePass (void) /* Make one pass through the code */ { - unsigned Count; + uint32_t Count; PrevAddrMode = 0; diff --git a/src/da65/output.c b/src/da65/output.c index 8e786e130e..bc5f7d5c22 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -33,6 +33,7 @@ +#include #include #include #include @@ -208,13 +209,13 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs) -void DefConst (const char* Name, const char* Comment, unsigned Addr) +void DefConst (const char* Name, const char* Comment, uint32_t Addr) /* Define an address constant */ { if (Pass == PassCount) { Output ("%s", Name); Indent (ACol); - Output (":= $%04X", Addr); + Output (":= $%04" PRIX32, Addr); if (Comment) { Indent (CCol); Output ("; %s", Comment); @@ -225,19 +226,19 @@ void DefConst (const char* Name, const char* Comment, unsigned Addr) -void DataByteLine (unsigned ByteCount) +void DataByteLine (uint32_t ByteCount) /* Output a line with bytes */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".byte"); Indent (ACol); for (I = 0; I < ByteCount; ++I) { if (I > 0) { - Output (",$%02X", CodeBuf[PC+I]); + Output (",$%02" PRIX8, CodeBuf[PC+I]); } else { - Output ("$%02X", CodeBuf[PC+I]); + Output ("$%02" PRIX8, CodeBuf[PC+I]); } } LineComment (PC, ByteCount); @@ -246,19 +247,19 @@ void DataByteLine (unsigned ByteCount) -void DataDByteLine (unsigned ByteCount) +void DataDByteLine (uint32_t ByteCount) /* Output a line with dbytes */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".dbyt"); Indent (ACol); for (I = 0; I < ByteCount; I += 2) { if (I > 0) { - Output (",$%04X", GetCodeDByte (PC+I)); + Output (",$%04" PRIX16, GetCodeDByte (PC+I)); } else { - Output ("$%04X", GetCodeDByte (PC+I)); + Output ("$%04" PRIX16, GetCodeDByte (PC+I)); } } LineComment (PC, ByteCount); @@ -267,19 +268,19 @@ void DataDByteLine (unsigned ByteCount) -void DataWordLine (unsigned ByteCount) +void DataWordLine (uint32_t ByteCount) /* Output a line with words */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".word"); Indent (ACol); for (I = 0; I < ByteCount; I += 2) { if (I > 0) { - Output (",$%04X", GetCodeWord (PC+I)); + Output (",$%04" PRIX16, GetCodeWord (PC+I)); } else { - Output ("$%04X", GetCodeWord (PC+I)); + Output ("$%04" PRIX16, GetCodeWord (PC+I)); } } LineComment (PC, ByteCount); @@ -288,19 +289,19 @@ void DataWordLine (unsigned ByteCount) -void DataDWordLine (unsigned ByteCount) +void DataDWordLine (uint32_t ByteCount) /* Output a line with dwords */ { - unsigned I; + uint32_t I; Indent (MCol); Output (".dword"); Indent (ACol); for (I = 0; I < ByteCount; I += 4) { if (I > 0) { - Output (",$%08lX", GetCodeDWord (PC+I)); + Output (",$%08" PRIX32, GetCodeDWord (PC+I)); } else { - Output ("$%08lX", GetCodeDWord (PC+I)); + Output ("$%08" PRIX32, GetCodeDWord (PC+I)); } } LineComment (PC, ByteCount); @@ -372,12 +373,12 @@ void LineComment (unsigned PC, unsigned Count) Output ("; %04X", PC); if (Comments >= 3) { for (I = 0; I < Count; ++I) { - Output (" %02X", CodeBuf [PC+I]); + Output (" %02" PRIX8, CodeBuf [PC+I]); } if (Comments >= 4) { Indent (TCol); for (I = 0; I < Count; ++I) { - unsigned char C = CodeBuf [PC+I]; + uint8_t C = CodeBuf [PC+I]; if (!isprint (C)) { C = '.'; } diff --git a/src/da65/output.h b/src/da65/output.h index bc20aace0f..7370e0786f 100644 --- a/src/da65/output.h +++ b/src/da65/output.h @@ -72,22 +72,22 @@ void DefForward (const char* Name, const char* Comment, unsigned Offs); ** current PC. */ -void DefConst (const char* Name, const char* Comment, unsigned Addr); +void DefConst (const char* Name, const char* Comment, uint32_t Addr); /* Define an address constant */ void OneDataByte (void); /* Output a .byte line with the current code byte */ -void DataByteLine (unsigned ByteCount); +void DataByteLine (uint32_t ByteCount); /* Output a line with bytes */ -void DataDByteLine (unsigned ByteCount); +void DataDByteLine (uint32_t ByteCount); /* Output a line with dbytes */ -void DataWordLine (unsigned ByteCount); +void DataWordLine (uint32_t ByteCount); /* Output a line with words */ -void DataDWordLine (unsigned ByteCount); +void DataDWordLine (uint32_t ByteCount); /* Output a line with dwords */ void SeparatorLine (void); diff --git a/src/da65/scanner.c b/src/da65/scanner.c index d0301c08a4..66940dfb69 100644 --- a/src/da65/scanner.c +++ b/src/da65/scanner.c @@ -600,11 +600,11 @@ void InfoAssureIdent (void) -void InfoRangeCheck (long Lo, long Hi) +void InfoRangeCheck (const char* Attr, long Lo, long Hi) /* Check the range of InfoIVal */ { if (InfoIVal < Lo || InfoIVal > Hi) { - InfoError ("Range error"); + InfoError ("Range error for attribute %s", Attr); } } diff --git a/src/da65/scanner.h b/src/da65/scanner.h index ce76d4a98c..e34aecb4f9 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -191,7 +191,7 @@ void InfoAssureChar (void); void InfoAssureIdent (void); /* Make sure the next token is an identifier */ -void InfoRangeCheck (long Lo, long Hi); +void InfoRangeCheck (const char* Attr, long Lo, long Hi); /* Check the range of InfoIVal */ void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name); diff --git a/src/da65/segment.c b/src/da65/segment.c index 12d4cf6569..1a0b3b0627 100644 --- a/src/da65/segment.c +++ b/src/da65/segment.c @@ -58,7 +58,7 @@ typedef struct Segment Segment; struct Segment { Segment* NextStart; /* Pointer to next segment */ - unsigned long Start; + uint32_t Start; unsigned AddrSize; char Name[1]; /* Name, dynamically allocated */ }; @@ -76,7 +76,7 @@ static Segment* StartTab[HASH_SIZE]; /* Table containing segment starts */ -void AddAbsSegment (unsigned Start, unsigned End, const char* Name) +void AddAbsSegment (uint32_t Start, uint32_t End, const char* Name) /* Add an absolute segment to the segment table */ { /* Get the length of the name */ @@ -104,7 +104,7 @@ void AddAbsSegment (unsigned Start, unsigned End, const char* Name) -char* GetSegmentStartName (unsigned Addr) +char* GetSegmentStartName (uint32_t Addr) /* Return the name of the segment which starts at the given address */ { Segment* S = StartTab[Addr % HASH_SIZE]; @@ -122,7 +122,7 @@ char* GetSegmentStartName (unsigned Addr) -unsigned GetSegmentAddrSize (unsigned Addr) +unsigned GetSegmentAddrSize (uint32_t Addr) /* Return the address size of the segment which starts at the given address */ { Segment* S = StartTab[Addr % HASH_SIZE]; diff --git a/src/da65/segment.h b/src/da65/segment.h index b1423bb41a..5da30fda34 100644 --- a/src/da65/segment.h +++ b/src/da65/segment.h @@ -44,13 +44,13 @@ -void AddAbsSegment (unsigned Start, unsigned End, const char* Name); +void AddAbsSegment (uint32_t Start, uint32_t End, const char* Name); /* Add an absolute segment to the segment table */ -char* GetSegmentStartName (unsigned Addr); +char* GetSegmentStartName (uint32_t Addr); /* Return the name of the segment which starts at the given address */ -unsigned GetSegmentAddrSize (unsigned Addr); +unsigned GetSegmentAddrSize (uint32_t Addr); /* Return the address size of the segment which starts at the given address */ From 7d231d60a6b969ffd7198ac90ff77f23f74d4281 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 22 Jun 2025 12:15:33 +0200 Subject: [PATCH 2/3] Minor corrections after looking at the diff. --- src/da65/handler.c | 4 +--- src/da65/labels.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/da65/handler.c b/src/da65/handler.c index 836dc28845..db55b40584 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -125,10 +125,8 @@ static const char* GetAddrArg (unsigned Flags, uint32_t Addr) static char Buf [32]; if (Addr < 0x100) { xsprintf (Buf, sizeof (Buf), "$%02" PRIX32, Addr); - } else if (Addr < 0x10000) { - xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr); } else { - xsprintf (Buf, sizeof (Buf), "$%06" PRIX32, Addr); + xsprintf (Buf, sizeof (Buf), "$%04" PRIX32, Addr); } return Buf; } diff --git a/src/da65/labels.c b/src/da65/labels.c index 3a4cdd2d7f..6f6bce3ed2 100644 --- a/src/da65/labels.c +++ b/src/da65/labels.c @@ -507,7 +507,7 @@ void DefOutOfRangeLabels (void) ** sorted by address for better readability. This is not directly ** possible when using a hash table, so an intermediate data structure ** is required. It is not possible to collect out-of-range labels while - ** generating them, since they may come from an info file and where added + ** generating them, since they may come from an info file and are added ** while no input file was read. Which means it cannot be determined at ** that point if they're out-of-range or not. */ From e949fbdbbfb125769f5129f79a5033af051b2a54 Mon Sep 17 00:00:00 2001 From: Kugel Fuhr <98353208+kugelfuhr@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:32:55 +0200 Subject: [PATCH 3/3] Unify CPU list in the docs. --- doc/da65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/da65.sgml b/doc/da65.sgml index 7300d3d716..dd51a47647 100644 --- a/doc/da65.sgml +++ b/doc/da65.sgml @@ -248,8 +248,8 @@ With the command line option , the disassembler may be told which CPU to support: - - NMOS 6502 (all legal instructions) - - NMOS 6502 with all undocumented instructions + - NMOS 6502 (all legal instructions) + - NMOS 6502 with all undocumented instructions - the emulated CPU of the C64DTV device - first CMOS instruction set (no bit manipulation, no wai/stp) - full CMOS instruction set (has bit manipulation and wai/stp)