95 lines
2.5 KiB
Python
95 lines
2.5 KiB
Python
import sys
|
|
from generate import renderer
|
|
|
|
with open(sys.argv[1], 'r') as f:
|
|
buf = f.read()
|
|
|
|
def split_line(line):
|
|
register_name = line[0:21]
|
|
addr = line[21:44]
|
|
bits = line[44:53]
|
|
description = line[53:]
|
|
return (
|
|
register_name.strip(),
|
|
addr.strip(),
|
|
bits.strip(),
|
|
description.strip()
|
|
)
|
|
|
|
def parse_addr(addr):
|
|
base10, base16 = addr.split()
|
|
base16 = base16.removeprefix('(').removesuffix(')')
|
|
assert int(base10, 10) == int(base16, 16)
|
|
return int(base16, 16)
|
|
|
|
def parse_bits(bits):
|
|
high, low = bits.split(":")
|
|
return int(high, 10), int(low, 10)
|
|
|
|
def parse_lines(buf):
|
|
it = map(split_line, buf.strip().split('\n'))
|
|
header = next(it)
|
|
assert header == ('Register Name', 'Addr', 'Bits', 'Description')
|
|
for register_name, addr, bits, description in it:
|
|
if register_name.lower() == "reserved":
|
|
continue
|
|
addr = parse_addr(addr)
|
|
bits = parse_bits(bits)
|
|
yield register_name, addr, bits, description
|
|
|
|
def bits_length(bits):
|
|
high, low = bits
|
|
assert (high + 1) % 8 == 0 and low == 0
|
|
length = (high + 1) // 8
|
|
return length
|
|
|
|
def reg_type(length):
|
|
if length == 1:
|
|
return "reg8"
|
|
if length == 2:
|
|
return "reg16"
|
|
if length == 3:
|
|
return "reg8"
|
|
if length == 4:
|
|
return "reg32"
|
|
assert False, length
|
|
|
|
def render_struct(buf):
|
|
next_address = 0
|
|
reserved_ix = 0
|
|
yield "struct voodoo2_config {"
|
|
lines = list(parse_lines(buf))
|
|
for register_name, addr, bits, description in lines:
|
|
if addr != next_address:
|
|
yield f"reg8 _reserved{reserved_ix}[{addr - next_address}];"
|
|
reserved_ix += 1
|
|
length = bits_length(bits)
|
|
arr = "" if length != 3 else "[3]"
|
|
yield f"{reg_type(length)} {register_name}{arr};"
|
|
next_address = addr + length
|
|
yield "};"
|
|
yield ""
|
|
for register_name, addr, bits, description in lines:
|
|
length = bits_length(bits)
|
|
arr = "" if length != 3 else "[0]"
|
|
yield f"static_assert((offsetof (struct voodoo2_config, {register_name}{arr})) == 0x{addr:02x});"
|
|
|
|
def render_all(buf):
|
|
yield "#pragma once"
|
|
yield ""
|
|
yield "#include <stddef.h>"
|
|
yield "#include <stdint.h>"
|
|
yield ""
|
|
yield '#include "reg.h"'
|
|
yield ""
|
|
yield from render_struct(buf)
|
|
yield ""
|
|
yield "typedef struct voodoo2_config voodoo2_config;"
|
|
|
|
with open(sys.argv[1], 'r') as f:
|
|
buf = f.read()
|
|
lines = buf.split('\n')
|
|
render, out = renderer()
|
|
render(render_all(buf))
|
|
sys.stdout.write(out.getvalue())
|