Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/tools/rasm2armips.py
7854 views
1
#!/usr/bin/env python
2
3
import argparse
4
import re
5
import sys
6
7
def read_file(filepath):
8
with open(filepath) as f:
9
lines = f.readlines()
10
split_lines = [re.split(r'[ ,]+', l.strip().replace('$', '')) for l in lines]
11
return split_lines
12
13
# jumps and branches with named targets
14
jumps = ['jal', 'j']
15
branches = ['beq', 'bgez', 'bgtz', 'blez', 'bltz', 'bne']
16
jump_branches = jumps + branches
17
# jumps and branches with delay slots
18
has_delay_slot = jump_branches + ['jr']
19
20
def decode_references(instructions):
21
refs = []
22
for ins in instructions:
23
if ins[3] in jump_branches:
24
target = int(ins[-1], 0)
25
if target not in refs:
26
refs.append(target)
27
return refs
28
29
def reassemble(args, instructions, refs):
30
print('.rsp')
31
print('\n.create DATA_FILE, 0x%04X' % 0x0000)
32
print('\n.close // DATA_FILE\n')
33
print('.create CODE_FILE, 0x%08X\n' % args.base)
34
delay_slot = False
35
for ins in instructions:
36
addr = int(ins[0], 0)
37
if (addr & 0xFFFF) in refs:
38
print('%s_%08x:' % (args.name, addr))
39
sys.stdout.write(' ' * args.indent)
40
if delay_slot:
41
sys.stdout.write(' ')
42
delay_slot = False
43
if ins[3] in jumps:
44
target = int(ins[-1], 0) | (args.base & 0xFFFF0000)
45
ins[-1] = '%s_%08x' % (args.name, target)
46
elif ins[3] in branches:
47
if ins[3][-1] =='z' and ins[5] == 'zero':
48
del ins[5] # remove 'zero' operand from branch
49
target = (int(ins[-1], 0) & 0x1FFF) + (args.base & 0xFFFF0000)
50
ins[-1] = '%s_%08x' % (args.name, target)
51
elif ins[3] == 'vsar': # fixup last operand of vsar
52
reg_map = {'ACC_H': 0, 'ACC_M': 1, 'ACC_L': 2}
53
reg = ins[4].split(r'[')[0]
54
num = reg_map[ins[-1]]
55
ins[-1] = '%s[%d]' % (reg, num)
56
if ins[3] in has_delay_slot:
57
delay_slot = True
58
if len(ins) > 4: # with args
59
print('%-5s %s' % (ins[3], ', '.join(ins[4:])))
60
else:
61
print('%s' % ins[3])
62
print('\n.close // CODE_FILE')
63
64
def main():
65
parser = argparse.ArgumentParser()
66
parser.add_argument('input_file', help="input assembly file generated from `rasm2 -D -e -a rsp -B -o 0x04001000 -f`")
67
parser.add_argument('-b', type=int, help="base address of file", dest='base', default=0x04001000)
68
parser.add_argument('-i', type=int, help="amount of indentation", dest='indent', default=4)
69
parser.add_argument('-n', help="name to prefex labels with", dest='name', default='f3d')
70
args = parser.parse_args()
71
72
lines = read_file(args.input_file)
73
refs = decode_references(lines)
74
reassemble(args, lines, refs)
75
76
main()
77
78