gdrom: add gdrom register definitions
This commit is contained in:
parent
38b4dda6ab
commit
c851070604
@ -161,6 +161,12 @@ sh7091/sh7091.hpp: regs/sh7091.csv regs/gen/sh7091.py
|
|||||||
sh7091/sh7091_bits.hpp: regs/sh7091_bits.csv regs/gen/core_bits.py
|
sh7091/sh7091_bits.hpp: regs/sh7091_bits.csv regs/gen/core_bits.py
|
||||||
python regs/gen/core_bits.py $< > $@
|
python regs/gen/core_bits.py $< > $@
|
||||||
|
|
||||||
|
systembus.hpp: regs/systembus.csv regs/gen/systembus.py
|
||||||
|
python regs/gen/systembus.py $< > $@
|
||||||
|
|
||||||
|
gdrom.hpp: regs/gdrom.csv regs/gen/gdrom.py
|
||||||
|
python regs/gen/gdrom.py $< > $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
find -P \
|
find -P \
|
||||||
-regextype posix-egrep \
|
-regextype posix-egrep \
|
||||||
|
53
gdrom.hpp
Normal file
53
gdrom.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "type.hpp"
|
||||||
|
|
||||||
|
struct gdrom_if_reg {
|
||||||
|
const reg8 _pad0[24];
|
||||||
|
union {
|
||||||
|
const reg8 alternate_status;
|
||||||
|
reg8 device_control;
|
||||||
|
};
|
||||||
|
const reg8 _pad1[103];
|
||||||
|
reg16 data;
|
||||||
|
const reg8 _pad2[2];
|
||||||
|
union {
|
||||||
|
const reg8 error;
|
||||||
|
reg8 features;
|
||||||
|
};
|
||||||
|
const reg8 _pad3[3];
|
||||||
|
union {
|
||||||
|
const reg8 interrupt_reason;
|
||||||
|
reg8 sector_count;
|
||||||
|
};
|
||||||
|
const reg8 _pad4[3];
|
||||||
|
reg8 sector_number;
|
||||||
|
const reg8 _pad5[3];
|
||||||
|
reg8 byte_control_low;
|
||||||
|
const reg8 _pad6[3];
|
||||||
|
reg8 byte_control_high;
|
||||||
|
const reg8 _pad7[3];
|
||||||
|
reg8 drive_select;
|
||||||
|
const reg8 _pad8[3];
|
||||||
|
union {
|
||||||
|
const reg8 status;
|
||||||
|
reg8 command;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, alternate_status)) == 24);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, device_control)) == 24);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, data)) == 128);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, error)) == 132);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, features)) == 132);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, interrupt_reason)) == 136);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, sector_count)) == 136);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, sector_number)) == 140);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, byte_control_low)) == 144);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, byte_control_high)) == 148);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, drive_select)) == 152);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, status)) == 156);
|
||||||
|
static_assert((offsetof (struct gdrom_if_reg, command)) == 156);
|
||||||
|
|
||||||
|
extern struct gdrom_if_reg gdrom_if __asm("gdrom_if");
|
14
regs/gdrom.csv
Normal file
14
regs/gdrom.csv
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"address","size","name","r/w","description"
|
||||||
|
"0018","1","alternate_status","R",
|
||||||
|
"0018","1","device_control","W",
|
||||||
|
"0080","2","data","RW",
|
||||||
|
"0084","1","error","R",
|
||||||
|
"0084","1","features","W",
|
||||||
|
"0088","1","interrupt_reason","R",
|
||||||
|
"0088","1","sector_count","W",
|
||||||
|
"008C","1","sector_number","RW",
|
||||||
|
"0090","1","byte_control_low","RW",
|
||||||
|
"0094","1","byte_control_high","RW",
|
||||||
|
"0098","1","drive_select","RW",
|
||||||
|
"009C","1","status","R",
|
||||||
|
"009C","1","command","W",
|
|
BIN
regs/gdrom.ods
Normal file
BIN
regs/gdrom.ods
Normal file
Binary file not shown.
85
regs/gen/gdrom.py
Normal file
85
regs/gen/gdrom.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from sh7091 import read_input, size_to_type, headers
|
||||||
|
from generate import renderer
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Register:
|
||||||
|
address: int
|
||||||
|
name: str
|
||||||
|
size: int
|
||||||
|
rw: set[str]
|
||||||
|
|
||||||
|
def group_by_address(rows):
|
||||||
|
_rw = defaultdict(set)
|
||||||
|
_size = dict()
|
||||||
|
_groups = defaultdict(list)
|
||||||
|
|
||||||
|
def process_row(row):
|
||||||
|
address = int(row["address"], 16)
|
||||||
|
name = row["name"]
|
||||||
|
size = int(row["size"], 10)
|
||||||
|
rw = set(row["r/w"].upper())
|
||||||
|
|
||||||
|
if address not in _size:
|
||||||
|
_size[address] = size
|
||||||
|
assert _size[address] == size, row
|
||||||
|
assert _rw[address].intersection(rw) == set(), row
|
||||||
|
_groups[address].append(Register(
|
||||||
|
address=address,
|
||||||
|
name=name,
|
||||||
|
size=size,
|
||||||
|
rw=rw
|
||||||
|
))
|
||||||
|
|
||||||
|
_ = list(map(process_row, rows))
|
||||||
|
|
||||||
|
return list(sorted(_groups.items(), key=lambda kv: kv[0]))
|
||||||
|
|
||||||
|
def render_groups(groups):
|
||||||
|
next_address = 0
|
||||||
|
reserved_num = 0
|
||||||
|
|
||||||
|
yield "struct gdrom_if_reg {"
|
||||||
|
|
||||||
|
for address, group in groups:
|
||||||
|
assert address >= next_address
|
||||||
|
if address > next_address:
|
||||||
|
padding = address - next_address
|
||||||
|
type = size_to_type(1)
|
||||||
|
yield f"const {type} _pad{reserved_num}[{padding}];"
|
||||||
|
reserved_num += 1
|
||||||
|
|
||||||
|
if len(group) > 1:
|
||||||
|
yield "union {"
|
||||||
|
|
||||||
|
for reg in group:
|
||||||
|
type = size_to_type(reg.size)
|
||||||
|
const = "const " if reg.rw == {'R'} else ""
|
||||||
|
yield f"{const}{type} {reg.name};"
|
||||||
|
|
||||||
|
if len(group) > 1:
|
||||||
|
yield "};" # end of union
|
||||||
|
|
||||||
|
next_address = address + group[0].size
|
||||||
|
|
||||||
|
yield "};"
|
||||||
|
|
||||||
|
|
||||||
|
for address, group in groups:
|
||||||
|
for reg in group:
|
||||||
|
yield f"static_assert((offsetof (struct gdrom_if_reg, {reg.name})) == {reg.address});"
|
||||||
|
|
||||||
|
yield ""
|
||||||
|
yield 'extern struct gdrom_if_reg gdrom_if __asm("gdrom_if");'
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
input_file = sys.argv[1]
|
||||||
|
rows = read_input(input_file)
|
||||||
|
groups = group_by_address(rows)
|
||||||
|
render, out = renderer()
|
||||||
|
render(headers())
|
||||||
|
render(render_groups(groups))
|
||||||
|
sys.stdout.write(out.getvalue())
|
@ -37,7 +37,7 @@ def size_to_type(size):
|
|||||||
|
|
||||||
def new_writer():
|
def new_writer():
|
||||||
first_address = 0
|
first_address = 0
|
||||||
last_address = 0
|
next_address = 0
|
||||||
last_block = None
|
last_block = None
|
||||||
size_total = 0
|
size_total = 0
|
||||||
reserved_num = 0
|
reserved_num = 0
|
||||||
@ -56,7 +56,7 @@ def new_writer():
|
|||||||
|
|
||||||
def process_row(row):
|
def process_row(row):
|
||||||
nonlocal first_address
|
nonlocal first_address
|
||||||
nonlocal last_address
|
nonlocal next_address
|
||||||
nonlocal last_block
|
nonlocal last_block
|
||||||
nonlocal reserved_num
|
nonlocal reserved_num
|
||||||
nonlocal size_total
|
nonlocal size_total
|
||||||
@ -76,14 +76,14 @@ def new_writer():
|
|||||||
if block != last_block:
|
if block != last_block:
|
||||||
yield from terminate()
|
yield from terminate()
|
||||||
first_address = offset_address
|
first_address = offset_address
|
||||||
last_address = offset_address
|
next_address = offset_address
|
||||||
size_total = 0
|
size_total = 0
|
||||||
reserved_num = 0
|
reserved_num = 0
|
||||||
yield f"struct {block.lower()}_reg {{"
|
yield f"struct {block.lower()}_reg {{"
|
||||||
|
|
||||||
if address != last_address:
|
assert address >= next_address, row
|
||||||
padding = address - last_address
|
if address > next_address:
|
||||||
assert padding > 0, (row, address, last_address)
|
padding = address - next_address
|
||||||
type = size_to_type(1)
|
type = size_to_type(1)
|
||||||
yield f"{type} _pad{reserved_num}[{padding}];"
|
yield f"{type} _pad{reserved_num}[{padding}];"
|
||||||
reserved_num += 1
|
reserved_num += 1
|
||||||
@ -101,7 +101,7 @@ def new_writer():
|
|||||||
yield field().ljust(27) + f"/* {description} */"
|
yield field().ljust(27) + f"/* {description} */"
|
||||||
|
|
||||||
stack.append((address, name))
|
stack.append((address, name))
|
||||||
last_address = address + size
|
next_address = address + size
|
||||||
last_block = block
|
last_block = block
|
||||||
size_total += size
|
size_total += size
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user