as2gbmap 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/env python
  2. # as2gbmap - asxxxx to gb map file converter
  3. #
  4. # Copyright (c) 2010 Borut Razem
  5. #
  6. # This file is part of sdcc.
  7. #
  8. # This software is provided 'as-is', without any express or implied
  9. # warranty. In no event will the authors be held liable for any damages
  10. # arising from the use of this software.
  11. #
  12. # Permission is granted to anyone to use this software for any purpose,
  13. # including commercial applications, and to alter it and redistribute it
  14. # freely, subject to the following restrictions:
  15. #
  16. # 1. The origin of this software must not be misrepresented; you must not
  17. # claim that you wrote the original software. If you use this software
  18. # in a product, an acknowledgment in the product documentation would be
  19. # appreciated but is not required.
  20. # 2. Altered source versions must be plainly marked as such, and must not be
  21. # misrepresented as being the original software.
  22. # 3. This notice may not be removed or altered from any source distribution.
  23. #
  24. # Borut Razem
  25. # borut.razem@siol.net
  26. import sys
  27. import os
  28. import re
  29. from optparse import OptionParser
  30. import operator
  31. def main():
  32. '''asxxxx to gb map file converter'''
  33. usage = "usage: %prog [options] [<input_asxxxx_map_file> [<output_gb_file>]]"
  34. parser = OptionParser(usage = usage, version = "1.0")
  35. parser.set_defaults(no_gmb = False)
  36. parser.add_option("-j", "--no$gmb", action = "store_true", dest = "no_gmb", help = "generate no$gmb symbol file (default: rrgb)")
  37. (options, args) = parser.parse_args()
  38. if len(args) > 0 and args[0] != "-":
  39. try:
  40. fin = open(args[0], "r")
  41. except IOError, (errno, strerror):
  42. print >> sys.stderr, "%s: can't open %s: %s" % (os.path.basename(sys.argv[0]), args[0], strerror)
  43. return 1
  44. else:
  45. fin = sys.stdin
  46. if len(args) > 1 and args[1] != "-":
  47. try:
  48. fout = open(args[1], "w")
  49. except IOError, (errno, strerror):
  50. print >> sys.stderr, "%s: can't create %s: %s" % (os.path.basename(sys.argv[1]), args[1], strerror)
  51. return 1
  52. else:
  53. fout = sys.stdout;
  54. areas = []
  55. modules = []
  56. libraries = []
  57. ubads = []
  58. radix = 'HEX'
  59. state = None
  60. area = None
  61. # process asxxxx map file
  62. for line in fin:
  63. if re.match(r"^Hexadecimal$", line):
  64. radix = 'HEX';
  65. continue
  66. if re.match(r"^Area +Addr +Size +Decimal +Bytes +\(Attributes\)$", line):
  67. line = fin.next()
  68. if re.match(r"^[- ]+$", line):
  69. line = fin.next()
  70. m = re.match(r"^([^ ]+) +([0-9A-Fa-f]{4}) +([0-9A-Fa-f]{4}) += +\d+\. +\w+ +\(([^\)]+)\)$", line)
  71. if m:
  72. if area:
  73. if m.group(1) != area['area']:
  74. areas.append(area)
  75. 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': []}
  76. else:
  77. 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': []}
  78. state = 'IN_AREA'
  79. continue
  80. m = re.match(r"^ +([0-9A-Fa-f]{4}) +([^ ]+) +$", line)
  81. if state == 'IN_AREA' and m:
  82. area['globals'].append({'value': int(m.group(1), 16), 'global': m.group(2)})
  83. continue
  84. m = re.match(r"Files Linked +\[ module\(s\) \]$", line)
  85. if m:
  86. state = 'IN_MODULES'
  87. continue
  88. m = re.match(r"Libraries Linked +\[ object file \]$", line)
  89. if m:
  90. state = 'IN_LIBRARIES'
  91. continue
  92. m = re.match(r"User Base Address Definitions$", line)
  93. if m:
  94. state = 'IN_UBAD'
  95. continue
  96. m = re.match(r"^([^ ]+) +\[ ([^ ]*) \]$", line)
  97. if m:
  98. if state == 'IN_MODULES':
  99. modules.append({'file': m.group(1), 'name': m.group(2)})
  100. continue
  101. if state == 'IN_LIBRARIES':
  102. libraries.append({'library': m.group(1), 'module': m.group(2)})
  103. continue
  104. m = re.match(r"^([^ ]+) += +0x([0-9A-Fa-f]{4})$", line)
  105. if state == 'IN_UBAD' and m:
  106. ubads.append({'symbol': m.group(1), 'value': m.group(2)})
  107. continue
  108. if area:
  109. areas.append(area)
  110. if options.no_gmb:
  111. # generate no$gmp map file
  112. print >> fout, '; no$gmb format .sym file'
  113. print >> fout, '; Generated automagically by %s' % os.path.basename(sys.argv[0])
  114. for e in areas:
  115. print >> fout, '; Area: %s' % e['area']
  116. if e['globals']:
  117. e['globals'].sort(key = operator.itemgetter('value'))
  118. for g in e['globals']:
  119. if g['global'][0:3] != 'l__':
  120. if g['value'] > 0x7FFF:
  121. print >> fout, '00:%04X %s' % (g['value'], g['global'])
  122. else:
  123. print >> fout, '%02X:%04X %s' % (g['value'] // 16384, g['value'], g['global'])
  124. else:
  125. # generate rrgb map file
  126. for e in areas:
  127. print >> fout, 'AREA %s' % e['area']
  128. print >> fout, '\tRADIX %s' % e['radix']
  129. print >> fout, '\tBASE %04X' % e['base']
  130. print >> fout, '\tSIZE %04X' % e['size']
  131. print >> fout, '\tATTRIB %s' % e['attrib']
  132. if e['globals']:
  133. e['globals'].sort(key = operator.itemgetter('value'))
  134. print >> fout, '\tGLOBALS'
  135. for g in e['globals']:
  136. print >> fout, '\t\t%s\t%04X' % (g['global'], g['value'])
  137. if modules:
  138. print >> fout, 'MODULES'
  139. for m in modules:
  140. print >> fout, '\tFILE %s' % m['file']
  141. if m['name']:
  142. print >> fout, '\t\tNAME %s' % m['name']
  143. if libraries:
  144. print >> fout, 'LIBRARIES'
  145. for m in libraries:
  146. print >> fout, '\tLIBRARY %s' % m['library']
  147. print >> fout, '\t\tMODULE %s' % m['module']
  148. if ubads:
  149. print >> fout, 'USERBASEDEF'
  150. for m in ubads:
  151. print >> fout, '\t%s = 0x%04X' % (m['symbol'], int(m['value'], 16))
  152. return 0
  153. if __name__ == '__main__':
  154. sys.exit(main())