/*****************************************************************************/ /* */ /* attrtab.c */ /* */ /* Disassembler attribute table */ /* */ /* */ /* */ /* (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 */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. 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. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ /* da65 */ #include "cpu.h" #include "error.h" #include "attrtab.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ /* Attribute table */ static unsigned short AttrTab[0x10000]; /* 65816 attribute table */ #define MAX_LONG_ATTRS 256 static unsigned short LongAttrVal[MAX_LONG_ATTRS]; static unsigned LongAttrAddr[MAX_LONG_ATTRS]; static unsigned LongAttrsUsed; /*****************************************************************************/ /* Code */ /*****************************************************************************/ void AddrCheck (unsigned Addr) /* Check if the given address has a valid range */ { if (Addr >= 0x10000 && CPU != CPU_65816) { Error ("Address out of range: %08X", Addr); } } unsigned char IsLongAddr (unsigned Addr) /* Is it 24-bit? */ { return Addr >= 0x10000 && CPU == CPU_65816; } attr_t GetAttr (unsigned Addr) /* Return the attribute for the given address */ { /* Check the given address */ AddrCheck (Addr); if (IsLongAddr (Addr)) { unsigned i; for (i = 0; i < LongAttrsUsed; i++) { if (LongAttrAddr[i] == Addr) { return LongAttrVal[i]; } } return 0; } /* 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 */ { while (Start <= End) { if (AttrTab[Start++] & atSegment) { return 1; } } return 0; } int IsSegmentEnd (unsigned Addr) /* Return true if a segment ends at the given address */ { return (GetAttr (Addr) & atSegmentEnd) != 0x0000; } int IsSegmentStart (unsigned Addr) /* Return true if a segment starts at the given address */ { return (GetAttr (Addr) & atSegmentStart) != 0x0000; } unsigned GetGranularity (attr_t Style) /* Get the granularity for the given style */ { switch (Style) { case atDefault: return 1; case atCode: return 1; case atIllegal: return 1; case atByteTab: return 1; case atDByteTab: return 2; case atWordTab: return 2; case atDWordTab: return 4; case atAddrTab: return 2; case atRtsTab: return 2; case atTextTab: return 1; case atSkip: default: Internal ("GetGraularity called for style = %d", Style); return 0; } } void MarkRange (unsigned Start, unsigned End, attr_t Attr) /* Mark a range with the given attribute */ { /* Do it easy here... */ while (Start <= End) { MarkAddr (Start++, Attr); } } void MarkAddr (unsigned 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; } /* We must not have more than one style bit */ if (Attr & atStyleMask) { if (AttrTab[Addr] & atStyleMask) { Error ("Duplicate style for address %04X", Addr); } } /* Set the style */ AttrTab[Addr] |= Attr; } attr_t GetStyleAttr (unsigned Addr) /* Return the style attribute for the given address */ { /* Check the given address */ AddrCheck (Addr); /* Return the attribute */ return (GetAttr (Addr) & atStyleMask); } attr_t GetLabelAttr (unsigned Addr) /* Return the label attribute for the given address */ { /* Check the given address */ AddrCheck (Addr); /* Return the attribute */ return (GetAttr (Addr) & atLabelMask); }