From e9e60965a8ebe4939eb226832e21449c188d8e46 Mon Sep 17 00:00:00 2001 From: Rangi Date: Sun, 9 Aug 2020 15:30:06 -0400 Subject: Fix coverage utility script --- tools/disasm_coverage.py | 100 --------------------------- tools/mapreader.py | 171 ----------------------------------------------- 2 files changed, 271 deletions(-) delete mode 100644 tools/disasm_coverage.py delete mode 100644 tools/mapreader.py (limited to 'tools') diff --git a/tools/disasm_coverage.py b/tools/disasm_coverage.py deleted file mode 100644 index fcb9e86..0000000 --- a/tools/disasm_coverage.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from __future__ import division - -import os -import sys -import argparse -import png -from mapreader import MapReader -from colorsys import hls_to_rgb - -if __name__ == '__main__': - # argument parser - ap = argparse.ArgumentParser() - ap.add_argument('-r', dest='romname') - ap.add_argument('-o', dest='filename', default='coverage.png') - ap.add_argument('-m', dest='mapfile', required=True) - ap.add_argument('-b', dest='num_banks', required=True, type=lambda x: int(x, 0)) - args = ap.parse_args() - - bank_mask = 0x3FFF - bank_size = 0x4000 # bytes - width = 256 # pixels per row - bpp = 8 # bytes per pixel - - romname = args.romname - rom_size = args.num_banks * bank_size # bytes - height = (args.num_banks * bank_size + (width * bpp - 1)) // (width * bpp) # pixels - rows_per_bank = bank_size // (width * bpp) - - r = MapReader() - try: - with open(args.mapfile, 'r') as f: - l = f.readlines() - except UnicodeDecodeError: - # Python 3 seems to choke on the file's encoding, but the `encoding` keyword only works on Py3 - with open(args.mapfile, 'r', encoding= 'utf-8') as f: - l = f.readlines() - r.read_map_data(l) - - default_bank_data = {'sections': [], 'used': 0, 'slack': bank_size} - filler = [0x00, 0xFF] - - if (romname is not None): - with open(romname, 'rb') as f: - for rb in range(0, args.num_banks): - data = r.bank_data['ROM Bank'].get(rb, default_bank_data) - bank = f.read(bank_size) - if (bank[bank_size - 1] in filler): - fill = bank[bank_size - 1] - for i in reversed(range(-1, bank_size - 1)): - if (i < 0 or bank[i] != fill): - break - # i is now pointing to first different byte - beg = i + 1 + (0 if rb == 0 else bank_size) - end = bank_size + (0 if rb == 0 else bank_size) - data['sections'].append({'beg': beg, 'end': end, 'name': 'Section_Trailing_Fill', 'symbols': []}) - - hit_data = [[0] * width for _ in range(height)] - for bank in range(args.num_banks): - data = r.bank_data['ROM Bank'].get(bank, default_bank_data) - for s in data['sections']: - beg = (s['beg'] & bank_mask) + bank * bank_size - end = ((s['end'] -1) & bank_mask) + bank * bank_size # end is exclusive - # skip zero-sized entries - if (s['beg'] == s['end']): - continue - y_beg = beg // (width * bpp) - x_beg = (beg % (width * bpp)) // bpp - y_end = end // (width * bpp) - x_end = (end % (width * bpp)) // bpp - #print('beg {0} end {1}: {2}/{3} -- {4}/{5}'.format(beg, end, y_beg, x_beg, y_end, x_end)) - # special case y_beg/x_beg and y_end/x_end - if (y_beg == y_end and x_beg == x_end): - hit_data[y_beg][x_beg] += end - beg + 1 - else: - hit_data[y_beg][x_beg] += bpp - ((beg % (width * bpp)) - x_beg * bpp) - hit_data[y_end][x_end] += ((end % (width * bpp)) - x_end * bpp + 1) - # regular case - for y in range(y_beg, y_end + 1): - x_line_beg = 0 if y_beg != y else x_beg + 1 - x_line_end = width - 1 if y_end != y else x_end - 1 - for x in range(x_line_beg, x_line_end + 1): - hit_data[y][x] += bpp - - png_data = [] - for i, row in enumerate(hit_data): - bank = i // rows_per_bank - hue = 0 if bank % 2 else 120 - row_png_data = () - for col in row: - hls = (hue/360.0, 1.0 - (col/bpp * (100 - 15))/100.0, 1.0) - rgb = tuple(255 * x for x in hls_to_rgb(*hls)) - row_png_data += rgb - png_data.append(row_png_data) - - with open(args.filename, 'wb') as f: - w = png.Writer(width, height) - w.write(f, png_data) diff --git a/tools/mapreader.py b/tools/mapreader.py deleted file mode 100644 index 95a4723..0000000 --- a/tools/mapreader.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import re - -class MapReader: - - # {'ROM Bank': { 0: { 'sections': [ { 'beg': 1234, - # 'end': 5678, - # 'name': 'Section001', - # 'symbols': [ { 'symbol': 'Function1234', - # 'address: 1234, - # }, - # ] - # }, - # ], - # 'used': 1234, - # 'slack': 4567, - # }, - # }, - # 'OAM': { 'sections': [ { 'beg': 1234, - # 'end': 5678, - # 'name': 'Section002', - # 'symbols': [ { 'symbol': 'Data1234', - # 'address: 1234, - # }, - # ] - # }, - # ], - # 'used': 1234, - # 'slack': 4567, - # }, - # } - # - bank_data = {} - - bank_types = { - 'HRAM' : { 'size': 0x80, 'banked': False, }, - 'OAM' : { 'size': 0xA0, 'banked': False, }, - 'ROM Bank' : { 'size': 0x4000, 'banked': True, }, - 'SRAM Bank': { 'size': 0x2000, 'banked': True, }, - 'VRAM Bank': { 'size': 0x1000, 'banked': True, }, - 'WRAM Bank': { 'size': 0x2000, 'banked': True, }, - } - - # FSM states - INIT, BANK, SECTION = range(3) - - # $506D-$519A ($012E bytes) ["Type Matchups"] - section_header_regex = re.compile('\$([0-9A-Fa-f]{4})-\$([0-9A-Fa-f]{4}) \(.*\) \["(.*)"\]') - # $506D = TypeMatchups - section_data_regex = re.compile('\$([0-9A-Fa-f]{4}) = (.*)') - # $3ED2 bytes - slack_regex = re.compile('\$([0-9A-Fa-f]{4}) bytes') - - def __init__(self, *args, **kwargs): - self.__dict__.update(kwargs) - - def _parse_init(self, line): - - line = line.split(':', 1)[0] - parts = line.split(' #', 1) - - if (parts[0] in self.bank_types): - self._cur_bank_name = parts[0] - self._cur_bank_type = self.bank_types[self._cur_bank_name] - if (self._cur_bank_type['banked'] and len(parts) > 1): - parts[1] = parts[1].split(':', 1)[0] - parts[1] = parts[1].split(' ', 1)[0] - self._cur_bank = int(parts[1], 10) - if self._cur_bank_name not in self.bank_data: - self.bank_data[self._cur_bank_name] = {} - if self._cur_bank_type['banked']: - if self._cur_bank not in self.bank_data[self._cur_bank_name]: - self.bank_data[self._cur_bank_name][self._cur_bank] = {} - self._cur_data = self.bank_data[self._cur_bank_name][self._cur_bank] - else: - self._cur_data = self.bank_data[self._cur_bank_name] - - if ({} == self._cur_data): - self._cur_data['sections'] = [] - self._cur_data['used'] = 0 - self._cur_data['slack'] = self._cur_bank_type['size'] - return True - - return False - - def _parse_section_header(self, header): - - section_data = self.section_header_regex.match(header) - if section_data is not None: - beg = int(section_data.group(1), 16) - end = int(section_data.group(2), 16) - name = section_data.group(3) - self._cur_section = {'beg': beg, 'end': end, 'name': name, 'symbols': []} - self._cur_data['sections'].append(self._cur_section) - return True - return False - - def _parse_slack(self, data): - - slack_data = self.slack_regex.match(data) - slack_bytes = int(slack_data.group(1), 16) - self._cur_data['slack'] = slack_bytes - - used_bytes = 0 - - for s in self._cur_data['sections']: - used_bytes += s['end'] - s['beg'] + 1 - - self._cur_data['used'] = used_bytes - - def read_map_data(self, map): - - if type(map) is str: - map = map.split('\n') - - self._state = MapReader.INIT - self._cur_bank_name = '' - self._cur_bank_type = {} - self._cur_bank = 0 - self._cur_data = {} - - for line in map: - - line = line.rstrip() - if (MapReader.INIT == self._state): - - if (self._parse_init(line)): - self._state = MapReader.BANK - - elif (MapReader.BANK == self._state or MapReader.SECTION == self._state): - - if ('' == line): - self._state = MapReader.INIT - else: - - line = line.lstrip() - parts = line.split(': ', 1) - - if (MapReader.SECTION == self._state): - section_data = self.section_data_regex.match(parts[0]) - if section_data is not None: - address = int(section_data.group(1), 16) - name = section_data.group(2) - self._cur_section['symbols'].append({'name': name, 'address': address}) - continue - - if ('SECTION' == parts[0]): - if (self._parse_section_header(parts[1])): - self._state = MapReader.SECTION - elif ('SLACK' == parts[0]): - self._parse_slack(parts[1]) - self._state = MapReader.INIT - elif ('EMPTY' == parts[0]): - self._cur_data = {'sections': [], 'used': 0, 'slack': self._cur_bank_type['size']} - self._state = MapReader.INIT - - else: - pass - - for k, v in self.bank_data.items(): - if (self.bank_types[k]['banked']): - for _, vv in v.items(): - vv['sections'].sort(key=lambda x: x['beg']) - for vvv in vv['sections']: - vvv['symbols'].sort(key=lambda x: x['address']) - else: - v['sections'].sort(key=lambda x: x['beg']) - for vv in v['sections']: - vv['symbols'].sort(key=lambda x: x['address']) -- cgit v1.2.3