regs: add us_disassemble
This commit is contained in:
parent
9b4cc94138
commit
35cd0e07ca
@ -3,6 +3,7 @@ from typing import Union
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
from collections import OrderedDict
|
||||
|
||||
def split_line_fields(line):
|
||||
fields = [0, 17, 24, 32]
|
||||
@ -87,11 +88,22 @@ def aggregate(fields):
|
||||
yield description
|
||||
ix += 1
|
||||
|
||||
def parse_possible_value_num(s):
|
||||
num, description = s.split(' - ')
|
||||
num = int(num, 10)
|
||||
if ": " in description:
|
||||
name, description = description.split(": ")
|
||||
else:
|
||||
name = None
|
||||
return num, (name, description)
|
||||
|
||||
while ix < len(fields):
|
||||
field_name, bits, default, description = fields[ix]
|
||||
description_lines = [description]
|
||||
description_lines.extend(parse_description_lines())
|
||||
possible_values = list(parse_possible_values())
|
||||
possible_values = OrderedDict(
|
||||
map(parse_possible_value_num, parse_possible_values())
|
||||
)
|
||||
|
||||
assert default.startswith('0x'), default
|
||||
yield Descriptor(
|
||||
@ -105,6 +117,7 @@ def aggregate(fields):
|
||||
ix += 1
|
||||
next_nonempty()
|
||||
|
||||
if __name__ == "__main__":
|
||||
l = list(parse_file_fields(sys.argv[1]))
|
||||
for descriptor in aggregate(l):
|
||||
pprint(descriptor, width=200)
|
||||
|
116
regs/us_disassemble.py
Normal file
116
regs/us_disassemble.py
Normal file
@ -0,0 +1,116 @@
|
||||
import parse_bits
|
||||
from pprint import pprint
|
||||
from collections import OrderedDict
|
||||
|
||||
register_names = [
|
||||
"US_CMN_INST",
|
||||
"US_ALU_RGB_ADDR",
|
||||
"US_ALU_ALPHA_ADDR",
|
||||
"US_ALU_RGB_INST",
|
||||
"US_ALU_ALPHA_INST",
|
||||
"US_ALU_RGBA_INST",
|
||||
"US_TEX_INST",
|
||||
"US_TEX_ADDR",
|
||||
"US_TEX_ADDR_DXDY",
|
||||
"US_FC_INST",
|
||||
"US_FC_ADDR",
|
||||
]
|
||||
|
||||
alu_output = [
|
||||
"US_CMN_INST",
|
||||
"US_ALU_RGB_ADDR",
|
||||
"US_ALU_ALPHA_ADDR",
|
||||
"US_ALU_RGB_INST",
|
||||
"US_ALU_ALPHA_INST",
|
||||
"US_ALU_RGBA_INST",
|
||||
]
|
||||
|
||||
tex = [
|
||||
"US_CMN_INST",
|
||||
"US_TEX_INST",
|
||||
"US_TEX_ADDR",
|
||||
"US_TEX_ADDR_DXDY",
|
||||
0,
|
||||
0,
|
||||
]
|
||||
|
||||
fc = [
|
||||
"US_CMN_INST",
|
||||
0,
|
||||
"US_FC_INST",
|
||||
"US_FC_ADDR",
|
||||
0,
|
||||
0,
|
||||
]
|
||||
|
||||
def parse_registers():
|
||||
for register in register_names:
|
||||
filename = register.lower() + ".txt"
|
||||
l = list(parse_bits.parse_file_fields(filename))
|
||||
yield register, OrderedDict(
|
||||
(d.field_name, d) for d in parse_bits.aggregate(l)
|
||||
)
|
||||
|
||||
registers = dict(parse_registers())
|
||||
US_CMN_INST = registers["US_CMN_INST"]
|
||||
|
||||
code = [
|
||||
0x00078005,
|
||||
0x08020080,
|
||||
0x08020080,
|
||||
0x1c9b04d8,
|
||||
0x1c810003,
|
||||
0x00000005,
|
||||
]
|
||||
|
||||
def get_field(n, descriptor):
|
||||
if type(descriptor.bits) is int:
|
||||
return (n >> descriptor.bits) & 1
|
||||
else:
|
||||
high, low = descriptor.bits
|
||||
assert high > low
|
||||
mask_length = (high - low) + 1
|
||||
mask = (1 << mask_length) - 1
|
||||
return (n >> low) & mask
|
||||
|
||||
def get_possible_value(value, descriptor):
|
||||
if not descriptor.possible_values:
|
||||
return value
|
||||
|
||||
name, description = descriptor.possible_values[value]
|
||||
if name is not None:
|
||||
return name
|
||||
else:
|
||||
if len(description) < 20:
|
||||
return description
|
||||
else:
|
||||
return value
|
||||
|
||||
def get_field_pv_name(value, descriptor):
|
||||
return get_possible_value(get_field(value, descriptor), descriptor)
|
||||
|
||||
def disassemble(code, ix):
|
||||
us_cmn_inst = code[ix + 0]
|
||||
print(f"{ix:04x}")
|
||||
max_length = max(map(len, US_CMN_INST.keys())) + 1
|
||||
|
||||
def inner(register_name_list):
|
||||
for i, register_name in enumerate(register_name_list):
|
||||
value = code[ix + i]
|
||||
register = registers[register_name]
|
||||
print(" ", f"{value:08x}", register_name)
|
||||
for d in register.values():
|
||||
field_pv_name = get_field_pv_name(value, d)
|
||||
print(" ", d.field_name.ljust(max_length), field_pv_name)
|
||||
|
||||
inst_type = get_field_pv_name(us_cmn_inst, US_CMN_INST["TYPE"])
|
||||
if inst_type in {"US_INST_TYPE_OUT", "US_INST_TYPE_ALU"}:
|
||||
inner(alu_output)
|
||||
elif inst_type == "US_INST_TYPE_FC":
|
||||
inner(fc)
|
||||
elif inst_type == "US_INST_TYPE_TEX":
|
||||
inner(tex)
|
||||
else:
|
||||
assert False, inst_type
|
||||
|
||||
disassemble(code, 0)
|
Loading…
x
Reference in New Issue
Block a user