1 /*****************************************************************************/
5 /* Disassembler info file handling */
9 /* (C) 2000-2003 Ullrich von Bassewitz */
10 /* Römerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
39 /* Microsoft compiler */
58 /*****************************************************************************/
60 /*****************************************************************************/
64 static void GlobalSection (void)
65 /* Parse a global section */
67 static const IdentTok GlobalDefs[] = {
68 { "INPUTNAME", INFOTOK_INPUTNAME },
69 { "OUTPUTNAME", INFOTOK_OUTPUTNAME },
70 { "PAGELENGTH", INFOTOK_PAGELENGTH },
71 { "STARTADDR", INFOTOK_STARTADDR },
77 /* Expect the opening curly brace */
80 /* Look for section tokens */
81 while (InfoTok != INFOTOK_RCURLY) {
83 /* Convert to special token */
84 InfoSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive");
86 /* Look at the token */
89 case INFOTOK_INPUTNAME:
93 InfoError ("Input file name already given");
95 InFile = xstrdup (InfoSVal);
99 case INFOTOK_OUTPUTNAME:
103 InfoError ("Output file name already given");
105 OutFile = xstrdup (InfoSVal);
109 case INFOTOK_PAGELENGTH:
112 if (InfoIVal != -1) {
113 InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
115 PageLength = InfoIVal;
119 case INFOTOK_STARTADDR:
122 InfoRangeCheck (0x0000, 0xFFFF);
123 StartAddr = InfoIVal;
129 /* Directive is followed by a semicolon */
134 /* Consume the closing brace */
135 InfoConsumeRCurly ();
140 static void RangeSection (void)
141 /* Parse a range section */
143 static const IdentTok RangeDefs[] = {
144 { "START", INFOTOK_START },
145 { "END", INFOTOK_END },
146 { "TYPE", INFOTOK_TYPE },
149 static const IdentTok TypeDefs[] = {
150 { "CODE", INFOTOK_CODE },
151 { "BYTETABLE", INFOTOK_BYTETAB },
152 { "WORDTABLE", INFOTOK_WORDTAB },
153 { "DWORDTABLE", INFOTOK_DWORDTAB },
154 { "ADDRTABLE", INFOTOK_ADDRTAB },
155 { "RTSTABLE", INFOTOK_RTSTAB },
156 { "TEXTTABLE", INFOTOK_TEXTTAB },
160 /* Which values did we get? */
169 /* Locals - initialize to avoid gcc warnings */
172 unsigned char Type = 0;
177 /* Expect the opening curly brace */
178 InfoConsumeLCurly ();
180 /* Look for section tokens */
181 while (InfoTok != INFOTOK_RCURLY) {
183 /* Convert to special token */
184 InfoSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
186 /* Look at the token */
192 InfoRangeCheck (0x0000, 0xFFFF);
201 InfoRangeCheck (0x0000, 0xFFFF);
209 InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
211 case INFOTOK_CODE: Type = atCode; break;
212 case INFOTOK_BYTETAB: Type = atByteTab; break;
213 case INFOTOK_WORDTAB: Type = atWordTab; break;
214 case INFOTOK_DWORDTAB: Type = atDWordTab; break;
215 case INFOTOK_ADDRTAB: Type = atAddrTab; break;
216 case INFOTOK_RTSTAB: Type = atRtsTab; break;
217 case INFOTOK_TEXTTAB: Type = atTextTab; break;
224 /* Directive is followed by a semicolon */
229 /* Did we get all required values? */
230 if (Needed != tAll) {
231 InfoError ("Required values missing from this section");
234 /* Start must be less than end */
236 InfoError ("Start value must not be greater than end value");
240 MarkRange (Start, End, Type);
242 /* Consume the closing brace */
243 InfoConsumeRCurly ();
248 static void LabelSection (void)
249 /* Parse a label section */
251 static const IdentTok LabelDefs[] = {
252 { "NAME", INFOTOK_NAME },
253 { "ADDR", INFOTOK_ADDR },
254 { "SIZE", INFOTOK_SIZE },
257 /* Locals - initialize to avoid gcc warnings */
265 /* Expect the opening curly brace */
266 InfoConsumeLCurly ();
268 /* Look for section tokens */
269 while (InfoTok != INFOTOK_RCURLY) {
271 /* Convert to special token */
272 InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive");
274 /* Look at the token */
280 InfoError ("Name already given");
283 if (InfoSVal[0] == '\0') {
284 InfoError ("Name may not be empty");
286 Name = xstrdup (InfoSVal);
293 InfoError ("Value already given");
296 InfoRangeCheck (0, 0xFFFF);
304 InfoError ("Size already given");
307 InfoRangeCheck (1, 0x10000);
314 /* Directive is followed by a semicolon */
318 /* Did we get the necessary data */
320 InfoError ("Label name is missing");
323 InfoError ("Label value is missing");
329 if (Value + Size > 0x10000) {
330 InfoError ("Invalid size (address out of range)");
332 if (HaveLabel ((unsigned) Value)) {
333 InfoError ("Label for address $%04lX already defined", Value);
336 /* Define the label */
337 AddLabel ((unsigned) Value, atExtLabel, Name);
339 /* Define dependent labels if necessary */
343 /* Allocate memory for the dependent label names */
344 unsigned NameLen = strlen (Name);
345 char* DepName = xmalloc (NameLen + 7);
346 char* DepOffs = DepName + NameLen + 1;
348 /* Copy the original name into the buffer */
349 memcpy (DepName, Name, NameLen);
350 DepName[NameLen] = '+';
352 /* Define the labels */
353 for (Offs = 1; Offs < (unsigned) Size; ++Offs) {
354 sprintf (DepOffs, "%u", Offs);
355 AddLabel ((unsigned) Value+Offs, atDepLabel, DepName);
358 /* Free the name buffer */
362 /* Delete the dynamically allocated memory for Name */
365 /* Consume the closing brace */
366 InfoConsumeRCurly ();
371 static void InfoParse (void)
372 /* Parse the config file */
374 static const IdentTok Globals[] = {
375 { "GLOBAL", INFOTOK_GLOBAL },
376 { "RANGE", INFOTOK_RANGE },
377 { "LABEL", INFOTOK_LABEL },
380 while (InfoTok != INFOTOK_EOF) {
382 /* Convert an identifier into a token */
383 InfoSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive");
385 /* Check the token */
402 /* Semicolon expected */
409 void ReadInfoFile (void)
410 /* Read the info file */
412 /* Check if we have a info file given */
414 /* Open the config file */
417 /* Parse the config file */