summaryrefslogtreecommitdiff
path: root/tools/fix_sections.py
blob: dc23f524bbda23114b677b21745eaff2339c0c73 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import os, errno
import re
import fix_sections_directory

os.chdir("..")
cwd = os.getcwd()

debug_lines_startswith = [
    "SECTION ",
    "else",
    "SECTION ",
    "endc"
]

with open("pokegold-spaceworld-gen.link", "r") as f:
    linkerscript = f.read()

def clean_section(line, file, multiple):
    global linkerscript
    lines = line.lstrip().split("\"")
    if "@" in lines[1] or file == lines[1] or file == "hram.asm" or file == "vram.asm" or file == "sram.asm":
        file = lines[1]
    else:
        file += ("@" + lines[1]) if multiple else ""
    
    linkerscript = linkerscript.replace("\"" + lines[1] + "\"", "\"" + file + "\"")
    if "ROMX" in lines[2]:
        return "SECTION \"%s\", ROMX" % file
    elif "HRAM" in lines[2]:
        return "SECTION \"%s\", HRAM" % file
    elif "VRAM" in lines[2]:
        return "SECTION \"%s\", VRAM" % file
    elif "ROM0" in lines[2]:
        return "SECTION \"%s\", ROM0" % file
    elif "SRAM" in lines[2]:
        return "SECTION \"%s\", SRAM" % file
    else:
        raise

TEMP_PATH = fix_sections_directory.TEMP_DIRECTORY

for root, dirs, files in os.walk(cwd):
    for file in files:
        rel_root = os.path.relpath(root, cwd)
        if not rel_root.startswith("build") and not rel_root.startswith("temp") and file.endswith(".asm") and file != "rst.asm" and file != "wram.asm" and file != "zero_checksum.asm":
            canonical_path = os.path.join(root, file)
            rel_path = os.path.relpath(canonical_path, cwd)
            with open(canonical_path, "r") as f:
                contents = f.read()
            content_lines = contents.splitlines()
            
            if "SECTION" in contents:
                print(canonical_path)
                modify_flag = False
                skip_next_line = False
                for i, line in enumerate(content_lines):
                    if not skip_next_line:
                        if line.lstrip().startswith("SECTION"):
                            modify_flag = True
                            content_lines[i] = clean_section(content_lines[i], rel_path, contents.count("SECTION") > 1)
                        elif "if DEBUG" in line:
                            debug_content_lines = content_lines[i+1:i+5]
                            debug_code = False
                            for debug_content_line, debug_line_startswith in zip(debug_content_lines, debug_lines_startswith):
                                if not debug_content_line.lstrip().startswith(debug_line_startswith):
                                    break
                            else:
                                modify_flag = True
                                content_lines[i] = "; " + content_lines[i]
                                content_lines[i+1] = clean_section(content_lines[i+1], rel_path, contents.count("SECTION") > 2)
                                content_lines[i+2] = "; " + content_lines[i+2]
                                content_lines[i+3] = "; " + content_lines[i+3]
                                content_lines[i+4] = "; " + content_lines[i+4]
                                skip_next_line = True
                    else:
                        skip_next_line = False
                
                if modify_flag:
                    output = "\n".join(content_lines)
                    print("rel root: " + rel_root)
                    try:
                        os.makedirs(TEMP_PATH + rel_root)
                    except OSError as e:
                        if e.errno != errno.EEXIST:
                            raise
                    
                    with open(TEMP_PATH + rel_path, "w+") as f:
                        f.write(output)

linkerscript_lines = linkerscript.splitlines()

i = 0
clean_wram = False

while i < len(linkerscript_lines):
    line = linkerscript_lines[i]
    if clean_wram:
        if "org $dfff" not in line:
            print(linkerscript_lines.pop(i))
        else:
            clean_wram = False
            i += 1
    elif "\"Shim for " in line:
        no_pop_count = 0
        shim_addr = line.replace(", ", " ; ").split(" ; ")[1]
        if linkerscript_lines[i-1] == "\torg " + shim_addr and linkerscript_lines[i-1] != "\torg $4000":
            print(linkerscript_lines.pop(i-1))
        else:
            no_pop_count += 1
        print(linkerscript_lines.pop(i-1 + no_pop_count))
        
        if linkerscript_lines[i-1 + no_pop_count] == "\t; " + shim_addr:
            print(linkerscript_lines.pop(i-1 + no_pop_count))
        else:
            no_pop_count += 1
        
        i -= 3 - no_pop_count
        print("")
    elif "ROMX" in line and "org $4000" not in linkerscript_lines[i+1]:
        linkerscript_lines.insert(i+1, "\torg $4000")
        i += 1
    elif line.startswith("WRAM0"):
        linkerscript_lines.insert(i+1, "\torg $c000")
        i += 1
    elif "\"Map Buffer\"" in line:
        clean_wram = True
        i += 1
    else:
        i += 1

for i in range(len(linkerscript_lines)):
    linkerscript_lines[i] = linkerscript_lines[i].split(" ; ")[0]

linkerscript = "\n".join(linkerscript_lines) + "\n"

with open(TEMP_PATH + "pokegold-spaceworld.link", "w+") as f:
    f.write(linkerscript)