gdrom: add gdrom register definitions

This commit is contained in:
Zack Buhman 2024-02-24 17:04:39 +08:00
parent 38b4dda6ab
commit c851070604
7 changed files with 291 additions and 133 deletions

View File

@ -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
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:
find -P \
-regextype posix-egrep \

53
gdrom.hpp Normal file
View 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
View 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",
1 address size name r/w description
2 0018 1 alternate_status R
3 0018 1 device_control W
4 0080 2 data RW
5 0084 1 error R
6 0084 1 features W
7 0088 1 interrupt_reason R
8 0088 1 sector_count W
9 008C 1 sector_number RW
10 0090 1 byte_control_low RW
11 0094 1 byte_control_high RW
12 0098 1 drive_select RW
13 009C 1 status R
14 009C 1 command W

BIN
regs/gdrom.ods Normal file

Binary file not shown.

85
regs/gen/gdrom.py Normal file
View 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())

View File

@ -37,7 +37,7 @@ def size_to_type(size):
def new_writer():
first_address = 0
last_address = 0
next_address = 0
last_block = None
size_total = 0
reserved_num = 0
@ -56,7 +56,7 @@ def new_writer():
def process_row(row):
nonlocal first_address
nonlocal last_address
nonlocal next_address
nonlocal last_block
nonlocal reserved_num
nonlocal size_total
@ -76,14 +76,14 @@ def new_writer():
if block != last_block:
yield from terminate()
first_address = offset_address
last_address = offset_address
next_address = offset_address
size_total = 0
reserved_num = 0
yield f"struct {block.lower()}_reg {{"
if address != last_address:
padding = address - last_address
assert padding > 0, (row, address, last_address)
assert address >= next_address, row
if address > next_address:
padding = address - next_address
type = size_to_type(1)
yield f"{type} _pad{reserved_num}[{padding}];"
reserved_num += 1
@ -101,7 +101,7 @@ def new_writer():
yield field().ljust(27) + f"/* {description} */"
stack.append((address, name))
last_address = address + size
next_address = address + size
last_block = block
size_total += size