summaryrefslogtreecommitdiff
path: root/tools/sort_sym.py
blob: f4674e8db9ac7bf1cf4c129a54ed891ad2d08be9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/python3.6

import argparse
from functools import total_ordering


@total_ordering
class GBSection:
    ROM0 = 0
    ROMX = 1
    VRAM = 2
    SRAM = 3
    WRAM0 = 4
    WRAMX = 5

    __thresholds__ = (0x4000, 0x8000, 0xa000, 0xc000, 0xd000, 0xe000)

    def __init__(self, addr):
        self.ident = sum(x <= addr for x in self.__thresholds__)

    @property
    def start(self):
        if self.ident == self.ROM0:
            return 0
        return self.__thresholds__[self.ident - 1]

    @property
    def end(self):
        return self.__thresholds__[self.ident]

    def __eq__(self, other):
        return self.ident == other.ident

    def __lt__(self, other):
        return self.ident < other.ident


def read_sym(filename):
    with open(filename) as fp:
        for line in fp:
            try:
                line, *rest = line.split(';')
                pointer, name = line.split()
                bank, addr = (int(part, 16) for part in pointer.split(':'))
                yield bank, addr, name
            except ValueError:
                continue


def sort_key(args):
    bank, addr, name = args
    return GBSection(addr), bank, addr, name


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('symfile')
    args = parser.parse_args()

    symbols = list(read_sym(args.symfile))
    symbols.sort(key=sort_key)
    with open(args.symfile, 'w') as fp:
        for bank, addr, name in symbols:
            print(f'{bank:02X}:{addr:04X}', name, file=fp)


if __name__ == '__main__':
    main()