1 /*****************************************************************************/
5 /* Disassembler configuration file handling */
9 /* (C) 2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
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", CFGTOK_INPUTNAME },
69 { "OUTPUTNAME", CFGTOK_OUTPUTNAME },
70 { "PAGELENGTH", CFGTOK_PAGELENGTH },
71 { "STARTADDR", CFGTOK_STARTADDR },
77 /* Expect the opening curly brace */
80 /* Look for section tokens */
81 while (CfgTok != CFGTOK_RCURLY) {
83 /* Convert to special token */
84 CfgSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive");
86 /* Look at the token */
89 case CFGTOK_INPUTNAME:
93 CfgError ("Input file name already given");
95 InFile = xstrdup (CfgSVal);
99 case CFGTOK_OUTPUTNAME:
103 CfgError ("Output file name already given");
105 OutFile = xstrdup (CfgSVal);
109 case CFGTOK_PAGELENGTH:
113 CfgRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN);
115 PageLength = CfgIVal;
119 case CFGTOK_STARTADDR:
122 CfgRangeCheck (0x0000, 0xFFFF);
129 /* Directive is followed by a semicolon */
134 /* Consume the closing brace */
140 static void RangeSection (void)
141 /* Parse a range section */
143 static const IdentTok RangeDefs[] = {
144 { "START", CFGTOK_START },
145 { "END", CFGTOK_END },
146 { "TYPE", CFGTOK_TYPE },
149 static const IdentTok TypeDefs[] = {
150 { "CODE", CFGTOK_CODE },
151 { "BYTETABLE", CFGTOK_BYTETAB },
152 { "WORDTABLE", CFGTOK_WORDTAB },
153 { "DWORDTABLE", CFGTOK_DWORDTAB },
154 { "ADDRTABLE", CFGTOK_ADDRTAB },
155 { "RTSTABLE", CFGTOK_RTSTAB },
159 /* Which values did we get? */
168 /* Locals - initialize to avoid gcc warnings */
171 unsigned char Type = 0;
176 /* Expect the opening curly brace */
179 /* Look for section tokens */
180 while (CfgTok != CFGTOK_RCURLY) {
182 /* Convert to special token */
183 CfgSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range directive");
185 /* Look at the token */
191 CfgRangeCheck (0x0000, 0xFFFF);
200 CfgRangeCheck (0x0000, 0xFFFF);
208 CfgSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "Type");
210 case CFGTOK_CODE: Type = atCode; break;
211 case CFGTOK_BYTETAB: Type = atByteTab; break;
212 case CFGTOK_WORDTAB: Type = atWordTab; break;
213 case CFGTOK_DWORDTAB: Type = atDWordTab; break;
214 case CFGTOK_ADDRTAB: Type = atAddrTab; break;
215 case CFGTOK_RTSTAB: Type = atRtsTab; break;
222 /* Directive is followed by a semicolon */
227 /* Did we get all required values? */
228 if (Needed != tAll) {
229 CfgError ("Required values missing from this section");
232 /* Start must be less than end */
234 CfgError ("Start value must not be greater than end value");
238 MarkRange (Start, End, Type);
240 /* Consume the closing brace */
246 static void LabelSection (void)
247 /* Parse a label section */
249 static const IdentTok LabelDefs[] = {
250 { "NAME", CFGTOK_NAME },
251 { "ADDR", CFGTOK_ADDR },
252 { "SIZE", CFGTOK_SIZE },
255 /* Locals - initialize to avoid gcc warnings */
263 /* Expect the opening curly brace */
266 /* Look for section tokens */
267 while (CfgTok != CFGTOK_RCURLY) {
269 /* Convert to special token */
270 CfgSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive");
272 /* Look at the token */
278 CfgError ("Name already given");
281 if (CfgSVal[0] == '\0') {
282 CfgError ("Name may not be empty");
284 Name = xstrdup (CfgSVal);
291 CfgError ("Value already given");
294 CfgRangeCheck (0, 0xFFFF);
302 CfgError ("Size already given");
305 CfgRangeCheck (1, 0x10000);
312 /* Directive is followed by a semicolon */
316 /* Did we get the necessary data */
318 CfgError ("Label name is missing");
321 CfgError ("Label value is missing");
327 if (Value + Size > 0x10000) {
328 CfgError ("Invalid size (address out of range)");
330 if (HaveLabel ((unsigned) Value)) {
331 CfgError ("Label for address $%04lX already defined", Value);
334 /* Define the label */
335 AddLabel ((unsigned) Value, atExtLabel, Name);
337 /* Define dependent labels if necessary */
341 /* Allocate memory for the dependent label names */
342 unsigned NameLen = strlen (Name);
343 char* DepName = xmalloc (NameLen + 7);
344 char* DepOffs = DepName + NameLen + 1;
346 /* Copy the original name into the buffer */
347 memcpy (DepName, Name, NameLen);
348 DepName[NameLen] = '+';
350 /* Define the labels */
351 for (Offs = 1; Offs < (unsigned) Size; ++Offs) {
352 sprintf (DepOffs, "%u", Offs);
353 AddLabel ((unsigned) Value+Offs, atDepLabel, DepName);
356 /* Free the name buffer */
360 /* Delete the dynamically allocated memory for Name */
363 /* Consume the closing brace */
369 static void CfgParse (void)
370 /* Parse the config file */
372 static const IdentTok Globals[] = {
373 { "GLOBAL", CFGTOK_GLOBAL },
374 { "RANGE", CFGTOK_RANGE },
375 { "LABEL", CFGTOK_LABEL },
378 while (CfgTok != CFGTOK_EOF) {
380 /* Convert an identifier into a token */
381 CfgSpecialToken (Globals, ENTRY_COUNT (Globals), "Config directive");
383 /* Check the token */
400 /* Semicolon expected */
408 /* Read the configuration if a configuration file exists */
410 /* Check if we have a config file given */
411 if (!CfgAvail() || access (CfgGetName(), 0) != 0) {
412 /* No name given or file not found */
416 /* Open the config file */
419 /* Parse the config file */