3 # as2gbmap - asxxxx to gb map file converter
5 # Copyright (c) 2010 Borut Razem
7 # This file is part of sdcc.
9 # This software is provided 'as-is', without any express or implied
10 # warranty. In no event will the authors be held liable for any damages
11 # arising from the use of this software.
13 # Permission is granted to anyone to use this software for any purpose,
14 # including commercial applications, and to alter it and redistribute it
15 # freely, subject to the following restrictions:
17 # 1. The origin of this software must not be misrepresented; you must not
18 # claim that you wrote the original software. If you use this software
19 # in a product, an acknowledgment in the product documentation would be
20 # appreciated but is not required.
21 # 2. Altered source versions must be plainly marked as such, and must not be
22 # misrepresented as being the original software.
23 # 3. This notice may not be removed or altered from any source distribution.
26 # borut.razem@siol.net
31 from optparse
import OptionParser
35 '''asxxxx to gb map file converter'''
36 usage
= "usage: %prog [options] [<input_asxxxx_map_file> [<output_gb_file>]]"
37 parser
= OptionParser(usage
= usage
, version
= "1.0")
38 parser
.set_defaults(no_gmb
= False)
39 parser
.add_option("-j", "--no$gmb", action
= "store_true", dest
= "no_gmb", help = "generate no$gmb symbol file (default: rrgb)")
40 (options
, args
) = parser
.parse_args()
42 if len(args
) > 0 and args
[0] != "-":
44 fin
= open(args
[0], "r")
45 except IOError as xxx_todo_changeme
:
46 (errno
, strerror
) = xxx_todo_changeme
.args
47 print("%s: can't open %s: %s" % (os
.path
.basename(sys
.argv
[0]), args
[0], strerror
), file=sys
.stderr
)
52 if len(args
) > 1 and args
[1] != "-":
54 fout
= open(args
[1], "w")
55 except IOError as xxx_todo_changeme1
:
56 (errno
, strerror
) = xxx_todo_changeme1
.args
57 print("%s: can't create %s: %s" % (os
.path
.basename(sys
.argv
[1]), args
[1], strerror
), file=sys
.stderr
)
71 # process asxxxx map file
73 if re
.match(r
"^Hexadecimal$", line
):
77 if re
.match(r
"^Area +Addr +Size +Decimal +Bytes +\(Attributes\)$", line
):
79 if re
.match(r
"^[- ]+$", line
):
81 m
= re
.match(r
"^([^ ]+) +([0-9A-Fa-f]{4}) +([0-9A-Fa-f]{4}) += +\d+\. +\w+ +\(([^\)]+)\)$", line
)
84 if m
.group(1) != area
['area']:
86 area
= {'area': m
.group(1), 'radix': radix
, 'base': int(m
.group(2), 16), 'size': int(m
.group(3), 16), 'attrib': m
.group(4).replace(',', ' '), 'globals': []}
88 area
= {'area': m
.group(1), 'radix': radix
, 'base': int(m
.group(2), 16), 'size': int(m
.group(3), 16), 'attrib': m
.group(4).replace(',', ' '), 'globals': []}
92 m
= re
.match(r
"^ +([0-9A-Fa-f]{4}) +([^ ]+) +$", line
)
93 if state
== 'IN_AREA' and m
:
94 area
['globals'].append({'value': int(m
.group(1), 16), 'global': m
.group(2)})
97 m
= re
.match(r
"Files Linked +\[ module\(s\) \]$", line
)
102 m
= re
.match(r
"Libraries Linked +\[ object file \]$", line
)
104 state
= 'IN_LIBRARIES'
107 m
= re
.match(r
"User Base Address Definitions$", line
)
112 m
= re
.match(r
"^([^ ]+) +\[ ([^ ]*) \]$", line
)
114 if state
== 'IN_MODULES':
115 modules
.append({'file': m
.group(1), 'name': m
.group(2)})
118 if state
== 'IN_LIBRARIES':
119 libraries
.append({'library': m
.group(1), 'module': m
.group(2)})
122 m
= re
.match(r
"^([^ ]+) += +0x([0-9A-Fa-f]{4})$", line
)
123 if state
== 'IN_UBAD' and m
:
124 ubads
.append({'symbol': m
.group(1), 'value': m
.group(2)})
132 # generate no$gmp map file
133 print('; no$gmb format .sym file', file=fout
)
134 print('; Generated automagically by %s' % os
.path
.basename(sys
.argv
[0]), file=fout
)
136 print('; Area: %s' % e
['area'], file=fout
)
138 e
['globals'].sort(key
= operator
.itemgetter('value'))
139 for g
in e
['globals']:
140 if g
['global'][0:3] != 'l__':
141 if g
['value'] > 0x7FFF:
142 print('00:%04X %s' % (g
['value'], g
['global']), file=fout
)
144 print('%02X:%04X %s' % (g
['value'] // 16384, g
['value'], g
['global']), file=fout
)
146 # generate rrgb map file
148 print('AREA %s' % e
['area'], file=fout
)
149 print('\tRADIX %s' % e
['radix'], file=fout
)
150 print('\tBASE %04X' % e
['base'], file=fout
)
151 print('\tSIZE %04X' % e
['size'], file=fout
)
152 print('\tATTRIB %s' % e
['attrib'], file=fout
)
154 e
['globals'].sort(key
= operator
.itemgetter('value'))
155 print('\tGLOBALS', file=fout
)
156 for g
in e
['globals']:
157 print('\t\t%s\t%04X' % (g
['global'], g
['value']), file=fout
)
160 print('MODULES', file=fout
)
162 print('\tFILE %s' % m
['file'], file=fout
)
164 print('\t\tNAME %s' % m
['name'], file=fout
)
167 print('LIBRARIES', file=fout
)
169 print('\tLIBRARY %s' % m
['library'], file=fout
)
170 print('\t\tMODULE %s' % m
['module'], file=fout
)
173 print('USERBASEDEF', file=fout
)
175 print('\t%s = 0x%04X' % (m
['symbol'], int(m
['value'], 16)), file=fout
)
178 if __name__
== '__main__':