1 | /*****************************************************************************/ |
2 | /* */ |
3 | /* attrtab.c */ |
4 | /* */ |
5 | /* Disassembler attribute table */ |
6 | /* */ |
7 | /* */ |
8 | /* */ |
9 | /* (C) 2000-2014, Ullrich von Bassewitz */ |
10 | /* Roemerstrasse 52 */ |
11 | /* D-70794 Filderstadt */ |
12 | /* EMail: uz@cc65.org */ |
13 | /* */ |
14 | /* */ |
15 | /* This software is provided 'as-is', without any expressed or implied */ |
16 | /* warranty. In no event will the authors be held liable for any damages */ |
17 | /* arising from the use of this software. */ |
18 | /* */ |
19 | /* Permission is granted to anyone to use this software for any purpose, */ |
20 | /* including commercial applications, and to alter it and redistribute it */ |
21 | /* freely, subject to the following restrictions: */ |
22 | /* */ |
23 | /* 1. The origin of this software must not be misrepresented; you must not */ |
24 | /* claim that you wrote the original software. If you use this software */ |
25 | /* in a product, an acknowledgment in the product documentation would be */ |
26 | /* appreciated but is not required. */ |
27 | /* 2. Altered source versions must be plainly marked as such, and must not */ |
28 | /* be misrepresented as being the original software. */ |
29 | /* 3. This notice may not be removed or altered from any source */ |
30 | /* distribution. */ |
31 | /* */ |
32 | /*****************************************************************************/ |
33 | |
34 | |
35 | |
36 | /* da65 */ |
37 | #include "error.h" |
38 | #include "attrtab.h" |
39 | |
40 | |
41 | |
42 | /*****************************************************************************/ |
43 | /* Data */ |
44 | /*****************************************************************************/ |
45 | |
46 | |
47 | |
48 | /* Attribute table */ |
49 | static unsigned short AttrTab[0x10000]; |
50 | |
51 | |
52 | |
53 | /*****************************************************************************/ |
54 | /* Code */ |
55 | /*****************************************************************************/ |
56 | |
57 | |
58 | |
59 | void AddrCheck (unsigned Addr) |
60 | /* Check if the given address has a valid range */ |
61 | { |
62 | if (Addr >= 0x10000) { |
63 | Error ("Address out of range: %08X" , Addr); |
64 | } |
65 | } |
66 | |
67 | |
68 | |
69 | attr_t GetAttr (unsigned Addr) |
70 | /* Return the attribute for the given address */ |
71 | { |
72 | /* Check the given address */ |
73 | AddrCheck (Addr); |
74 | |
75 | /* Return the attribute */ |
76 | return AttrTab[Addr]; |
77 | } |
78 | |
79 | |
80 | |
81 | int SegmentDefined (unsigned Start, unsigned End) |
82 | /* Return true if the atSegment bit is set somewhere in the given range */ |
83 | { |
84 | while (Start <= End) { |
85 | if (AttrTab[Start++] & atSegment) { |
86 | return 1; |
87 | } |
88 | } |
89 | return 0; |
90 | } |
91 | |
92 | |
93 | |
94 | int IsSegmentEnd (unsigned Addr) |
95 | /* Return true if a segment ends at the given address */ |
96 | { |
97 | return (GetAttr (Addr) & atSegmentEnd) != 0x0000; |
98 | } |
99 | |
100 | |
101 | |
102 | int IsSegmentStart (unsigned Addr) |
103 | /* Return true if a segment starts at the given address */ |
104 | { |
105 | return (GetAttr (Addr) & atSegmentStart) != 0x0000; |
106 | } |
107 | |
108 | |
109 | |
110 | unsigned GetGranularity (attr_t Style) |
111 | /* Get the granularity for the given style */ |
112 | { |
113 | switch (Style) { |
114 | case atDefault: return 1; |
115 | case atCode: return 1; |
116 | case atIllegal: return 1; |
117 | case atByteTab: return 1; |
118 | case atDByteTab: return 2; |
119 | case atWordTab: return 2; |
120 | case atDWordTab: return 4; |
121 | case atAddrTab: return 2; |
122 | case atRtsTab: return 2; |
123 | case atTextTab: return 1; |
124 | |
125 | case atSkip: |
126 | default: |
127 | Internal ("GetGraularity called for style = %d" , Style); |
128 | return 0; |
129 | } |
130 | } |
131 | |
132 | |
133 | |
134 | void MarkRange (unsigned Start, unsigned End, attr_t Attr) |
135 | /* Mark a range with the given attribute */ |
136 | { |
137 | /* Do it easy here... */ |
138 | while (Start <= End) { |
139 | MarkAddr (Start++, Attr); |
140 | } |
141 | } |
142 | |
143 | |
144 | |
145 | void MarkAddr (unsigned Addr, attr_t Attr) |
146 | /* Mark an address with an attribute */ |
147 | { |
148 | /* Check the given address */ |
149 | AddrCheck (Addr); |
150 | |
151 | /* We must not have more than one style bit */ |
152 | if (Attr & atStyleMask) { |
153 | if (AttrTab[Addr] & atStyleMask) { |
154 | Error ("Duplicate style for address %04X" , Addr); |
155 | } |
156 | } |
157 | |
158 | /* Set the style */ |
159 | AttrTab[Addr] |= Attr; |
160 | } |
161 | |
162 | |
163 | |
164 | attr_t GetStyleAttr (unsigned Addr) |
165 | /* Return the style attribute for the given address */ |
166 | { |
167 | /* Check the given address */ |
168 | AddrCheck (Addr); |
169 | |
170 | /* Return the attribute */ |
171 | return (AttrTab[Addr] & atStyleMask); |
172 | } |
173 | |
174 | |
175 | |
176 | attr_t GetLabelAttr (unsigned Addr) |
177 | /* Return the label attribute for the given address */ |
178 | { |
179 | /* Check the given address */ |
180 | AddrCheck (Addr); |
181 | |
182 | /* Return the attribute */ |
183 | return (AttrTab[Addr] & atLabelMask); |
184 | } |
185 | |