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

View File

@ -4,51 +4,51 @@
#include "type.hpp"
struct system_reg {
reg32 C2DSTAT; /* CH2-DMA destination address */
reg32 C2DLEN; /* CH2-DMA length */
reg32 C2DST; /* CH2-DMA start */
reg32 C2DSTAT; /* CH2-DMA destination address */
reg32 C2DLEN; /* CH2-DMA length */
reg32 C2DST; /* CH2-DMA start */
reg8 _pad0[4];
reg32 SDSTAW; /* Sort-DMA start link table address */
reg32 SDBAAW; /* Sort-DMA link base address */
reg32 SDWLT; /* Sort-DMA link address bit width */
reg32 SDLAS; /* Sort-DMA link address shift control */
reg32 SDST; /* Sort-DMA start */
reg32 SDSTAW; /* Sort-DMA start link table address */
reg32 SDBAAW; /* Sort-DMA link base address */
reg32 SDWLT; /* Sort-DMA link address bit width */
reg32 SDLAS; /* Sort-DMA link address shift control */
reg32 SDST; /* Sort-DMA start */
reg8 _pad1[28];
reg32 DBREQM; /* DBREQ# signal mask control */
reg32 BAVLWC; /* BAVL# signal wait count */
reg32 C2DPYRC; /* DMA (TA/Root Bus) priority count */
reg32 DMAXL; /* CH2-DMA maximum burst length */
reg32 DBREQM; /* DBREQ# signal mask control */
reg32 BAVLWC; /* BAVL# signal wait count */
reg32 C2DPYRC; /* DMA (TA/Root Bus) priority count */
reg32 DMAXL; /* CH2-DMA maximum burst length */
reg8 _pad2[48];
reg32 TFREM; /* TA FIFO remaining amount */
reg32 LMMODE0; /* Via TA texture memory bus select 0 */
reg32 LMMODE1; /* Via TA texture memory bus select 1 */
reg32 FFST; /* FIFO status */
reg32 SFRES; /* System reset */
reg32 TFREM; /* TA FIFO remaining amount */
reg32 LMMODE0; /* Via TA texture memory bus select 0 */
reg32 LMMODE1; /* Via TA texture memory bus select 1 */
reg32 FFST; /* FIFO status */
reg32 SFRES; /* System reset */
reg8 _pad3[8];
reg32 SBREV; /* System bus revision number */
reg32 RBSPLT; /* SH4 Root Bus split enable */
reg32 SBREV; /* System bus revision number */
reg32 RBSPLT; /* SH4 Root Bus split enable */
reg8 _pad4[92];
reg32 ISTNRM; /* Normal interrupt status */
reg32 ISTEXT; /* External interrupt status */
reg32 ISTERR; /* Error interrupt status */
reg32 ISTNRM; /* Normal interrupt status */
reg32 ISTEXT; /* External interrupt status */
reg32 ISTERR; /* Error interrupt status */
reg8 _pad5[4];
reg32 IML2NRM; /* Level 2 normal interrupt mask */
reg32 IML2EXT; /* Level 2 external interrupt mask */
reg32 IML2ERR; /* Level 2 error interrupt mask */
reg32 IML2NRM; /* Level 2 normal interrupt mask */
reg32 IML2EXT; /* Level 2 external interrupt mask */
reg32 IML2ERR; /* Level 2 error interrupt mask */
reg8 _pad6[4];
reg32 IML4NRM; /* Level 4 normal interrupt mask */
reg32 IML4EXT; /* Level 4 external interrupt mask */
reg32 IML4ERR; /* Level 4 error interrupt mask */
reg32 IML4NRM; /* Level 4 normal interrupt mask */
reg32 IML4EXT; /* Level 4 external interrupt mask */
reg32 IML4ERR; /* Level 4 error interrupt mask */
reg8 _pad7[4];
reg32 IML6NRM; /* Level 6 normal interrupt mask */
reg32 IML6EXT; /* Level 6 external interrupt mask */
reg32 IML6ERR; /* Level 6 error interrupt mask */
reg32 IML6NRM; /* Level 6 normal interrupt mask */
reg32 IML6EXT; /* Level 6 external interrupt mask */
reg32 IML6ERR; /* Level 6 error interrupt mask */
reg8 _pad8[4];
reg32 PDTNRM; /* Normal interrupt PVR-DMA startup mask */
reg32 PDTEXT; /* External interrupt PVR-DMA startup mask */
reg32 PDTNRM; /* Normal interrupt PVR-DMA startup mask */
reg32 PDTEXT; /* External interrupt PVR-DMA startup mask */
reg8 _pad9[8];
reg32 G2DTNRM; /* Normal interrupt G2-DMA startup mask */
reg32 G2DTEXT; /* External interrupt G2-DMA startup mask */
reg32 G2DTNRM; /* Normal interrupt G2-DMA startup mask */
reg32 G2DTEXT; /* External interrupt G2-DMA startup mask */
};
static_assert((offsetof (struct system_reg, C2DSTAT)) == 0x0);
@ -89,22 +89,22 @@ static_assert((offsetof (struct system_reg, G2DTEXT)) == 0x154);
struct maple_if_reg {
reg8 _pad0[4];
reg32 MDSTAR; /* Maple-DMA command table address */
reg32 MDSTAR; /* Maple-DMA command table address */
reg8 _pad1[8];
reg32 MDTSEL; /* Maple-DMA trigger select */
reg32 MDEN; /* Maple-DMA enable */
reg32 MDST; /* Maple-DMA start */
reg32 MDTSEL; /* Maple-DMA trigger select */
reg32 MDEN; /* Maple-DMA enable */
reg32 MDST; /* Maple-DMA start */
reg8 _pad2[100];
reg32 MSYS; /* Maple system control */
reg32 MST; /* Maple status */
reg32 MSHTCL; /* Maple-DMA hard trigger clear */
reg32 MDAPRO; /* Maple-DMA address range */
reg32 MSYS; /* Maple system control */
reg32 MST; /* Maple status */
reg32 MSHTCL; /* Maple-DMA hard trigger clear */
reg32 MDAPRO; /* Maple-DMA address range */
reg8 _pad3[88];
reg32 MMSEL; /* Maple MSP selection */
reg32 MMSEL; /* Maple MSP selection */
reg8 _pad4[8];
reg32 MTXDAD; /* Maple TXD address counter */
reg32 MRXDAD; /* Maple RXD address counter */
reg32 MRXDBD; /* Maple RXD address base */
reg32 MTXDAD; /* Maple TXD address counter */
reg32 MRXDAD; /* Maple RXD address counter */
reg32 MRXDBD; /* Maple RXD address base */
};
static_assert((offsetof (struct maple_if_reg, MDSTAR)) == 0x4);
@ -122,29 +122,29 @@ static_assert((offsetof (struct maple_if_reg, MRXDBD)) == 0xfc);
struct g1_if_reg {
reg8 _pad0[4];
reg32 GDSTAR; /* GD-DMA start address */
reg32 GDLEN; /* GD-DMA length */
reg32 GDDIR; /* GD-DMA direction */
reg32 GDSTAR; /* GD-DMA start address */
reg32 GDLEN; /* GD-DMA length */
reg32 GDDIR; /* GD-DMA direction */
reg8 _pad1[4];
reg32 GDEN; /* GD-DMA enable */
reg32 GDST; /* GD-DMA start */
reg32 GDEN; /* GD-DMA enable */
reg32 GDST; /* GD-DMA start */
reg8 _pad2[100];
reg32 G1RRC; /* System ROM read access timing */
reg32 G1RWC; /* System ROM write access timing */
reg32 G1FRC; /* Flash ROM read access timing */
reg32 G1FWC; /* Flash ROM write access timing */
reg32 G1CRC; /* GD PIO read access timing */
reg32 G1CWC; /* GD PIO write access timing */
reg32 G1RRC; /* System ROM read access timing */
reg32 G1RWC; /* System ROM write access timing */
reg32 G1FRC; /* Flash ROM read access timing */
reg32 G1FWC; /* Flash ROM write access timing */
reg32 G1CRC; /* GD PIO read access timing */
reg32 G1CWC; /* GD PIO write access timing */
reg8 _pad3[8];
reg32 G1GDRC; /* GD-DMA read access timing */
reg32 G1GDWC; /* GD-DMA write access timing */
reg32 G1GDRC; /* GD-DMA read access timing */
reg32 G1GDWC; /* GD-DMA write access timing */
reg8 _pad4[8];
reg32 G1SYSM; /* System mode */
reg32 G1CRDYC; /* G1IORDY signal control */
reg32 GDAPRO; /* GD-DMA address range */
reg32 G1SYSM; /* System mode */
reg32 G1CRDYC; /* G1IORDY signal control */
reg32 GDAPRO; /* GD-DMA address range */
reg8 _pad5[56];
reg32 GDSTARD; /* GD-DMA address count (on Root Bus) */
reg32 GDLEND; /* GD-DMA transfer counter */
reg32 GDSTARD; /* GD-DMA address count (on Root Bus) */
reg32 GDLEND; /* GD-DMA transfer counter */
};
static_assert((offsetof (struct g1_if_reg, GDSTAR)) == 0x4);
@ -167,61 +167,61 @@ static_assert((offsetof (struct g1_if_reg, GDSTARD)) == 0xf4);
static_assert((offsetof (struct g1_if_reg, GDLEND)) == 0xf8);
struct g2_if_reg {
reg32 ADSTAG; /* ACIA:G2-DMA G2 start address */
reg32 ADSTAR; /* ACIA:G2-DMA system memory start address */
reg32 ADLEN; /* ACIA:G2-DMA length */
reg32 ADDIR; /* ACIA:G2-DMA direction */
reg32 ADTSEL; /* ACIA:G2-DMA trigger select */
reg32 ADEN; /* ACIA:G2-DMA enable */
reg32 ADST; /* ACIA:G2-DMA start */
reg32 ADSUSP; /* ACIA:G2-DMA suspend */
reg32 E1STAG; /* Ext1:G2-DMA start address */
reg32 E1STAR; /* Ext1:G2-DMA system memory start address */
reg32 E1LEN; /* Ext1:G2-DMA length */
reg32 E1DIR; /* Ext1:G2-DMA direction */
reg32 E1TSEL; /* Ext1:G2-DMA trigger select */
reg32 E1EN; /* Ext1:G2-DMA enable */
reg32 E1ST; /* Ext1:G2-DMA start */
reg32 E1SUSP; /* Ext1:G2-DMA suspend */
reg32 E2STAG; /* Ext2:G2-DMA start address */
reg32 E2STAR; /* Ext2:G2-DMA system memory start address */
reg32 E2LEN; /* Ext2:G2-DMA length */
reg32 E2DIR; /* Ext2:G2-DMA direction */
reg32 E2TSEL; /* Ext2:G2-DMA trigger select */
reg32 E2EN; /* Ext2:G2-DMA enable */
reg32 E2ST; /* Ext2:G2-DMA start */
reg32 E2SUSP; /* Ext2:G2-DMA suspend */
reg32 DDSTAG; /* Dev:G2-DMA start address */
reg32 DDSTAR; /* Dev:G2-DMA system memory start address */
reg32 DDLEN; /* Dev:G2-DMA length */
reg32 DDDIR; /* Dev:G2-DMA direction */
reg32 DDTSEL; /* Dev:G2-DMA trigger select */
reg32 DDEN; /* Dev:G2-DMA enable */
reg32 DDST; /* Dev:G2-DMA start */
reg32 DDSUSP; /* Dev:G2-DMA suspend */
reg32 G2ID; /* G2 bus version */
reg32 ADSTAG; /* ACIA:G2-DMA G2 start address */
reg32 ADSTAR; /* ACIA:G2-DMA system memory start address */
reg32 ADLEN; /* ACIA:G2-DMA length */
reg32 ADDIR; /* ACIA:G2-DMA direction */
reg32 ADTSEL; /* ACIA:G2-DMA trigger select */
reg32 ADEN; /* ACIA:G2-DMA enable */
reg32 ADST; /* ACIA:G2-DMA start */
reg32 ADSUSP; /* ACIA:G2-DMA suspend */
reg32 E1STAG; /* Ext1:G2-DMA start address */
reg32 E1STAR; /* Ext1:G2-DMA system memory start address */
reg32 E1LEN; /* Ext1:G2-DMA length */
reg32 E1DIR; /* Ext1:G2-DMA direction */
reg32 E1TSEL; /* Ext1:G2-DMA trigger select */
reg32 E1EN; /* Ext1:G2-DMA enable */
reg32 E1ST; /* Ext1:G2-DMA start */
reg32 E1SUSP; /* Ext1:G2-DMA suspend */
reg32 E2STAG; /* Ext2:G2-DMA start address */
reg32 E2STAR; /* Ext2:G2-DMA system memory start address */
reg32 E2LEN; /* Ext2:G2-DMA length */
reg32 E2DIR; /* Ext2:G2-DMA direction */
reg32 E2TSEL; /* Ext2:G2-DMA trigger select */
reg32 E2EN; /* Ext2:G2-DMA enable */
reg32 E2ST; /* Ext2:G2-DMA start */
reg32 E2SUSP; /* Ext2:G2-DMA suspend */
reg32 DDSTAG; /* Dev:G2-DMA start address */
reg32 DDSTAR; /* Dev:G2-DMA system memory start address */
reg32 DDLEN; /* Dev:G2-DMA length */
reg32 DDDIR; /* Dev:G2-DMA direction */
reg32 DDTSEL; /* Dev:G2-DMA trigger select */
reg32 DDEN; /* Dev:G2-DMA enable */
reg32 DDST; /* Dev:G2-DMA start */
reg32 DDSUSP; /* Dev:G2-DMA suspend */
reg32 G2ID; /* G2 bus version */
reg8 _pad0[12];
reg32 G2DSTO; /* G2/DS timeout */
reg32 G2TRTO; /* G2/TR timeout */
reg32 G2MDMTO; /* Modem unit wait timeout */
reg32 G2MDMW; /* Modem unit wait time */
reg32 G2DSTO; /* G2/DS timeout */
reg32 G2TRTO; /* G2/TR timeout */
reg32 G2MDMTO; /* Modem unit wait timeout */
reg32 G2MDMW; /* Modem unit wait time */
reg8 _pad1[28];
reg32 G2APRO; /* G2-DMA address range */
reg32 ADSTAGD; /* AICA-DMA address counter (on AICA) */
reg32 ADSTARD; /* AICA-DMA address counter (on root bus) */
reg32 ADLEND; /* AICA-DMA transfer counter */
reg32 G2APRO; /* G2-DMA address range */
reg32 ADSTAGD; /* AICA-DMA address counter (on AICA) */
reg32 ADSTARD; /* AICA-DMA address counter (on root bus) */
reg32 ADLEND; /* AICA-DMA transfer counter */
reg8 _pad2[4];
reg32 E1STAGD; /* Ext-DMA1 address counter (on Ext) */
reg32 E1STARD; /* Ext-DMA1 address counter (on root bus) */
reg32 E1LEND; /* Ext-DMA1 transfer counter */
reg32 E1STAGD; /* Ext-DMA1 address counter (on Ext) */
reg32 E1STARD; /* Ext-DMA1 address counter (on root bus) */
reg32 E1LEND; /* Ext-DMA1 transfer counter */
reg8 _pad3[4];
reg32 E2STAGD; /* Ext-DMA2 address counter (on Ext) */
reg32 E2STARD; /* Ext-DMA2 address counter (on root bus) */
reg32 E2LEND; /* Ext-DMA2 transfer counter */
reg32 E2STAGD; /* Ext-DMA2 address counter (on Ext) */
reg32 E2STARD; /* Ext-DMA2 address counter (on root bus) */
reg32 E2LEND; /* Ext-DMA2 transfer counter */
reg8 _pad4[4];
reg32 DDSTAGD; /* Dev-DMA address counter (on Dev) */
reg32 DDSTARD; /* Dev-DMA address counter (on root bus) */
reg32 DDLEND; /* Dev-DMA transfer counter */
reg32 DDSTAGD; /* Dev-DMA address counter (on Dev) */
reg32 DDSTARD; /* Dev-DMA address counter (on root bus) */
reg32 DDLEND; /* Dev-DMA transfer counter */
};
static_assert((offsetof (struct g2_if_reg, ADSTAG)) == 0x0);
@ -276,19 +276,19 @@ static_assert((offsetof (struct g2_if_reg, DDSTARD)) == 0xf4);
static_assert((offsetof (struct g2_if_reg, DDLEND)) == 0xf8);
struct pvr_if_reg {
reg32 PDSTAP; /* PVR-DMA start address */
reg32 PDSTAR; /* PVR-DMA system memory start address */
reg32 PDLEN; /* PVR-DMA length */
reg32 PDDIR; /* PVR-DMA direction */
reg32 PDTSEL; /* PVR-DMA trigger select */
reg32 PDEN; /* PVR-DMA enable */
reg32 PDST; /* PVR-DMA start */
reg32 PDSTAP; /* PVR-DMA start address */
reg32 PDSTAR; /* PVR-DMA system memory start address */
reg32 PDLEN; /* PVR-DMA length */
reg32 PDDIR; /* PVR-DMA direction */
reg32 PDTSEL; /* PVR-DMA trigger select */
reg32 PDEN; /* PVR-DMA enable */
reg32 PDST; /* PVR-DMA start */
reg8 _pad0[100];
reg32 PDAPRO; /* PVR-DMA address range */
reg32 PDAPRO; /* PVR-DMA address range */
reg8 _pad1[108];
reg32 PDSTAPD; /* PVR-DMA address counter (on Ext) */
reg32 PDSTARD; /* PVR-DMA address counter (on root bus) */
reg32 PDLEND; /* PVR-DMA transfer counter */
reg32 PDSTAPD; /* PVR-DMA address counter (on Ext) */
reg32 PDSTARD; /* PVR-DMA address counter (on root bus) */
reg32 PDLEND; /* PVR-DMA transfer counter */
};
static_assert((offsetof (struct pvr_if_reg, PDSTAP)) == 0x0);