diff --git a/dreamcast2/Makefile b/dreamcast2/Makefile index 6f0774a..5f4be2d 100644 --- a/dreamcast2/Makefile +++ b/dreamcast2/Makefile @@ -1,30 +1,9 @@ -%.csv: %.ods - libreoffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":44,34,76,,,,true --outdir $(dir $@) $< +include base.mk +OPT = -O2 -# HOLLY +MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST))))) +CFLAGS += -I$(MAKEFILE_PATH) +LIB ?= $(MAKEFILE_PATH) -holly/holly.hpp: regs/holly/holly.csv regs/holly.py - python regs/holly.py $< > $@ - -holly/holly_bits.hpp: regs/holly/holly_bits.csv regs/holly_bits.py - python regs/holly_bits.py $< holly > $@ - -holly/region_array_bits.hpp: regs/holly/region_array_bits.csv regs/holly_bits.py - python regs/holly_bits.py $< holly region_array > $@ - -# SH7091 - -sh7091/sh7091.hpp: regs/sh7091/sh7091.csv regs/sh7091.py - python regs/sh7091.py $< > $@ - -sh7091/sh7091_bits.hpp: regs/sh7091/sh7091_bits.csv regs/holly_bits.py - python regs/holly_bits.py $< sh7091 > $@ - -# SYSTEMBUS - -systembus/systembus.hpp: regs/systembus/systembus.csv regs/holly.py - python regs/holly.py $< > $@ - -systembus/systembus_bits.hpp: regs/systembus/systembus_bits.csv regs/holly_bits.py - python regs/holly_bits.py $< system > $@ +include example/example.mk diff --git a/dreamcast2/addresses.lds b/dreamcast2/addresses.lds new file mode 100644 index 0000000..1cd560c --- /dev/null +++ b/dreamcast2/addresses.lds @@ -0,0 +1,32 @@ +system_boot_rom = 0xa0000000; + +system = 0xa05f6800; +maple_if = 0xa05f6c00; +gdrom_if = 0xa05f7000; +g1_if = 0xa05f7400; +g2_if = 0xa05f7800; +pvr_if = 0xa05f7c00; +holly = 0xa05f8000; +modem = 0xa0600000; +aica_sound = 0xa0700000; +aica_rtc = 0xa0710000; + +system_boot_rom = 0xa0000000; +aica_wave_memory = 0xa0800000; +texture_memory64 = 0xa4000000; +texture_memory32 = 0xa5000000; +system_memory = 0xac000000; +ta_fifo_polygon_converter = 0x10000000; +ta_fifo_yuv_converter = 0x10800000; +ta_fifo_texture_memory = 0x11000000; +ta_fifo_polygon_converter_mirror = 0x12000000; +ta_fifo_yuv_converter_mirror = 0x12800000; +ta_fifo_texture_memory_mirror = 0x13000000; + +store_queue = 0xe0000000; + +sh7091_ic_a = 0xf0000000; +sh7091_ic_d = 0xf1000000; +sh7091_oc_a = 0xf4000000; +sh7091_oc_d = 0xf5000000; +sh7091 = 0xff000000; diff --git a/dreamcast2/base.mk b/dreamcast2/base.mk new file mode 100644 index 0000000..6af92e5 --- /dev/null +++ b/dreamcast2/base.mk @@ -0,0 +1,74 @@ +################################################################################ +# architecture flags +################################################################################ + +AARCH = --isa=sh4 --little + +CARCH ?= -m4-single-only -ml +CFLAGS += -mfsca -mfsrra -funsafe-math-optimizations -ffast-math + +OBJARCH = -O elf32-shl -B sh4 + +TARGET = sh4-none-elf- + +################################################################################ +# architecture-agnostic flags +################################################################################ + +DEBUG = -g -gdwarf-4 + +AFLAGS += --fatal-warnings + +CSTD ?= -std=gnu23 + +CXXSTD ?= -std=c++23 + +CFLAGS += -ffreestanding -nostdlib -fno-builtin +CFLAGS += -falign-functions=4 +CFLAGS += -ffunction-sections -fdata-sections -fshort-enums +CFLAGS += -Wall -Werror -Wfatal-errors -Winline +CFLAGS += -Wno-array-bounds +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=unused-variable +CFLAGS += -Wno-error=unused-function +CFLAGS += -D__dreamcast__ + +CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics + +LDFLAGS += --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error + +DEPFLAGS = -MMD -MP + +################################################################################ +# toolchain +################################################################################ + +CC = $(TARGET)gcc +CXX = $(TARGET)g++ +AS = $(TARGET)as +LD = $(TARGET)ld +OBJCOPY = $(TARGET)objcopy +OBJDUMP = $(TARGET)objdump + +################################################################################ +# base rules +################################################################################ + +%.o: %.s + $(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@ + +%.o: %.c + $(CC) $(CARCH) $(CFLAGS) $(CSTD) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ + +%.o: %.cpp + $(CXX) $(CARCH) $(CFLAGS) $(CXXSTD) $(CXXFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ + +%.elf: + $(LD) $(LDFLAGS) -L $(LIB) -T $(LDSCRIPT) $^ -o $@ + +%.bin: %.elf + $(OBJCOPY) -O binary $< $@ + du -b $@ + +-include $(shell find -type f -name '*.d') diff --git a/dreamcast2/binary.mk b/dreamcast2/binary.mk new file mode 100644 index 0000000..1e6ddc2 --- /dev/null +++ b/dreamcast2/binary.mk @@ -0,0 +1,29 @@ +define BUILD_BINARY_O + $(OBJCOPY) \ + -I binary $(OBJARCH) \ + --rename-section .data=.data.$(basename $@) \ + $< $@ +endef + +makefile_path := $(dir $(abspath $(firstword $(MAKEFILE_LIST)))) +makefile_relative = $(shell realpath --relative-to $(makefile_path) $(1)) +as_obj_binary = _binary_$(subst -,_,$(subst .,_,$(subst /,_,$(subst .h,,$(call makefile_relative,$(1)))))) + +define BUILD_BINARY_H + @echo gen $(call makefile_relative,$@) + @echo '#pragma once' > $@ + @echo '' >> $@ + @echo '#include ' >> $@ + @echo '' >> $@ + @echo '#ifdef __cplusplus' >> $@ + @echo 'extern "C" {' >> $@ + @echo '#endif' >> $@ + @echo '' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$@)_start __asm("$(call as_obj_binary,$@)_start");' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$@)_end __asm("$(call as_obj_binary,$@)_end");' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$@)_size __asm("$(call as_obj_binary,$@)_size");' >> $@ + @echo '' >> $@ + @echo '#ifdef __cplusplus' >> $@ + @echo '}' >> $@ + @echo '#endif' >> $@ +endef diff --git a/dreamcast2/common.lds b/dreamcast2/common.lds new file mode 100644 index 0000000..ad18b42 --- /dev/null +++ b/dreamcast2/common.lds @@ -0,0 +1,58 @@ +SECTIONS +{ + . = ORIGIN(p2ram); + + .text.start : + { + KEEP(*(.text.start)) + *(.text.startup.*) + } > p2ram AT>p1ram + + . = ORIGIN(p1ram) + (. - ORIGIN(p2ram)); + + .text : + { + *(.text.*) + *(.text) + } > p1ram + + .data : + { + *(.data) + *(.data.*) + } > p1ram + + .rodata : + { + *(.rodata) + *(.rodata.*) + } > p1ram + + .ctors ALIGN(4) : + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + } > p1ram + + .text.vbr : + { + __vbr100 = .; + KEEP(*(.vbr.100)) + . = __vbr100 + 0x300; + KEEP(*(.vbr.400)) + . = __vbr100 + 0x500; + KEEP(*(.vbr.600)) + } > p1ram + + .bss ALIGN(32) (NOLOAD) : + { + *(.bss) + *(.bss.*) + *(COMMON) + } > p1ram + + INCLUDE "debug.lds" +} + +INCLUDE "symbols.lds" +INCLUDE "addresses.lds" diff --git a/dreamcast2/debug.lds b/dreamcast2/debug.lds new file mode 100644 index 0000000..71b5eb2 --- /dev/null +++ b/dreamcast2/debug.lds @@ -0,0 +1,48 @@ + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.rela.*) } diff --git a/dreamcast2/example/example.mk b/dreamcast2/example/example.mk new file mode 100644 index 0000000..1232778 --- /dev/null +++ b/dreamcast2/example/example.mk @@ -0,0 +1,9 @@ +START_OBJ = \ + start.o \ + runtime.o + +FRAMEBUFFER_SHADED_OBJ = \ + example/framebuffer_shaded.o + +example/framebuffer_shaded.elf: LDSCRIPT = $(LIB)/main.lds +example/framebuffer_shaded.elf: $(START_OBJ) $(FRAMEBUFFER_SHADED_OBJ) diff --git a/dreamcast2/example/framebuffer_shaded.cpp b/dreamcast2/example/framebuffer_shaded.cpp new file mode 100644 index 0000000..97364be --- /dev/null +++ b/dreamcast2/example/framebuffer_shaded.cpp @@ -0,0 +1,36 @@ +#include "memorymap.hpp" +#include "holly/holly.hpp" +#include "holly/holly_bits.hpp" + +void main() +{ + volatile uint32_t * framebuffer = (volatile uint32_t * )texture_memory32; + + for (int y = 0; y < 480; y++) { + for (int x = 0; x < 640; x++) { + int red = (y % 255); + int blue = (x % 255); + + framebuffer[y * 640 + x] = (red << 16) | (blue << 0); + } + } + + using holly::holly; + using namespace holly; + + holly.FB_R_CTRL + = fb_r_ctrl::vclk_div::pclk_vclk_1 + | fb_r_ctrl::fb_depth::xrgb0888 + | fb_r_ctrl::fb_enable; + + int fb_y_size = 480 - 1; + int bytes_per_pixel = 4; + int fb_x_size = ((640 * bytes_per_pixel) / 4) - 1; + holly.FB_R_SIZE + = fb_r_size::fb_modulus(1) + | fb_r_size::fb_y_size(fb_y_size) + | fb_r_size::fb_x_size(fb_x_size); + + // the framebuffer is at the start of texture memory (texture memory address 0) + holly.FB_R_SOF1 = 0; +} diff --git a/dreamcast2/holly/holly.hpp b/dreamcast2/holly/holly.hpp index 25b71ca..1e2d03f 100644 --- a/dreamcast2/holly/holly.hpp +++ b/dreamcast2/holly/holly.hpp @@ -2,165 +2,166 @@ #include "reg.hpp" -struct holly_reg { - reg32 ID; /* Device ID */ - reg32 REVISION; /* Revision Number */ - reg32 SOFTRESET; /* CORE & TA software reset */ - reg8 _pad0[8]; - reg32 STARTRENDER; /* Drawing start */ - reg32 TEST_SELECT; /* Test (writing this register is prohibited) */ - reg8 _pad1[4]; - reg32 PARAM_BASE; /* Base address for ISP parameters */ - reg8 _pad2[8]; - reg32 REGION_BASE; /* Base address for Region Array */ - reg32 SPAN_SORT_CFG; /* Span Sorter control */ - reg8 _pad3[12]; - reg32 VO_BORDER_COL; /* Border area color */ - reg32 FB_R_CTRL; /* Frame buffer read control */ - reg32 FB_W_CTRL; /* Frame buffer write control */ - reg32 FB_W_LINESTRIDE; /* Frame buffer line stride */ - reg32 FB_R_SOF1; /* Read start address for field - 1/strip - 1 */ - reg32 FB_R_SOF2; /* Read start address for field - 2/strip - 2 */ - reg8 _pad4[4]; - reg32 FB_R_SIZE; /* Frame buffer XY size */ - reg32 FB_W_SOF1; /* Write start address for field - 1/strip - 1 */ - reg32 FB_W_SOF2; /* Write start address for field - 2/strip - 2 */ - reg32 FB_X_CLIP; /* Pixel clip X coordinate */ - reg32 FB_Y_CLIP; /* Pixel clip Y coordinate */ - reg8 _pad5[4]; - reg32 FPU_SHAD_SCALE; /* Intensity Volume mode */ - reg32 FPU_CULL_VAL; /* Comparison value for culling */ - reg32 FPU_PARAM_CFG; /* Parameter read control */ - reg32 HALF_OFFSET; /* Pixel sampling control */ - reg32 FPU_PERP_VAL; /* Comparison value for perpendicular polygons */ - reg32 ISP_BACKGND_D; /* Background surface depth */ - reg32 ISP_BACKGND_T; /* Background surface tag */ - reg8 _pad6[8]; - reg32 ISP_FEED_CFG; /* Translucent polygon sort mode */ - reg8 _pad7[4]; - reg32 SDRAM_REFRESH; /* Texture memory refresh counter */ - reg32 SDRAM_ARB_CFG; /* Texture memory arbiter control */ - reg32 SDRAM_CFG; /* Texture memory control */ - reg8 _pad8[4]; - reg32 FOG_COL_RAM; /* Color for Look Up table Fog */ - reg32 FOG_COL_VERT; /* Color for vertex Fog */ - reg32 FOG_DENSITY; /* Fog scale value */ - reg32 FOG_CLAMP_MAX; /* Color clamping maximum value */ - reg32 FOG_CLAMP_MIN; /* Color clamping minimum value */ - reg32 SPG_TRIGGER_POS; /* External trigger signal HV counter value */ - reg32 SPG_HBLANK_INT; /* H-blank interrupt control */ - reg32 SPG_VBLANK_INT; /* V-blank interrupt control */ - reg32 SPG_CONTROL; /* Sync pulse generator control */ - reg32 SPG_HBLANK; /* H-blank control */ - reg32 SPG_LOAD; /* HV counter load value */ - reg32 SPG_VBLANK; /* V-blank control */ - reg32 SPG_WIDTH; /* Sync width control */ - reg32 TEXT_CONTROL; /* Texturing control */ - reg32 VO_CONTROL; /* Video output control */ - reg32 VO_STARTX; /* Video output start X position */ - reg32 VO_STARTY; /* Video output start Y position */ - reg32 SCALER_CTL; /* X & Y scaler control */ - reg8 _pad9[16]; - reg32 PAL_RAM_CTRL; /* Palette RAM control */ - reg32 SPG_STATUS; /* Sync pulse generator status */ - reg32 FB_BURSTCTRL; /* Frame buffer burst control */ - reg32 FB_C_SOF; /* Current frame buffer start address */ - reg32 Y_COEFF; /* Y scaling coefficent */ - reg32 PT_ALPHA_REF; /* Alpha value for Punch Through polygon comparison */ - reg8 _pad10[4]; - reg32 TA_OL_BASE; /* Object List write start address */ - reg32 TA_ISP_BASE; /* ISP/TSP Parameter write start address */ - reg32 TA_OL_LIMIT; /* Object List write limit address */ - reg32 TA_ISP_LIMIT; /* ISP/TSP Parameter limit address */ - reg32 TA_NEXT_OPB; /* Start address for the Object Pointer Block */ - reg32 TA_ITP_CURRENT; /* Starting address where the next ISP/TSP Parameters are stored */ - reg32 TA_GLOB_TILE_CLIP; /* Global Tile Clip control */ - reg32 TA_ALLOC_CTRL; /* Object list control */ - reg32 TA_LIST_INIT; /* TA initialization */ - reg32 TA_YUV_TEX_BASE; /* YUV422 texture write start address */ - reg32 TA_YUV_TEX_CTRL; /* YUV converter control */ - reg32 TA_YUV_TEX_CNT; /* YUV converter macro block counter value */ - reg8 _pad11[12]; - reg32 TA_LIST_CONT; /* TA continuation processing */ - reg32 TA_NEXT_OPB_INIT; /* Additional OPB starting address */ - reg8 _pad12[152]; - reg32 FOG_TABLE[128]; /* Look-up table fog data */ - reg8 _pad13[512]; - reg32 TA_OL_POINTERS[600]; /* TA Object List Pointer data */ - reg8 _pad14[160]; - reg32 PALETTE_RAM[1024]; /* Palette RAM */ -}; +namespace holly { + struct holly_reg { + reg32 ID; /* Device ID */ + reg32 REVISION; /* Revision Number */ + reg32 SOFTRESET; /* CORE & TA software reset */ + reg8 _pad0[8]; + reg32 STARTRENDER; /* Drawing start */ + reg32 TEST_SELECT; /* Test (writing this register is prohibited) */ + reg8 _pad1[4]; + reg32 PARAM_BASE; /* Base address for ISP parameters */ + reg8 _pad2[8]; + reg32 REGION_BASE; /* Base address for Region Array */ + reg32 SPAN_SORT_CFG; /* Span Sorter control */ + reg8 _pad3[12]; + reg32 VO_BORDER_COL; /* Border area color */ + reg32 FB_R_CTRL; /* Frame buffer read control */ + reg32 FB_W_CTRL; /* Frame buffer write control */ + reg32 FB_W_LINESTRIDE; /* Frame buffer line stride */ + reg32 FB_R_SOF1; /* Read start address for field - 1/strip - 1 */ + reg32 FB_R_SOF2; /* Read start address for field - 2/strip - 2 */ + reg8 _pad4[4]; + reg32 FB_R_SIZE; /* Frame buffer XY size */ + reg32 FB_W_SOF1; /* Write start address for field - 1/strip - 1 */ + reg32 FB_W_SOF2; /* Write start address for field - 2/strip - 2 */ + reg32 FB_X_CLIP; /* Pixel clip X coordinate */ + reg32 FB_Y_CLIP; /* Pixel clip Y coordinate */ + reg8 _pad5[4]; + reg32 FPU_SHAD_SCALE; /* Intensity Volume mode */ + reg32f FPU_CULL_VAL; /* Comparison value for culling */ + reg32 FPU_PARAM_CFG; /* Parameter read control */ + reg32 HALF_OFFSET; /* Pixel sampling control */ + reg32f FPU_PERP_VAL; /* Comparison value for perpendicular polygons */ + reg32f ISP_BACKGND_D; /* Background surface depth */ + reg32 ISP_BACKGND_T; /* Background surface tag */ + reg8 _pad6[8]; + reg32 ISP_FEED_CFG; /* Translucent polygon sort mode */ + reg8 _pad7[4]; + reg32 SDRAM_REFRESH; /* Texture memory refresh counter */ + reg32 SDRAM_ARB_CFG; /* Texture memory arbiter control */ + reg32 SDRAM_CFG; /* Texture memory control */ + reg8 _pad8[4]; + reg32 FOG_COL_RAM; /* Color for Look Up table Fog */ + reg32 FOG_COL_VERT; /* Color for vertex Fog */ + reg32 FOG_DENSITY; /* Fog scale value */ + reg32 FOG_CLAMP_MAX; /* Color clamping maximum value */ + reg32 FOG_CLAMP_MIN; /* Color clamping minimum value */ + reg32 SPG_TRIGGER_POS; /* External trigger signal HV counter value */ + reg32 SPG_HBLANK_INT; /* H-blank interrupt control */ + reg32 SPG_VBLANK_INT; /* V-blank interrupt control */ + reg32 SPG_CONTROL; /* Sync pulse generator control */ + reg32 SPG_HBLANK; /* H-blank control */ + reg32 SPG_LOAD; /* HV counter load value */ + reg32 SPG_VBLANK; /* V-blank control */ + reg32 SPG_WIDTH; /* Sync width control */ + reg32 TEXT_CONTROL; /* Texturing control */ + reg32 VO_CONTROL; /* Video output control */ + reg32 VO_STARTX; /* Video output start X position */ + reg32 VO_STARTY; /* Video output start Y position */ + reg32 SCALER_CTL; /* X & Y scaler control */ + reg8 _pad9[16]; + reg32 PAL_RAM_CTRL; /* Palette RAM control */ + reg32 SPG_STATUS; /* Sync pulse generator status */ + reg32 FB_BURSTCTRL; /* Frame buffer burst control */ + reg32 FB_C_SOF; /* Current frame buffer start address */ + reg32 Y_COEFF; /* Y scaling coefficent */ + reg32 PT_ALPHA_REF; /* Alpha value for Punch Through polygon comparison */ + reg8 _pad10[4]; + reg32 TA_OL_BASE; /* Object List write start address */ + reg32 TA_ISP_BASE; /* ISP/TSP Parameter write start address */ + reg32 TA_OL_LIMIT; /* Object List write limit address */ + reg32 TA_ISP_LIMIT; /* ISP/TSP Parameter limit address */ + reg32 TA_NEXT_OPB; /* Start address for the Object Pointer Block */ + reg32 TA_ITP_CURRENT; /* Starting address where the next ISP/TSP Parameters are stored */ + reg32 TA_GLOB_TILE_CLIP; /* Global Tile Clip control */ + reg32 TA_ALLOC_CTRL; /* Object list control */ + reg32 TA_LIST_INIT; /* TA initialization */ + reg32 TA_YUV_TEX_BASE; /* YUV422 texture write start address */ + reg32 TA_YUV_TEX_CTRL; /* YUV converter control */ + reg32 TA_YUV_TEX_CNT; /* YUV converter macro block counter value */ + reg8 _pad11[12]; + reg32 TA_LIST_CONT; /* TA continuation processing */ + reg32 TA_NEXT_OPB_INIT; /* Additional OPB starting address */ + reg8 _pad12[152]; + reg32 FOG_TABLE[128]; /* Look-up table fog data */ + reg8 _pad13[512]; + reg32 TA_OL_POINTERS[600]; /* TA Object List Pointer data */ + reg8 _pad14[160]; + reg32 PALETTE_RAM[1024]; /* Palette RAM */ + }; + static_assert((offsetof (struct holly_reg, ID)) == 0x0); + static_assert((offsetof (struct holly_reg, REVISION)) == 0x4); + static_assert((offsetof (struct holly_reg, SOFTRESET)) == 0x8); + static_assert((offsetof (struct holly_reg, STARTRENDER)) == 0x14); + static_assert((offsetof (struct holly_reg, TEST_SELECT)) == 0x18); + static_assert((offsetof (struct holly_reg, PARAM_BASE)) == 0x20); + static_assert((offsetof (struct holly_reg, REGION_BASE)) == 0x2c); + static_assert((offsetof (struct holly_reg, SPAN_SORT_CFG)) == 0x30); + static_assert((offsetof (struct holly_reg, VO_BORDER_COL)) == 0x40); + static_assert((offsetof (struct holly_reg, FB_R_CTRL)) == 0x44); + static_assert((offsetof (struct holly_reg, FB_W_CTRL)) == 0x48); + static_assert((offsetof (struct holly_reg, FB_W_LINESTRIDE)) == 0x4c); + static_assert((offsetof (struct holly_reg, FB_R_SOF1)) == 0x50); + static_assert((offsetof (struct holly_reg, FB_R_SOF2)) == 0x54); + static_assert((offsetof (struct holly_reg, FB_R_SIZE)) == 0x5c); + static_assert((offsetof (struct holly_reg, FB_W_SOF1)) == 0x60); + static_assert((offsetof (struct holly_reg, FB_W_SOF2)) == 0x64); + static_assert((offsetof (struct holly_reg, FB_X_CLIP)) == 0x68); + static_assert((offsetof (struct holly_reg, FB_Y_CLIP)) == 0x6c); + static_assert((offsetof (struct holly_reg, FPU_SHAD_SCALE)) == 0x74); + static_assert((offsetof (struct holly_reg, FPU_CULL_VAL)) == 0x78); + static_assert((offsetof (struct holly_reg, FPU_PARAM_CFG)) == 0x7c); + static_assert((offsetof (struct holly_reg, HALF_OFFSET)) == 0x80); + static_assert((offsetof (struct holly_reg, FPU_PERP_VAL)) == 0x84); + static_assert((offsetof (struct holly_reg, ISP_BACKGND_D)) == 0x88); + static_assert((offsetof (struct holly_reg, ISP_BACKGND_T)) == 0x8c); + static_assert((offsetof (struct holly_reg, ISP_FEED_CFG)) == 0x98); + static_assert((offsetof (struct holly_reg, SDRAM_REFRESH)) == 0xa0); + static_assert((offsetof (struct holly_reg, SDRAM_ARB_CFG)) == 0xa4); + static_assert((offsetof (struct holly_reg, SDRAM_CFG)) == 0xa8); + static_assert((offsetof (struct holly_reg, FOG_COL_RAM)) == 0xb0); + static_assert((offsetof (struct holly_reg, FOG_COL_VERT)) == 0xb4); + static_assert((offsetof (struct holly_reg, FOG_DENSITY)) == 0xb8); + static_assert((offsetof (struct holly_reg, FOG_CLAMP_MAX)) == 0xbc); + static_assert((offsetof (struct holly_reg, FOG_CLAMP_MIN)) == 0xc0); + static_assert((offsetof (struct holly_reg, SPG_TRIGGER_POS)) == 0xc4); + static_assert((offsetof (struct holly_reg, SPG_HBLANK_INT)) == 0xc8); + static_assert((offsetof (struct holly_reg, SPG_VBLANK_INT)) == 0xcc); + static_assert((offsetof (struct holly_reg, SPG_CONTROL)) == 0xd0); + static_assert((offsetof (struct holly_reg, SPG_HBLANK)) == 0xd4); + static_assert((offsetof (struct holly_reg, SPG_LOAD)) == 0xd8); + static_assert((offsetof (struct holly_reg, SPG_VBLANK)) == 0xdc); + static_assert((offsetof (struct holly_reg, SPG_WIDTH)) == 0xe0); + static_assert((offsetof (struct holly_reg, TEXT_CONTROL)) == 0xe4); + static_assert((offsetof (struct holly_reg, VO_CONTROL)) == 0xe8); + static_assert((offsetof (struct holly_reg, VO_STARTX)) == 0xec); + static_assert((offsetof (struct holly_reg, VO_STARTY)) == 0xf0); + static_assert((offsetof (struct holly_reg, SCALER_CTL)) == 0xf4); + static_assert((offsetof (struct holly_reg, PAL_RAM_CTRL)) == 0x108); + static_assert((offsetof (struct holly_reg, SPG_STATUS)) == 0x10c); + static_assert((offsetof (struct holly_reg, FB_BURSTCTRL)) == 0x110); + static_assert((offsetof (struct holly_reg, FB_C_SOF)) == 0x114); + static_assert((offsetof (struct holly_reg, Y_COEFF)) == 0x118); + static_assert((offsetof (struct holly_reg, PT_ALPHA_REF)) == 0x11c); + static_assert((offsetof (struct holly_reg, TA_OL_BASE)) == 0x124); + static_assert((offsetof (struct holly_reg, TA_ISP_BASE)) == 0x128); + static_assert((offsetof (struct holly_reg, TA_OL_LIMIT)) == 0x12c); + static_assert((offsetof (struct holly_reg, TA_ISP_LIMIT)) == 0x130); + static_assert((offsetof (struct holly_reg, TA_NEXT_OPB)) == 0x134); + static_assert((offsetof (struct holly_reg, TA_ITP_CURRENT)) == 0x138); + static_assert((offsetof (struct holly_reg, TA_GLOB_TILE_CLIP)) == 0x13c); + static_assert((offsetof (struct holly_reg, TA_ALLOC_CTRL)) == 0x140); + static_assert((offsetof (struct holly_reg, TA_LIST_INIT)) == 0x144); + static_assert((offsetof (struct holly_reg, TA_YUV_TEX_BASE)) == 0x148); + static_assert((offsetof (struct holly_reg, TA_YUV_TEX_CTRL)) == 0x14c); + static_assert((offsetof (struct holly_reg, TA_YUV_TEX_CNT)) == 0x150); + static_assert((offsetof (struct holly_reg, TA_LIST_CONT)) == 0x160); + static_assert((offsetof (struct holly_reg, TA_NEXT_OPB_INIT)) == 0x164); + static_assert((offsetof (struct holly_reg, FOG_TABLE)) == 0x200); + static_assert((offsetof (struct holly_reg, TA_OL_POINTERS)) == 0x600); + static_assert((offsetof (struct holly_reg, PALETTE_RAM)) == 0x1000); -static_assert((offsetof (struct holly_reg, ID)) == 0x0); -static_assert((offsetof (struct holly_reg, REVISION)) == 0x4); -static_assert((offsetof (struct holly_reg, SOFTRESET)) == 0x8); -static_assert((offsetof (struct holly_reg, STARTRENDER)) == 0x14); -static_assert((offsetof (struct holly_reg, TEST_SELECT)) == 0x18); -static_assert((offsetof (struct holly_reg, PARAM_BASE)) == 0x20); -static_assert((offsetof (struct holly_reg, REGION_BASE)) == 0x2c); -static_assert((offsetof (struct holly_reg, SPAN_SORT_CFG)) == 0x30); -static_assert((offsetof (struct holly_reg, VO_BORDER_COL)) == 0x40); -static_assert((offsetof (struct holly_reg, FB_R_CTRL)) == 0x44); -static_assert((offsetof (struct holly_reg, FB_W_CTRL)) == 0x48); -static_assert((offsetof (struct holly_reg, FB_W_LINESTRIDE)) == 0x4c); -static_assert((offsetof (struct holly_reg, FB_R_SOF1)) == 0x50); -static_assert((offsetof (struct holly_reg, FB_R_SOF2)) == 0x54); -static_assert((offsetof (struct holly_reg, FB_R_SIZE)) == 0x5c); -static_assert((offsetof (struct holly_reg, FB_W_SOF1)) == 0x60); -static_assert((offsetof (struct holly_reg, FB_W_SOF2)) == 0x64); -static_assert((offsetof (struct holly_reg, FB_X_CLIP)) == 0x68); -static_assert((offsetof (struct holly_reg, FB_Y_CLIP)) == 0x6c); -static_assert((offsetof (struct holly_reg, FPU_SHAD_SCALE)) == 0x74); -static_assert((offsetof (struct holly_reg, FPU_CULL_VAL)) == 0x78); -static_assert((offsetof (struct holly_reg, FPU_PARAM_CFG)) == 0x7c); -static_assert((offsetof (struct holly_reg, HALF_OFFSET)) == 0x80); -static_assert((offsetof (struct holly_reg, FPU_PERP_VAL)) == 0x84); -static_assert((offsetof (struct holly_reg, ISP_BACKGND_D)) == 0x88); -static_assert((offsetof (struct holly_reg, ISP_BACKGND_T)) == 0x8c); -static_assert((offsetof (struct holly_reg, ISP_FEED_CFG)) == 0x98); -static_assert((offsetof (struct holly_reg, SDRAM_REFRESH)) == 0xa0); -static_assert((offsetof (struct holly_reg, SDRAM_ARB_CFG)) == 0xa4); -static_assert((offsetof (struct holly_reg, SDRAM_CFG)) == 0xa8); -static_assert((offsetof (struct holly_reg, FOG_COL_RAM)) == 0xb0); -static_assert((offsetof (struct holly_reg, FOG_COL_VERT)) == 0xb4); -static_assert((offsetof (struct holly_reg, FOG_DENSITY)) == 0xb8); -static_assert((offsetof (struct holly_reg, FOG_CLAMP_MAX)) == 0xbc); -static_assert((offsetof (struct holly_reg, FOG_CLAMP_MIN)) == 0xc0); -static_assert((offsetof (struct holly_reg, SPG_TRIGGER_POS)) == 0xc4); -static_assert((offsetof (struct holly_reg, SPG_HBLANK_INT)) == 0xc8); -static_assert((offsetof (struct holly_reg, SPG_VBLANK_INT)) == 0xcc); -static_assert((offsetof (struct holly_reg, SPG_CONTROL)) == 0xd0); -static_assert((offsetof (struct holly_reg, SPG_HBLANK)) == 0xd4); -static_assert((offsetof (struct holly_reg, SPG_LOAD)) == 0xd8); -static_assert((offsetof (struct holly_reg, SPG_VBLANK)) == 0xdc); -static_assert((offsetof (struct holly_reg, SPG_WIDTH)) == 0xe0); -static_assert((offsetof (struct holly_reg, TEXT_CONTROL)) == 0xe4); -static_assert((offsetof (struct holly_reg, VO_CONTROL)) == 0xe8); -static_assert((offsetof (struct holly_reg, VO_STARTX)) == 0xec); -static_assert((offsetof (struct holly_reg, VO_STARTY)) == 0xf0); -static_assert((offsetof (struct holly_reg, SCALER_CTL)) == 0xf4); -static_assert((offsetof (struct holly_reg, PAL_RAM_CTRL)) == 0x108); -static_assert((offsetof (struct holly_reg, SPG_STATUS)) == 0x10c); -static_assert((offsetof (struct holly_reg, FB_BURSTCTRL)) == 0x110); -static_assert((offsetof (struct holly_reg, FB_C_SOF)) == 0x114); -static_assert((offsetof (struct holly_reg, Y_COEFF)) == 0x118); -static_assert((offsetof (struct holly_reg, PT_ALPHA_REF)) == 0x11c); -static_assert((offsetof (struct holly_reg, TA_OL_BASE)) == 0x124); -static_assert((offsetof (struct holly_reg, TA_ISP_BASE)) == 0x128); -static_assert((offsetof (struct holly_reg, TA_OL_LIMIT)) == 0x12c); -static_assert((offsetof (struct holly_reg, TA_ISP_LIMIT)) == 0x130); -static_assert((offsetof (struct holly_reg, TA_NEXT_OPB)) == 0x134); -static_assert((offsetof (struct holly_reg, TA_ITP_CURRENT)) == 0x138); -static_assert((offsetof (struct holly_reg, TA_GLOB_TILE_CLIP)) == 0x13c); -static_assert((offsetof (struct holly_reg, TA_ALLOC_CTRL)) == 0x140); -static_assert((offsetof (struct holly_reg, TA_LIST_INIT)) == 0x144); -static_assert((offsetof (struct holly_reg, TA_YUV_TEX_BASE)) == 0x148); -static_assert((offsetof (struct holly_reg, TA_YUV_TEX_CTRL)) == 0x14c); -static_assert((offsetof (struct holly_reg, TA_YUV_TEX_CNT)) == 0x150); -static_assert((offsetof (struct holly_reg, TA_LIST_CONT)) == 0x160); -static_assert((offsetof (struct holly_reg, TA_NEXT_OPB_INIT)) == 0x164); -static_assert((offsetof (struct holly_reg, FOG_TABLE)) == 0x200); -static_assert((offsetof (struct holly_reg, TA_OL_POINTERS)) == 0x600); -static_assert((offsetof (struct holly_reg, PALETTE_RAM)) == 0x1000); - -extern struct holly_reg holly __asm("holly"); + extern struct holly_reg holly __asm("holly"); +} diff --git a/dreamcast2/holly/holly_bits.hpp b/dreamcast2/holly/holly_bits.hpp index fe6dd75..7fb9a5f 100644 --- a/dreamcast2/holly/holly_bits.hpp +++ b/dreamcast2/holly/holly_bits.hpp @@ -140,7 +140,7 @@ namespace holly { } namespace fpu_cull_val { - inline uint32_t culling_comparison_value(float num) { return _i(__builtin_fabsf(num));; } + inline float culling_comparison_value(float num) { return num; } } namespace fpu_param_cfg { @@ -181,11 +181,11 @@ namespace holly { } namespace fpu_perp_val { - inline uint32_t perpendicular_triangle_compare(float num) { return _i(__builtin_fabsf(num));; } + inline float perpendicular_triangle_compare(float num) { return num; } } namespace isp_backgnd_d { - inline uint32_t background_plane_depth(float num) { return _i(num) & 0xfffffff0; } + inline float background_plane_depth(float num) { return num; } } namespace isp_backgnd_t { diff --git a/dreamcast2/main.lds b/dreamcast2/main.lds new file mode 100644 index 0000000..3583424 --- /dev/null +++ b/dreamcast2/main.lds @@ -0,0 +1,10 @@ +OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl") +MEMORY +{ + p1ram : ORIGIN = 0x8c010000, LENGTH = 0xff0000 + p2ram : ORIGIN = 0xac010000, LENGTH = 0xff0000 +} + +INCLUDE "common.lds" + +__stack_end = ORIGIN(p1ram) + LENGTH(p1ram) - 0x4000; diff --git a/dreamcast2/reg.hpp b/dreamcast2/reg.hpp index d24bbb1..df02c2e 100644 --- a/dreamcast2/reg.hpp +++ b/dreamcast2/reg.hpp @@ -6,7 +6,9 @@ typedef volatile uint8_t reg8; typedef volatile uint16_t reg16; typedef volatile uint32_t reg32; +typedef volatile float reg32f; static_assert((sizeof (reg8)) == 1); static_assert((sizeof (reg16)) == 2); static_assert((sizeof (reg32)) == 4); +static_assert((sizeof (reg32f)) == 4); diff --git a/dreamcast2/regs.mk b/dreamcast2/regs.mk new file mode 100644 index 0000000..3d20b89 --- /dev/null +++ b/dreamcast2/regs.mk @@ -0,0 +1,30 @@ +%.csv: %.ods + libreoffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":44,34,76,,,,true --outdir $(dir $@) $< + + +# HOLLY + +holly/holly.hpp: regs/holly/holly.csv regs/render_block_regs.py + python regs/render_block_regs.py $< holly > $@ + +holly/holly_bits.hpp: regs/holly/holly_bits.csv regs/render_bits.py + python regs/render_bits.py $< holly > $@ + +holly/region_array_bits.hpp: regs/holly/region_array_bits.csv regs/render_bits.py + python regs/render_bits.py $< holly region_array > $@ + +# SH7091 + +sh7091/sh7091.hpp: regs/sh7091/sh7091.csv regs/sh7091.py + python regs/sh7091.py $< sh7091 > $@ + +sh7091/sh7091_bits.hpp: regs/sh7091/sh7091_bits.csv regs/render_bits.py + python regs/render_bits.py $< sh7091 > $@ + +# SYSTEMBUS + +systembus/systembus.hpp: regs/systembus/systembus.csv regs/render_block_regs.py + python regs/render_block_regs.py $< systembus > $@ + +systembus/systembus_bits.hpp: regs/systembus/systembus_bits.csv regs/render_bits.py + python regs/render_bits.py $< systembus > $@ diff --git a/dreamcast2/regs/block_regs.py b/dreamcast2/regs/block_regs.py index a189e20..017bcd4 100644 --- a/dreamcast2/regs/block_regs.py +++ b/dreamcast2/regs/block_regs.py @@ -1,21 +1,41 @@ import sys +import string from generate import renderer from csv_input import read_input def size_p(size): return size in {1, 2, 4} -def size_to_type(size): +def size_to_type(size, type=None): if size == 1: + assert type is None return "reg8 " elif size == 2: + assert type is None return "reg16" elif size == 4: - return "reg32" + if type == "f": + return "reg32f" + else: + assert type is None + return "reg32" else: raise NotImplemented(size) +def split_integer(s): + acc = [] + for i, c in enumerate(s): + if c in string.digits: + acc.append(c) + else: + return int("".join(acc), 10), s[i:] + return int("".join(acc), 10), None + +def parse_size_type(s): + size, type = split_integer(s) + return size, type + def new_writer(): first_address = 0 next_address = 0 @@ -50,7 +70,7 @@ def new_writer(): assert _address <= 0xffff offset_address = (_offset << 16) address = offset_address | (_address << 0) - size = int(row["size"], 10) + size, size_type = parse_size_type(row["size"]) name = row["name"] description = row["description"] @@ -73,7 +93,7 @@ def new_writer(): def field(): if size_p(size): assert address % size == 0 - type = size_to_type(size) + type = size_to_type(size, size_type) return f"{type} {name};" else: type = size_to_type(4) diff --git a/dreamcast2/regs/holly.py b/dreamcast2/regs/holly.py deleted file mode 100644 index 35ffcae..0000000 --- a/dreamcast2/regs/holly.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys - -from csv_input import read_input -from generate import renderer -from block_regs import new_writer -from block_regs import headers - -def block(): - yield 'extern struct holly_reg holly __asm("holly");' - -input_file = sys.argv[1] -rows = read_input(input_file) -process = new_writer() -render, out = renderer() -render(headers()) -render(process(rows)) -render(block()) -sys.stdout.write(out.getvalue()) diff --git a/dreamcast2/regs/holly/holly.csv b/dreamcast2/regs/holly/holly.csv index 353e47e..2e0a20e 100644 --- a/dreamcast2/regs/holly/holly.csv +++ b/dreamcast2/regs/holly/holly.csv @@ -25,11 +25,11 @@ "holly","006c","4","FB_Y_CLIP","RW","Pixel clip Y coordinate" ,,,,, "holly","0074","4","FPU_SHAD_SCALE","RW","Intensity Volume mode" -"holly","0078","4","FPU_CULL_VAL","RW","Comparison value for culling" +"holly","0078","4f","FPU_CULL_VAL","RW","Comparison value for culling" "holly","007c","4","FPU_PARAM_CFG","RW","Parameter read control" "holly","0080","4","HALF_OFFSET","RW","Pixel sampling control" -"holly","0084","4","FPU_PERP_VAL","RW","Comparison value for perpendicular polygons" -"holly","0088","4","ISP_BACKGND_D","RW","Background surface depth" +"holly","0084","4f","FPU_PERP_VAL","RW","Comparison value for perpendicular polygons" +"holly","0088","4f","ISP_BACKGND_D","RW","Background surface depth" "holly","008c","4","ISP_BACKGND_T","RW","Background surface tag" ,,,,, "holly","0098","4","ISP_FEED_CFG","RW","Translucent polygon sort mode" diff --git a/dreamcast2/regs/holly/holly.ods b/dreamcast2/regs/holly/holly.ods index 5ffe8ed..85942f4 100644 Binary files a/dreamcast2/regs/holly/holly.ods and b/dreamcast2/regs/holly/holly.ods differ diff --git a/dreamcast2/regs/holly_bits.py b/dreamcast2/regs/render_bits.py similarity index 92% rename from dreamcast2/regs/holly_bits.py rename to dreamcast2/regs/render_bits.py index 890d3ae..883704b 100644 --- a/dreamcast2/regs/holly_bits.py +++ b/dreamcast2/regs/render_bits.py @@ -154,29 +154,14 @@ def render_read_only(bit_def): " }" ) -def render_float_mask(mask): - if mask == "float_0_8_23": - return "_i(__builtin_fabsf(num));" - elif mask == "float_1_8_23": - return "_i(num)" - else: - assert mask.startswith("float_") - mask = mask.removeprefix("float_") - sign, exponent, fraction = map(int, mask.split('_')) - assert exponent == 8, exponent - assert sign == 1 - bit_length = (sign + exponent + fraction) - mask = (2 ** bit_length - 1) << (32 - bit_length) - return f"_i(num) & {hex(mask)}" - def render_mask(bit_def): assert bit_def["value"] == "" mask = bit_def["mask"] bits = parse_bit_range(bit_def["bits"]) if mask.startswith("float_"): yield ( - f"inline uint32_t {escape(bit_def['bit_name'])}(float num) {{ " - f"return {render_float_mask(mask)};" + f"inline float {escape(bit_def['bit_name'])}(float num) {{ " + f"return num;" " }" ) else: diff --git a/dreamcast2/regs/render_block_regs.py b/dreamcast2/regs/render_block_regs.py new file mode 100644 index 0000000..bd5b6e2 --- /dev/null +++ b/dreamcast2/regs/render_block_regs.py @@ -0,0 +1,32 @@ +import sys + +from csv_input import read_input +from generate import renderer +from block_regs import new_writer +from block_regs import headers + +def blocks(rows): + blocks = [] + for row in rows: + block = row["block"] + if block not in blocks: + blocks.append(block) + + for block in blocks: + yield f'extern struct {block.lower()}_reg {block.lower()} __asm("{block.lower()}");' + +def namespace(namespace_name, rows): + yield f"namespace {namespace_name} {{" + yield from process(rows) + yield from blocks(rows) + yield "}" + +if __name__ == "__main__": + input_file = sys.argv[1] + namespace_name = sys.argv[2] + rows = read_input(input_file) + process = new_writer() + render, out = renderer() + render(headers()) + render(namespace(namespace_name, rows)) + sys.stdout.write(out.getvalue()) diff --git a/dreamcast2/regs/render_sh7091.py b/dreamcast2/regs/render_sh7091.py new file mode 100644 index 0000000..43bdd40 --- /dev/null +++ b/dreamcast2/regs/render_sh7091.py @@ -0,0 +1,55 @@ +import sys + +from generate import renderer +from csv_input import read_input +from block_regs import new_writer +from block_regs import headers +from block_regs import size_to_type + +def blocks(rows): + stack = [] + last_block = None + for row in rows: + block = row["block"] + if last_block != block: + offset = int(row["offset"], 16) + stack.append((block, offset)) + last_block = block + + yield "struct sh7091_reg {" + last_offset = 0 + last_block = None + reserved_num = 0 + for block, offset in stack: + if offset != last_offset: + assert last_block is not None + type = size_to_type(1) + raw_pad = (offset - last_offset) << 16 + yield f"{type} _pad{reserved_num}[{hex(raw_pad)} - (sizeof (struct {last_block.lower()}_reg))];" + reserved_num += 1 + yield f"struct {block.lower()}_reg {block};" + last_offset = offset + last_block = block + yield "};" + + for block, offset in stack: + yield f"static_assert((offsetof (struct sh7091_reg, {block})) == {hex(offset << 16)});" + + yield "" + yield 'extern struct sh7091_reg sh7091 __asm("sh7091");' + +def namespace(namespace_name, rows): + yield f"namespace {namespace_name} {{" + yield from process(rows) + yield from blocks(rows) + yield "}" + +if __name__ == "__main__": + input_file = sys.argv[1] + namespace_name = sys.argv[2] + rows = read_input(input_file) + process = new_writer() + render, out = renderer() + render(headers()) + render(namespace(namespace_name, rows)) + sys.stdout.write(out.getvalue()) diff --git a/dreamcast2/regs/sh7091.py b/dreamcast2/regs/sh7091.py deleted file mode 100644 index b93e545..0000000 --- a/dreamcast2/regs/sh7091.py +++ /dev/null @@ -1,145 +0,0 @@ -import sys - -from generate import renderer -from csv_input import read_input - -def size_p(size): - return size in {1, 2, 4} - -def size_to_type(size): - if size == 1: - return "reg8 " - elif size == 2: - return "reg16" - elif size == 4: - return "reg32" - else: - raise NotImplemented(size) - -def new_writer(): - first_address = 0 - next_address = 0 - last_block = None - size_total = 0 - reserved_num = 0 - stack = [] - - def terminate(): - nonlocal last_block - nonlocal stack - - if last_block is not None: - yield "};" - for address, name in stack: - yield f"static_assert((offsetof (struct {last_block.lower()}_reg, {name})) == {hex(address - first_address)});" - yield "" - stack = [] - - def process_row(row): - nonlocal first_address - nonlocal next_address - nonlocal last_block - nonlocal reserved_num - nonlocal size_total - nonlocal stack - - block = row["block"] - _offset = int(row["offset"], 16) if "offset" in row else 0 - _address = int(row["address"], 16) - assert _offset <= 0xff - assert _address <= 0xffff - offset_address = (_offset << 16) - address = offset_address | (_address << 0) - size = int(row["size"], 10) - name = row["name"] - description = row["description"] - - if block != last_block: - yield from terminate() - first_address = offset_address - next_address = offset_address - size_total = 0 - reserved_num = 0 - yield f"struct {block.lower()}_reg {{" - - 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 - size_total += padding - - def field(): - if size_p(size): - assert address % size == 0 - type = size_to_type(size) - return f"{type} {name};" - else: - type = size_to_type(4) - return f"{type} {name}[{size // 4}];" - - yield field().ljust(27) + f"/* {description} */" - - stack.append((address, name)) - next_address = address + size - last_block = block - size_total += size - - def process(rows): - for row in rows: - yield from process_row(row) - yield from terminate() - - return process - -def blocks(rows): - stack = [] - last_block = None - for row in rows: - block = row["block"] - if last_block != block: - offset = int(row["offset"], 16) - stack.append((block, offset)) - last_block = block - - yield "struct sh7091_reg {" - last_offset = 0 - last_block = None - reserved_num = 0 - for block, offset in stack: - if offset != last_offset: - assert last_block is not None - type = size_to_type(1) - raw_pad = (offset - last_offset) << 16 - yield f"{type} _pad{reserved_num}[{hex(raw_pad)} - (sizeof (struct {last_block.lower()}_reg))];" - reserved_num += 1 - yield f"struct {block.lower()}_reg {block};" - last_offset = offset - last_block = block - yield "};" - - for block, offset in stack: - yield f"static_assert((offsetof (struct sh7091_reg, {block})) == {hex(offset << 16)});" - - yield "" - yield 'extern struct sh7091_reg sh7091 __asm("sh7091");' - -def headers(): - yield "#pragma once" - yield "" - yield "#include " - yield "#include " - yield "" - yield '#include "type.hpp"' - yield "" - -if __name__ == "__main__": - input_file = sys.argv[1] - rows = read_input(input_file) - process = new_writer() - render, out = renderer() - render(headers()) - render(process(rows)) - render(blocks(rows)) - sys.stdout.write(out.getvalue()) diff --git a/dreamcast2/regs/systembus/systembus_bits.csv b/dreamcast2/regs/systembus/systembus_bits.csv new file mode 100644 index 0000000..310596b --- /dev/null +++ b/dreamcast2/regs/systembus/systembus_bits.csv @@ -0,0 +1,67 @@ +"register_name","enum_name","bits","bit_name","value","mask","description" +"C2DSTAT",,"31-0","texture_memory_start_address",,"0x13ffffe0", +"C2DLEN",,"23-0","transfer_length",,"0xffffe0", +"C2DST",,"0","start","1",, +,,,,,, +"ISTNRM",,"21","end_of_transferring_punch_through_list","1",, +"ISTNRM",,"20","end_of_dma_sort_dma","1",, +"ISTNRM",,"19","end_of_dma_ch2_dma","1",, +"ISTNRM",,"18","end_of_dma_dev_dma","1",, +"ISTNRM",,"17","end_of_dma_ext_dma2","1",, +"ISTNRM",,"16","end_of_dma_ext_dma1","1",, +"ISTNRM",,"15","end_of_dma_aica_dma","1",, +"ISTNRM",,"14","end_of_dma_gd_dma","1",, +"ISTNRM",,"13","maple_v_blank_over","1",, +"ISTNRM",,"12","end_of_dma_maple_dma","1",, +"ISTNRM",,"11","end_of_dma_pvr_dma","1",, +"ISTNRM",,"10","end_of_transferring_translucent_modifier_volume_list","1",, +"ISTNRM",,"9","end_of_transferring_translucent_list","1",, +"ISTNRM",,"8","end_of_transferring_opaque_modifier_volume_list","1",, +"ISTNRM",,"7","end_of_transferring_opaque_list","1",, +"ISTNRM",,"6","end_of_transferring_yuv","1",, +"ISTNRM",,"5","h_blank_in","1",, +"ISTNRM",,"4","v_blank_out","1",, +"ISTNRM",,"3","v_blank_in","1",, +"ISTNRM",,"2","end_of_render_tsp","1",, +"ISTNRM",,"1","end_of_render_isp","1",, +"ISTNRM",,"0","end_of_render_video","1",, +,,,,,, +"ISTERR",,"31","sh4__if_access_inhibited_area","1",, +"ISTERR",,"28","ddt__if_sort_dma_command_error","1",, +"ISTERR",,"27","g2__time_out_in_cpu_access","1",, +"ISTERR",,"26","g2__dev_dma_time_out","1",, +"ISTERR",,"25","g2__ext_dma2_time_out","1",, +"ISTERR",,"24","g2__ext_dma1_time_out","1",, +"ISTERR",,"23","g2__aica_dma_time_out","1",, +"ISTERR",,"22","g2__dev_dma_over_run","1",, +"ISTERR",,"21","g2__ext_dma2_over_run","1",, +"ISTERR",,"20","g2__ext_dma1_over_run","1",, +"ISTERR",,"19","g2__aica_dma_over_run","1",, +"ISTERR",,"18","g2__dev_dma_illegal_address_set","1",, +"ISTERR",,"17","g2__ext_dma2_illegal_address_set","1",, +"ISTERR",,"16","g2__ext_dma1_illegal_address_set","1",, +"ISTERR",,"15","g2__aica_dma_illegal_address_set","1",, +"ISTERR",,"14","g1__rom_flash_access_at_gd_dma","1",, +"ISTERR",,"13","g1__gd_dma_over_run","1",, +"ISTERR",,"12","g1__illegal_address_set","1",, +"ISTERR",,"11","maple__illegal_command","1",, +"ISTERR",,"10","maple__write_fifo_over_flow","1",, +"ISTERR",,"9","maple__dma_over_run","1",, +"ISTERR",,"8","maple__illegal_address_set","1",, +"ISTERR",,"7","pvrif__dma_over_run","1",, +"ISTERR",,"6","pvrif__illegal_address_set","1",, +"ISTERR",,"5","ta__fifo_overflow","1",, +"ISTERR",,"4","ta__illegal_parameter","1",, +"ISTERR",,"3","ta__object_list_pointer_overflow","1",, +"ISTERR",,"2","ta__isp_tsp_parameter_overflow","1",, +"ISTERR",,"1","render__hazard_processing_of_strip_buffer","1",, +"ISTERR",,"0","render__isp_out_of_cache","1",, +,,,,,, +"FFST",,"5","holly_cpu_if_block_internal_write_buffer",,, +"FFST",,"4","holly_g2_if_block_internal_write_buffer",,, +"FFST",,"0","aica_internal_write_buffer",,, +,,,,,, +"ISTEXT",,3,"external_device",1,, +"ISTEXT",,2,"modem",1,, +"ISTEXT",,1,"aica",1,, +"ISTEXT",,0,"gdrom",1,, diff --git a/dreamcast2/runtime.cpp b/dreamcast2/runtime.cpp new file mode 100644 index 0000000..327bf23 --- /dev/null +++ b/dreamcast2/runtime.cpp @@ -0,0 +1,59 @@ +#include + +#include "sh7091/store_queue_transfer.hpp" + +extern uint32_t __text_link_start __asm("__text_link_start"); +extern uint32_t __text_link_end __asm("__text_link_end"); +extern uint32_t __text_load_start __asm("__text_load_start"); + +extern uint32_t __data_link_start __asm("__data_link_start"); +extern uint32_t __data_link_end __asm("__data_link_end"); +extern uint32_t __data_load_start __asm("__data_load_start"); + +extern uint32_t __rodata_link_start __asm("__rodata_link_start"); +extern uint32_t __rodata_link_end __asm("__rodata_link_end"); +extern uint32_t __rodata_load_start __asm("__rodata_load_start"); + +extern uint32_t __ctors_link_start __asm("__ctors_link_start"); +extern uint32_t __ctors_link_end __asm("__ctors_link_end"); + +extern uint32_t __bss_link_start __asm("__bss_link_start"); +extern uint32_t __bss_link_end __asm("__bss_link_end"); + +extern void main(); + +typedef void(init_t)(void); + +void runtime_init() +__attribute__((section(".text.start.runtime_init"))); + +void runtime_init() +{ + // relocate text (if necessary) + //copy(&__text_link_start, &__text_link_end, &__text_load_start); + + // relocate data (if necessary) + //copy(&__data_link_start, &__data_link_end, &__data_load_start); + + // relocate rodata (if necessary) + //copy(&__rodata_link_start, &__rodata_link_end, &__rodata_load_start); + + // clear BSS + uint32_t * bss_start = &__bss_link_start; + uint32_t * bss_end = &__bss_link_end; + int bss_length = bss_end - bss_start; + sh7091::store_queue_transfer::zeroize(bss_start, bss_length, 0); + + // call ctors + uint32_t * ctors_start = &__ctors_link_start; + uint32_t * ctors_end = &__ctors_link_end; + while (ctors_start < ctors_end) { + ((init_t *)(*ctors_start++))(); + } +} + +extern "C" +void foo() +{ + runtime_init(); +} diff --git a/dreamcast2/sh7091/sh7091.hpp b/dreamcast2/sh7091/sh7091.hpp index 1e640e2..ef71499 100644 --- a/dreamcast2/sh7091/sh7091.hpp +++ b/dreamcast2/sh7091/sh7091.hpp @@ -1,379 +1,366 @@ #pragma once -#include -#include +#include "reg.hpp" -#include "type.hpp" +namespace sh7091 { + struct ccn_reg { + reg32 PTEH; /* Page table entry high register */ + reg32 PTEL; /* Page table entry low register */ + reg32 TTB; /* Translation table base register */ + reg32 TEA; /* TLB exception address register */ + reg32 MMUCR; /* MMU control register */ + reg8 BASRA; /* Break ASID register A */ + reg8 _pad0[3]; + reg8 BASRB; /* Break ASID register B */ + reg8 _pad1[3]; + reg32 CCR; /* Cache control register */ + reg32 TRA; /* TRAPA exception register */ + reg32 EXPEVT; /* Exception event register */ + reg32 INTEVT; /* Interrupt event register */ + reg8 _pad2[8]; + reg32 PTEA; /* Page table entry assistance register */ + reg32 QACR0; /* Queue address control register 0 */ + reg32 QACR1; /* Queue address control register 1 */ + }; + static_assert((offsetof (struct ccn_reg, PTEH)) == 0x0); + static_assert((offsetof (struct ccn_reg, PTEL)) == 0x4); + static_assert((offsetof (struct ccn_reg, TTB)) == 0x8); + static_assert((offsetof (struct ccn_reg, TEA)) == 0xc); + static_assert((offsetof (struct ccn_reg, MMUCR)) == 0x10); + static_assert((offsetof (struct ccn_reg, BASRA)) == 0x14); + static_assert((offsetof (struct ccn_reg, BASRB)) == 0x18); + static_assert((offsetof (struct ccn_reg, CCR)) == 0x1c); + static_assert((offsetof (struct ccn_reg, TRA)) == 0x20); + static_assert((offsetof (struct ccn_reg, EXPEVT)) == 0x24); + static_assert((offsetof (struct ccn_reg, INTEVT)) == 0x28); + static_assert((offsetof (struct ccn_reg, PTEA)) == 0x34); + static_assert((offsetof (struct ccn_reg, QACR0)) == 0x38); + static_assert((offsetof (struct ccn_reg, QACR1)) == 0x3c); -struct ccn_reg { - reg32 PTEH; /* Page table entry high register */ - reg32 PTEL; /* Page table entry low register */ - reg32 TTB; /* Translation table base register */ - reg32 TEA; /* TLB exception address register */ - reg32 MMUCR; /* MMU control register */ - reg8 BASRA; /* Break ASID register A */ - reg8 _pad0[3]; - reg8 BASRB; /* Break ASID register B */ - reg8 _pad1[3]; - reg32 CCR; /* Cache control register */ - reg32 TRA; /* TRAPA exception register */ - reg32 EXPEVT; /* Exception event register */ - reg32 INTEVT; /* Interrupt event register */ - reg8 _pad2[8]; - reg32 PTEA; /* Page table entry assistance register */ - reg32 QACR0; /* Queue address control register 0 */ - reg32 QACR1; /* Queue address control register 1 */ -}; + struct ubc_reg { + reg32 BARA; /* Break address register A */ + reg8 BAMRA; /* Break address mask register A */ + reg8 _pad0[3]; + reg16 BBRA; /* Break bus cycle register A */ + reg8 _pad1[2]; + reg32 BARB; /* Break address register B */ + reg8 BAMRB; /* Break address mask register B */ + reg8 _pad2[3]; + reg16 BBRB; /* Break bus cycle register B */ + reg8 _pad3[2]; + reg32 BDRB; /* Break data register B */ + reg32 BDMRB; /* Break data mask register B */ + reg16 BRCR; /* Break control register */ + }; + static_assert((offsetof (struct ubc_reg, BARA)) == 0x0); + static_assert((offsetof (struct ubc_reg, BAMRA)) == 0x4); + static_assert((offsetof (struct ubc_reg, BBRA)) == 0x8); + static_assert((offsetof (struct ubc_reg, BARB)) == 0xc); + static_assert((offsetof (struct ubc_reg, BAMRB)) == 0x10); + static_assert((offsetof (struct ubc_reg, BBRB)) == 0x14); + static_assert((offsetof (struct ubc_reg, BDRB)) == 0x18); + static_assert((offsetof (struct ubc_reg, BDMRB)) == 0x1c); + static_assert((offsetof (struct ubc_reg, BRCR)) == 0x20); -static_assert((offsetof (struct ccn_reg, PTEH)) == 0x0); -static_assert((offsetof (struct ccn_reg, PTEL)) == 0x4); -static_assert((offsetof (struct ccn_reg, TTB)) == 0x8); -static_assert((offsetof (struct ccn_reg, TEA)) == 0xc); -static_assert((offsetof (struct ccn_reg, MMUCR)) == 0x10); -static_assert((offsetof (struct ccn_reg, BASRA)) == 0x14); -static_assert((offsetof (struct ccn_reg, BASRB)) == 0x18); -static_assert((offsetof (struct ccn_reg, CCR)) == 0x1c); -static_assert((offsetof (struct ccn_reg, TRA)) == 0x20); -static_assert((offsetof (struct ccn_reg, EXPEVT)) == 0x24); -static_assert((offsetof (struct ccn_reg, INTEVT)) == 0x28); -static_assert((offsetof (struct ccn_reg, PTEA)) == 0x34); -static_assert((offsetof (struct ccn_reg, QACR0)) == 0x38); -static_assert((offsetof (struct ccn_reg, QACR1)) == 0x3c); + struct bsc_reg { + reg32 BCR1; /* Bus control register 1 */ + reg16 BCR2; /* Bus control register 2 */ + reg8 _pad0[2]; + reg32 WCR1; /* Wait state control register 1 */ + reg32 WCR2; /* Wait state control register 2 */ + reg32 WCR3; /* Wait state control register 3 */ + reg32 MCR; /* Memory control register */ + reg16 PCR; /* PCMCIA control register */ + reg8 _pad1[2]; + reg16 RTCSR; /* Refresh timer control/status register */ + reg8 _pad2[2]; + reg16 RTCNT; /* Refresh timer counter */ + reg8 _pad3[2]; + reg16 RTCOR; /* Refresh timer constant counter */ + reg8 _pad4[2]; + reg16 RFCR; /* Refresh count register */ + reg8 _pad5[2]; + reg32 PCTRA; /* Port control register A */ + reg16 PDTRA; /* Port data register A */ + reg8 _pad6[14]; + reg32 PCTRB; /* Port control register B */ + reg16 PDTRB; /* Port data register B */ + reg8 _pad7[2]; + reg16 GPIOIC; /* GPIO interrupt control register */ + reg8 _pad8[1048502]; + reg32 SDMR2[16384]; /* Synchronous DRAM mode registers */ + reg8 _pad9[196608]; + reg32 SDMR3[16384]; /* Synchronous DRAM mode registers */ + }; + static_assert((offsetof (struct bsc_reg, BCR1)) == 0x0); + static_assert((offsetof (struct bsc_reg, BCR2)) == 0x4); + static_assert((offsetof (struct bsc_reg, WCR1)) == 0x8); + static_assert((offsetof (struct bsc_reg, WCR2)) == 0xc); + static_assert((offsetof (struct bsc_reg, WCR3)) == 0x10); + static_assert((offsetof (struct bsc_reg, MCR)) == 0x14); + static_assert((offsetof (struct bsc_reg, PCR)) == 0x18); + static_assert((offsetof (struct bsc_reg, RTCSR)) == 0x1c); + static_assert((offsetof (struct bsc_reg, RTCNT)) == 0x20); + static_assert((offsetof (struct bsc_reg, RTCOR)) == 0x24); + static_assert((offsetof (struct bsc_reg, RFCR)) == 0x28); + static_assert((offsetof (struct bsc_reg, PCTRA)) == 0x2c); + static_assert((offsetof (struct bsc_reg, PDTRA)) == 0x30); + static_assert((offsetof (struct bsc_reg, PCTRB)) == 0x40); + static_assert((offsetof (struct bsc_reg, PDTRB)) == 0x44); + static_assert((offsetof (struct bsc_reg, GPIOIC)) == 0x48); + static_assert((offsetof (struct bsc_reg, SDMR2)) == 0x100000); + static_assert((offsetof (struct bsc_reg, SDMR3)) == 0x140000); -struct ubc_reg { - reg32 BARA; /* Break address register A */ - reg8 BAMRA; /* Break address mask register A */ - reg8 _pad0[3]; - reg16 BBRA; /* Break bus cycle register A */ - reg8 _pad1[2]; - reg32 BARB; /* Break address register B */ - reg8 BAMRB; /* Break address mask register B */ - reg8 _pad2[3]; - reg16 BBRB; /* Break bus cycle register B */ - reg8 _pad3[2]; - reg32 BDRB; /* Break data register B */ - reg32 BDMRB; /* Break data mask register B */ - reg16 BRCR; /* Break control register */ -}; + struct dmac_reg { + reg32 SAR0; /* DMA source address register 0 */ + reg32 DAR0; /* DMA destination address register 0 */ + reg32 DMATCR0; /* DMA transfer count register 0 */ + reg32 CHCR0; /* DMA control register 0 */ + reg32 SAR1; /* DMA source address register 1 */ + reg32 DAR1; /* DMA destination address register 1 */ + reg32 DMATCR1; /* DMA transfer count register 1 */ + reg32 CHCR1; /* DMA control register 1 */ + reg32 SAR2; /* DMA source address register 2 */ + reg32 DAR2; /* DMA destination address register 2 */ + reg32 DMATCR2; /* DMA transfer count register 2 */ + reg32 CHCR2; /* DMA control register 2 */ + reg32 SAR3; /* DMA source address register 3 */ + reg32 DAR3; /* DMA destination address register 3 */ + reg32 DMATCR3; /* DMA transfer count register 3 */ + reg32 CHCR3; /* DMA control register 3 */ + reg32 DMAOR; /* DMA operation register */ + }; + static_assert((offsetof (struct dmac_reg, SAR0)) == 0x0); + static_assert((offsetof (struct dmac_reg, DAR0)) == 0x4); + static_assert((offsetof (struct dmac_reg, DMATCR0)) == 0x8); + static_assert((offsetof (struct dmac_reg, CHCR0)) == 0xc); + static_assert((offsetof (struct dmac_reg, SAR1)) == 0x10); + static_assert((offsetof (struct dmac_reg, DAR1)) == 0x14); + static_assert((offsetof (struct dmac_reg, DMATCR1)) == 0x18); + static_assert((offsetof (struct dmac_reg, CHCR1)) == 0x1c); + static_assert((offsetof (struct dmac_reg, SAR2)) == 0x20); + static_assert((offsetof (struct dmac_reg, DAR2)) == 0x24); + static_assert((offsetof (struct dmac_reg, DMATCR2)) == 0x28); + static_assert((offsetof (struct dmac_reg, CHCR2)) == 0x2c); + static_assert((offsetof (struct dmac_reg, SAR3)) == 0x30); + static_assert((offsetof (struct dmac_reg, DAR3)) == 0x34); + static_assert((offsetof (struct dmac_reg, DMATCR3)) == 0x38); + static_assert((offsetof (struct dmac_reg, CHCR3)) == 0x3c); + static_assert((offsetof (struct dmac_reg, DMAOR)) == 0x40); -static_assert((offsetof (struct ubc_reg, BARA)) == 0x0); -static_assert((offsetof (struct ubc_reg, BAMRA)) == 0x4); -static_assert((offsetof (struct ubc_reg, BBRA)) == 0x8); -static_assert((offsetof (struct ubc_reg, BARB)) == 0xc); -static_assert((offsetof (struct ubc_reg, BAMRB)) == 0x10); -static_assert((offsetof (struct ubc_reg, BBRB)) == 0x14); -static_assert((offsetof (struct ubc_reg, BDRB)) == 0x18); -static_assert((offsetof (struct ubc_reg, BDMRB)) == 0x1c); -static_assert((offsetof (struct ubc_reg, BRCR)) == 0x20); + struct cpg_reg { + reg16 FRQCR; /* Frequency control register */ + reg8 _pad0[2]; + reg8 STBCR; /* Standby control register */ + reg8 _pad1[3]; + reg16 WTCNT; /* Watchdog timer counter */ + reg8 _pad2[2]; + reg16 WTCSR; /* Watchdog timer control/status register */ + reg8 _pad3[2]; + reg8 STBCR2; /* Standby control register 2 */ + }; + static_assert((offsetof (struct cpg_reg, FRQCR)) == 0x0); + static_assert((offsetof (struct cpg_reg, STBCR)) == 0x4); + static_assert((offsetof (struct cpg_reg, WTCNT)) == 0x8); + static_assert((offsetof (struct cpg_reg, WTCSR)) == 0xc); + static_assert((offsetof (struct cpg_reg, STBCR2)) == 0x10); -struct bsc_reg { - reg32 BCR1; /* Bus control register 1 */ - reg16 BCR2; /* Bus control register 2 */ - reg8 _pad0[2]; - reg32 WCR1; /* Wait state control register 1 */ - reg32 WCR2; /* Wait state control register 2 */ - reg32 WCR3; /* Wait state control register 3 */ - reg32 MCR; /* Memory control register */ - reg16 PCR; /* PCMCIA control register */ - reg8 _pad1[2]; - reg16 RTCSR; /* Refresh timer control/status register */ - reg8 _pad2[2]; - reg16 RTCNT; /* Refresh timer counter */ - reg8 _pad3[2]; - reg16 RTCOR; /* Refresh timer constant counter */ - reg8 _pad4[2]; - reg16 RFCR; /* Refresh count register */ - reg8 _pad5[2]; - reg32 PCTRA; /* Port control register A */ - reg16 PDTRA; /* Port data register A */ - reg8 _pad6[14]; - reg32 PCTRB; /* Port control register B */ - reg16 PDTRB; /* Port data register B */ - reg8 _pad7[2]; - reg16 GPIOIC; /* GPIO interrupt control register */ - reg8 _pad8[1048502]; - reg32 SDMR2[16384]; /* Synchronous DRAM mode registers */ - reg8 _pad9[196608]; - reg32 SDMR3[16384]; /* Synchronous DRAM mode registers */ -}; + struct rtc_reg { + reg8 R64CNT; /* 64 Hz counter */ + reg8 _pad0[3]; + reg8 RSECCNT; /* Second counter */ + reg8 _pad1[3]; + reg8 RMINCNT; /* Minute counter */ + reg8 _pad2[3]; + reg8 RHRCNT; /* Hour counter */ + reg8 _pad3[3]; + reg8 RWKCNT; /* Day-of-week counter */ + reg8 _pad4[3]; + reg8 RDAYCNT; /* Day counter */ + reg8 _pad5[3]; + reg8 RMONCNT; /* Month counter */ + reg8 _pad6[3]; + reg16 RYRCNT; /* Year counter */ + reg8 _pad7[2]; + reg8 RSECAR; /* Second alarm register */ + reg8 _pad8[3]; + reg8 RMINAR; /* Minute alarm register */ + reg8 _pad9[3]; + reg8 RHRAR; /* Hour alarm register */ + reg8 _pad10[3]; + reg8 RWKAR; /* Day-of-week alarm register */ + reg8 _pad11[3]; + reg8 RDAYAR; /* Day alarm register */ + reg8 _pad12[3]; + reg8 RMONAR; /* Month alarm register */ + reg8 _pad13[3]; + reg8 RCR1; /* RTC control register 1 */ + reg8 _pad14[3]; + reg8 RCR2; /* RTC control register 2 */ + }; + static_assert((offsetof (struct rtc_reg, R64CNT)) == 0x0); + static_assert((offsetof (struct rtc_reg, RSECCNT)) == 0x4); + static_assert((offsetof (struct rtc_reg, RMINCNT)) == 0x8); + static_assert((offsetof (struct rtc_reg, RHRCNT)) == 0xc); + static_assert((offsetof (struct rtc_reg, RWKCNT)) == 0x10); + static_assert((offsetof (struct rtc_reg, RDAYCNT)) == 0x14); + static_assert((offsetof (struct rtc_reg, RMONCNT)) == 0x18); + static_assert((offsetof (struct rtc_reg, RYRCNT)) == 0x1c); + static_assert((offsetof (struct rtc_reg, RSECAR)) == 0x20); + static_assert((offsetof (struct rtc_reg, RMINAR)) == 0x24); + static_assert((offsetof (struct rtc_reg, RHRAR)) == 0x28); + static_assert((offsetof (struct rtc_reg, RWKAR)) == 0x2c); + static_assert((offsetof (struct rtc_reg, RDAYAR)) == 0x30); + static_assert((offsetof (struct rtc_reg, RMONAR)) == 0x34); + static_assert((offsetof (struct rtc_reg, RCR1)) == 0x38); + static_assert((offsetof (struct rtc_reg, RCR2)) == 0x3c); -static_assert((offsetof (struct bsc_reg, BCR1)) == 0x0); -static_assert((offsetof (struct bsc_reg, BCR2)) == 0x4); -static_assert((offsetof (struct bsc_reg, WCR1)) == 0x8); -static_assert((offsetof (struct bsc_reg, WCR2)) == 0xc); -static_assert((offsetof (struct bsc_reg, WCR3)) == 0x10); -static_assert((offsetof (struct bsc_reg, MCR)) == 0x14); -static_assert((offsetof (struct bsc_reg, PCR)) == 0x18); -static_assert((offsetof (struct bsc_reg, RTCSR)) == 0x1c); -static_assert((offsetof (struct bsc_reg, RTCNT)) == 0x20); -static_assert((offsetof (struct bsc_reg, RTCOR)) == 0x24); -static_assert((offsetof (struct bsc_reg, RFCR)) == 0x28); -static_assert((offsetof (struct bsc_reg, PCTRA)) == 0x2c); -static_assert((offsetof (struct bsc_reg, PDTRA)) == 0x30); -static_assert((offsetof (struct bsc_reg, PCTRB)) == 0x40); -static_assert((offsetof (struct bsc_reg, PDTRB)) == 0x44); -static_assert((offsetof (struct bsc_reg, GPIOIC)) == 0x48); -static_assert((offsetof (struct bsc_reg, SDMR2)) == 0x100000); -static_assert((offsetof (struct bsc_reg, SDMR3)) == 0x140000); + struct intc_reg { + reg16 ICR; /* Interrupt control register */ + reg8 _pad0[2]; + reg16 IPRA; /* Interrupt priority register A */ + reg8 _pad1[2]; + reg16 IPRB; /* Interrupt priority register B */ + reg8 _pad2[2]; + reg16 IPRC; /* Interrupt priority register C */ + }; + static_assert((offsetof (struct intc_reg, ICR)) == 0x0); + static_assert((offsetof (struct intc_reg, IPRA)) == 0x4); + static_assert((offsetof (struct intc_reg, IPRB)) == 0x8); + static_assert((offsetof (struct intc_reg, IPRC)) == 0xc); -struct dmac_reg { - reg32 SAR0; /* DMA source address register 0 */ - reg32 DAR0; /* DMA destination address register 0 */ - reg32 DMATCR0; /* DMA transfer count register 0 */ - reg32 CHCR0; /* DMA control register 0 */ - reg32 SAR1; /* DMA source address register 1 */ - reg32 DAR1; /* DMA destination address register 1 */ - reg32 DMATCR1; /* DMA transfer count register 1 */ - reg32 CHCR1; /* DMA control register 1 */ - reg32 SAR2; /* DMA source address register 2 */ - reg32 DAR2; /* DMA destination address register 2 */ - reg32 DMATCR2; /* DMA transfer count register 2 */ - reg32 CHCR2; /* DMA control register 2 */ - reg32 SAR3; /* DMA source address register 3 */ - reg32 DAR3; /* DMA destination address register 3 */ - reg32 DMATCR3; /* DMA transfer count register 3 */ - reg32 CHCR3; /* DMA control register 3 */ - reg32 DMAOR; /* DMA operation register */ -}; + struct tmu_reg { + reg8 TOCR; /* Timer output control register */ + reg8 _pad0[3]; + reg8 TSTR; /* Timer start register */ + reg8 _pad1[3]; + reg32 TCOR0; /* Timer constant register 0 */ + reg32 TCNT0; /* Timer counter 0 */ + reg16 TCR0; /* Timer control register 0 */ + reg8 _pad2[2]; + reg32 TCOR1; /* Timer constant register 1 */ + reg32 TCNT1; /* Timer counter 1 */ + reg16 TCR1; /* Timer control register 1 */ + reg8 _pad3[2]; + reg32 TCOR2; /* Timer constant register 2 */ + reg32 TCNT2; /* Timer counter 2 */ + reg16 TCR2; /* Timer control register 2 */ + reg8 _pad4[2]; + reg32 TCPR2; /* Timer input capture register 2 */ + }; + static_assert((offsetof (struct tmu_reg, TOCR)) == 0x0); + static_assert((offsetof (struct tmu_reg, TSTR)) == 0x4); + static_assert((offsetof (struct tmu_reg, TCOR0)) == 0x8); + static_assert((offsetof (struct tmu_reg, TCNT0)) == 0xc); + static_assert((offsetof (struct tmu_reg, TCR0)) == 0x10); + static_assert((offsetof (struct tmu_reg, TCOR1)) == 0x14); + static_assert((offsetof (struct tmu_reg, TCNT1)) == 0x18); + static_assert((offsetof (struct tmu_reg, TCR1)) == 0x1c); + static_assert((offsetof (struct tmu_reg, TCOR2)) == 0x20); + static_assert((offsetof (struct tmu_reg, TCNT2)) == 0x24); + static_assert((offsetof (struct tmu_reg, TCR2)) == 0x28); + static_assert((offsetof (struct tmu_reg, TCPR2)) == 0x2c); -static_assert((offsetof (struct dmac_reg, SAR0)) == 0x0); -static_assert((offsetof (struct dmac_reg, DAR0)) == 0x4); -static_assert((offsetof (struct dmac_reg, DMATCR0)) == 0x8); -static_assert((offsetof (struct dmac_reg, CHCR0)) == 0xc); -static_assert((offsetof (struct dmac_reg, SAR1)) == 0x10); -static_assert((offsetof (struct dmac_reg, DAR1)) == 0x14); -static_assert((offsetof (struct dmac_reg, DMATCR1)) == 0x18); -static_assert((offsetof (struct dmac_reg, CHCR1)) == 0x1c); -static_assert((offsetof (struct dmac_reg, SAR2)) == 0x20); -static_assert((offsetof (struct dmac_reg, DAR2)) == 0x24); -static_assert((offsetof (struct dmac_reg, DMATCR2)) == 0x28); -static_assert((offsetof (struct dmac_reg, CHCR2)) == 0x2c); -static_assert((offsetof (struct dmac_reg, SAR3)) == 0x30); -static_assert((offsetof (struct dmac_reg, DAR3)) == 0x34); -static_assert((offsetof (struct dmac_reg, DMATCR3)) == 0x38); -static_assert((offsetof (struct dmac_reg, CHCR3)) == 0x3c); -static_assert((offsetof (struct dmac_reg, DMAOR)) == 0x40); + struct sci_reg { + reg8 SCSMR1; /* Serial mode register 1 */ + reg8 _pad0[3]; + reg8 SCBRR1; /* Bit rate register 1 */ + reg8 _pad1[3]; + reg8 SCSCR1; /* Serial control register 1 */ + reg8 _pad2[3]; + reg8 SCTDR1; /* Transmit data register 1 */ + reg8 _pad3[3]; + reg8 SCSSR1; /* Serial status register 1 */ + reg8 _pad4[3]; + reg8 SCRDR1; /* Receive data register 1 */ + reg8 _pad5[3]; + reg8 SCSCMR1; /* Smart card mode register 1 */ + reg8 _pad6[3]; + reg8 SCSPTR1; /* Serial port register */ + }; + static_assert((offsetof (struct sci_reg, SCSMR1)) == 0x0); + static_assert((offsetof (struct sci_reg, SCBRR1)) == 0x4); + static_assert((offsetof (struct sci_reg, SCSCR1)) == 0x8); + static_assert((offsetof (struct sci_reg, SCTDR1)) == 0xc); + static_assert((offsetof (struct sci_reg, SCSSR1)) == 0x10); + static_assert((offsetof (struct sci_reg, SCRDR1)) == 0x14); + static_assert((offsetof (struct sci_reg, SCSCMR1)) == 0x18); + static_assert((offsetof (struct sci_reg, SCSPTR1)) == 0x1c); -struct cpg_reg { - reg16 FRQCR; /* Frequency control register */ - reg8 _pad0[2]; - reg8 STBCR; /* Standby control register */ - reg8 _pad1[3]; - reg16 WTCNT; /* Watchdog timer counter */ - reg8 _pad2[2]; - reg16 WTCSR; /* Watchdog timer control/status register */ - reg8 _pad3[2]; - reg8 STBCR2; /* Standby control register 2 */ -}; + struct scif_reg { + reg16 SCSMR2; /* Serial mode register 2 */ + reg8 _pad0[2]; + reg8 SCBRR2; /* Bit rate register 2 */ + reg8 _pad1[3]; + reg16 SCSCR2; /* Serial control register 2 */ + reg8 _pad2[2]; + reg8 SCFTDR2; /* Transmit FIFO data register 2 */ + reg8 _pad3[3]; + reg16 SCFSR2; /* Serial status register 2 */ + reg8 _pad4[2]; + reg8 SCFRDR2; /* Receive FIFO data register 2 */ + reg8 _pad5[3]; + reg16 SCFCR2; /* FIFO control register */ + reg8 _pad6[2]; + reg16 SCFDR2; /* FIFO data count register */ + reg8 _pad7[2]; + reg16 SCSPTR2; /* Serial port register 2 */ + reg8 _pad8[2]; + reg16 SCLSR2; /* Line status register 2 */ + }; + static_assert((offsetof (struct scif_reg, SCSMR2)) == 0x0); + static_assert((offsetof (struct scif_reg, SCBRR2)) == 0x4); + static_assert((offsetof (struct scif_reg, SCSCR2)) == 0x8); + static_assert((offsetof (struct scif_reg, SCFTDR2)) == 0xc); + static_assert((offsetof (struct scif_reg, SCFSR2)) == 0x10); + static_assert((offsetof (struct scif_reg, SCFRDR2)) == 0x14); + static_assert((offsetof (struct scif_reg, SCFCR2)) == 0x18); + static_assert((offsetof (struct scif_reg, SCFDR2)) == 0x1c); + static_assert((offsetof (struct scif_reg, SCSPTR2)) == 0x20); + static_assert((offsetof (struct scif_reg, SCLSR2)) == 0x24); -static_assert((offsetof (struct cpg_reg, FRQCR)) == 0x0); -static_assert((offsetof (struct cpg_reg, STBCR)) == 0x4); -static_assert((offsetof (struct cpg_reg, WTCNT)) == 0x8); -static_assert((offsetof (struct cpg_reg, WTCSR)) == 0xc); -static_assert((offsetof (struct cpg_reg, STBCR2)) == 0x10); + struct udi_reg { + reg16 SDIR; /* Instruction register */ + reg8 _pad0[6]; + reg32 SDDR; /* Data register */ + }; + static_assert((offsetof (struct udi_reg, SDIR)) == 0x0); + static_assert((offsetof (struct udi_reg, SDDR)) == 0x8); -struct rtc_reg { - reg8 R64CNT; /* 64 Hz counter */ - reg8 _pad0[3]; - reg8 RSECCNT; /* Second counter */ - reg8 _pad1[3]; - reg8 RMINCNT; /* Minute counter */ - reg8 _pad2[3]; - reg8 RHRCNT; /* Hour counter */ - reg8 _pad3[3]; - reg8 RWKCNT; /* Day-of-week counter */ - reg8 _pad4[3]; - reg8 RDAYCNT; /* Day counter */ - reg8 _pad5[3]; - reg8 RMONCNT; /* Month counter */ - reg8 _pad6[3]; - reg16 RYRCNT; /* Year counter */ - reg8 _pad7[2]; - reg8 RSECAR; /* Second alarm register */ - reg8 _pad8[3]; - reg8 RMINAR; /* Minute alarm register */ - reg8 _pad9[3]; - reg8 RHRAR; /* Hour alarm register */ - reg8 _pad10[3]; - reg8 RWKAR; /* Day-of-week alarm register */ - reg8 _pad11[3]; - reg8 RDAYAR; /* Day alarm register */ - reg8 _pad12[3]; - reg8 RMONAR; /* Month alarm register */ - reg8 _pad13[3]; - reg8 RCR1; /* RTC control register 1 */ - reg8 _pad14[3]; - reg8 RCR2; /* RTC control register 2 */ -}; + struct sh7091_reg { + struct ccn_reg CCN; + reg8 _pad0[0x200000 - (sizeof (struct ccn_reg))]; + struct ubc_reg UBC; + reg8 _pad1[0x600000 - (sizeof (struct ubc_reg))]; + struct bsc_reg BSC; + reg8 _pad2[0x200000 - (sizeof (struct bsc_reg))]; + struct dmac_reg DMAC; + reg8 _pad3[0x200000 - (sizeof (struct dmac_reg))]; + struct cpg_reg CPG; + reg8 _pad4[0x80000 - (sizeof (struct cpg_reg))]; + struct rtc_reg RTC; + reg8 _pad5[0x80000 - (sizeof (struct rtc_reg))]; + struct intc_reg INTC; + reg8 _pad6[0x80000 - (sizeof (struct intc_reg))]; + struct tmu_reg TMU; + reg8 _pad7[0x80000 - (sizeof (struct tmu_reg))]; + struct sci_reg SCI; + reg8 _pad8[0x80000 - (sizeof (struct sci_reg))]; + struct scif_reg SCIF; + reg8 _pad9[0x80000 - (sizeof (struct scif_reg))]; + struct udi_reg UDI; + }; + static_assert((offsetof (struct sh7091_reg, CCN)) == 0x0); + static_assert((offsetof (struct sh7091_reg, UBC)) == 0x200000); + static_assert((offsetof (struct sh7091_reg, BSC)) == 0x800000); + static_assert((offsetof (struct sh7091_reg, DMAC)) == 0xa00000); + static_assert((offsetof (struct sh7091_reg, CPG)) == 0xc00000); + static_assert((offsetof (struct sh7091_reg, RTC)) == 0xc80000); + static_assert((offsetof (struct sh7091_reg, INTC)) == 0xd00000); + static_assert((offsetof (struct sh7091_reg, TMU)) == 0xd80000); + static_assert((offsetof (struct sh7091_reg, SCI)) == 0xe00000); + static_assert((offsetof (struct sh7091_reg, SCIF)) == 0xe80000); + static_assert((offsetof (struct sh7091_reg, UDI)) == 0xf00000); -static_assert((offsetof (struct rtc_reg, R64CNT)) == 0x0); -static_assert((offsetof (struct rtc_reg, RSECCNT)) == 0x4); -static_assert((offsetof (struct rtc_reg, RMINCNT)) == 0x8); -static_assert((offsetof (struct rtc_reg, RHRCNT)) == 0xc); -static_assert((offsetof (struct rtc_reg, RWKCNT)) == 0x10); -static_assert((offsetof (struct rtc_reg, RDAYCNT)) == 0x14); -static_assert((offsetof (struct rtc_reg, RMONCNT)) == 0x18); -static_assert((offsetof (struct rtc_reg, RYRCNT)) == 0x1c); -static_assert((offsetof (struct rtc_reg, RSECAR)) == 0x20); -static_assert((offsetof (struct rtc_reg, RMINAR)) == 0x24); -static_assert((offsetof (struct rtc_reg, RHRAR)) == 0x28); -static_assert((offsetof (struct rtc_reg, RWKAR)) == 0x2c); -static_assert((offsetof (struct rtc_reg, RDAYAR)) == 0x30); -static_assert((offsetof (struct rtc_reg, RMONAR)) == 0x34); -static_assert((offsetof (struct rtc_reg, RCR1)) == 0x38); -static_assert((offsetof (struct rtc_reg, RCR2)) == 0x3c); - -struct intc_reg { - reg16 ICR; /* Interrupt control register */ - reg8 _pad0[2]; - reg16 IPRA; /* Interrupt priority register A */ - reg8 _pad1[2]; - reg16 IPRB; /* Interrupt priority register B */ - reg8 _pad2[2]; - reg16 IPRC; /* Interrupt priority register C */ -}; - -static_assert((offsetof (struct intc_reg, ICR)) == 0x0); -static_assert((offsetof (struct intc_reg, IPRA)) == 0x4); -static_assert((offsetof (struct intc_reg, IPRB)) == 0x8); -static_assert((offsetof (struct intc_reg, IPRC)) == 0xc); - -struct tmu_reg { - reg8 TOCR; /* Timer output control register */ - reg8 _pad0[3]; - reg8 TSTR; /* Timer start register */ - reg8 _pad1[3]; - reg32 TCOR0; /* Timer constant register 0 */ - reg32 TCNT0; /* Timer counter 0 */ - reg16 TCR0; /* Timer control register 0 */ - reg8 _pad2[2]; - reg32 TCOR1; /* Timer constant register 1 */ - reg32 TCNT1; /* Timer counter 1 */ - reg16 TCR1; /* Timer control register 1 */ - reg8 _pad3[2]; - reg32 TCOR2; /* Timer constant register 2 */ - reg32 TCNT2; /* Timer counter 2 */ - reg16 TCR2; /* Timer control register 2 */ - reg8 _pad4[2]; - reg32 TCPR2; /* Timer input capture register 2 */ -}; - -static_assert((offsetof (struct tmu_reg, TOCR)) == 0x0); -static_assert((offsetof (struct tmu_reg, TSTR)) == 0x4); -static_assert((offsetof (struct tmu_reg, TCOR0)) == 0x8); -static_assert((offsetof (struct tmu_reg, TCNT0)) == 0xc); -static_assert((offsetof (struct tmu_reg, TCR0)) == 0x10); -static_assert((offsetof (struct tmu_reg, TCOR1)) == 0x14); -static_assert((offsetof (struct tmu_reg, TCNT1)) == 0x18); -static_assert((offsetof (struct tmu_reg, TCR1)) == 0x1c); -static_assert((offsetof (struct tmu_reg, TCOR2)) == 0x20); -static_assert((offsetof (struct tmu_reg, TCNT2)) == 0x24); -static_assert((offsetof (struct tmu_reg, TCR2)) == 0x28); -static_assert((offsetof (struct tmu_reg, TCPR2)) == 0x2c); - -struct sci_reg { - reg8 SCSMR1; /* Serial mode register 1 */ - reg8 _pad0[3]; - reg8 SCBRR1; /* Bit rate register 1 */ - reg8 _pad1[3]; - reg8 SCSCR1; /* Serial control register 1 */ - reg8 _pad2[3]; - reg8 SCTDR1; /* Transmit data register 1 */ - reg8 _pad3[3]; - reg8 SCSSR1; /* Serial status register 1 */ - reg8 _pad4[3]; - reg8 SCRDR1; /* Receive data register 1 */ - reg8 _pad5[3]; - reg8 SCSCMR1; /* Smart card mode register 1 */ - reg8 _pad6[3]; - reg8 SCSPTR1; /* Serial port register */ -}; - -static_assert((offsetof (struct sci_reg, SCSMR1)) == 0x0); -static_assert((offsetof (struct sci_reg, SCBRR1)) == 0x4); -static_assert((offsetof (struct sci_reg, SCSCR1)) == 0x8); -static_assert((offsetof (struct sci_reg, SCTDR1)) == 0xc); -static_assert((offsetof (struct sci_reg, SCSSR1)) == 0x10); -static_assert((offsetof (struct sci_reg, SCRDR1)) == 0x14); -static_assert((offsetof (struct sci_reg, SCSCMR1)) == 0x18); -static_assert((offsetof (struct sci_reg, SCSPTR1)) == 0x1c); - -struct scif_reg { - reg16 SCSMR2; /* Serial mode register 2 */ - reg8 _pad0[2]; - reg8 SCBRR2; /* Bit rate register 2 */ - reg8 _pad1[3]; - reg16 SCSCR2; /* Serial control register 2 */ - reg8 _pad2[2]; - reg8 SCFTDR2; /* Transmit FIFO data register 2 */ - reg8 _pad3[3]; - reg16 SCFSR2; /* Serial status register 2 */ - reg8 _pad4[2]; - reg8 SCFRDR2; /* Receive FIFO data register 2 */ - reg8 _pad5[3]; - reg16 SCFCR2; /* FIFO control register */ - reg8 _pad6[2]; - reg16 SCFDR2; /* FIFO data count register */ - reg8 _pad7[2]; - reg16 SCSPTR2; /* Serial port register 2 */ - reg8 _pad8[2]; - reg16 SCLSR2; /* Line status register 2 */ -}; - -static_assert((offsetof (struct scif_reg, SCSMR2)) == 0x0); -static_assert((offsetof (struct scif_reg, SCBRR2)) == 0x4); -static_assert((offsetof (struct scif_reg, SCSCR2)) == 0x8); -static_assert((offsetof (struct scif_reg, SCFTDR2)) == 0xc); -static_assert((offsetof (struct scif_reg, SCFSR2)) == 0x10); -static_assert((offsetof (struct scif_reg, SCFRDR2)) == 0x14); -static_assert((offsetof (struct scif_reg, SCFCR2)) == 0x18); -static_assert((offsetof (struct scif_reg, SCFDR2)) == 0x1c); -static_assert((offsetof (struct scif_reg, SCSPTR2)) == 0x20); -static_assert((offsetof (struct scif_reg, SCLSR2)) == 0x24); - -struct udi_reg { - reg16 SDIR; /* Instruction register */ - reg8 _pad0[6]; - reg32 SDDR; /* Data register */ -}; - -static_assert((offsetof (struct udi_reg, SDIR)) == 0x0); -static_assert((offsetof (struct udi_reg, SDDR)) == 0x8); - -struct sh7091_reg { - struct ccn_reg CCN; - reg8 _pad0[0x200000 - (sizeof (struct ccn_reg))]; - struct ubc_reg UBC; - reg8 _pad1[0x600000 - (sizeof (struct ubc_reg))]; - struct bsc_reg BSC; - reg8 _pad2[0x200000 - (sizeof (struct bsc_reg))]; - struct dmac_reg DMAC; - reg8 _pad3[0x200000 - (sizeof (struct dmac_reg))]; - struct cpg_reg CPG; - reg8 _pad4[0x80000 - (sizeof (struct cpg_reg))]; - struct rtc_reg RTC; - reg8 _pad5[0x80000 - (sizeof (struct rtc_reg))]; - struct intc_reg INTC; - reg8 _pad6[0x80000 - (sizeof (struct intc_reg))]; - struct tmu_reg TMU; - reg8 _pad7[0x80000 - (sizeof (struct tmu_reg))]; - struct sci_reg SCI; - reg8 _pad8[0x80000 - (sizeof (struct sci_reg))]; - struct scif_reg SCIF; - reg8 _pad9[0x80000 - (sizeof (struct scif_reg))]; - struct udi_reg UDI; -}; - -static_assert((offsetof (struct sh7091_reg, CCN)) == 0x0); -static_assert((offsetof (struct sh7091_reg, UBC)) == 0x200000); -static_assert((offsetof (struct sh7091_reg, BSC)) == 0x800000); -static_assert((offsetof (struct sh7091_reg, DMAC)) == 0xa00000); -static_assert((offsetof (struct sh7091_reg, CPG)) == 0xc00000); -static_assert((offsetof (struct sh7091_reg, RTC)) == 0xc80000); -static_assert((offsetof (struct sh7091_reg, INTC)) == 0xd00000); -static_assert((offsetof (struct sh7091_reg, TMU)) == 0xd80000); -static_assert((offsetof (struct sh7091_reg, SCI)) == 0xe00000); -static_assert((offsetof (struct sh7091_reg, SCIF)) == 0xe80000); -static_assert((offsetof (struct sh7091_reg, UDI)) == 0xf00000); - -extern struct sh7091_reg sh7091 __asm("sh7091"); + extern struct sh7091_reg sh7091 __asm("sh7091"); +} diff --git a/dreamcast2/sh7091/store_queue_transfer.hpp b/dreamcast2/sh7091/store_queue_transfer.hpp index 9c3a25b..6f8e205 100644 --- a/dreamcast2/sh7091/store_queue_transfer.hpp +++ b/dreamcast2/sh7091/store_queue_transfer.hpp @@ -6,6 +6,10 @@ namespace sh7091 { namespace store_queue_transfer { + static inline void copy(void * out_addr, + const void * src, + int length) __attribute__((always_inline)); + static inline void copy(void * out_addr, const void * src, int length) @@ -14,7 +18,7 @@ namespace sh7091 { sh7091.CCN.QACR0 = ((out >> 24) & 0b11100); sh7091.CCN.QACR1 = ((out >> 24) & 0b11100); - volatile uint32_t * base = &store_queue[(out & 0x03ffffe0)]; + volatile uint32_t * base = (volatile uint32_t *)&store_queue[(out & 0x03ffffe0)]; const uint32_t * src32 = reinterpret_cast(src); length = (length + 31) & ~31; // round up to nearest multiple of 32 @@ -38,6 +42,10 @@ namespace sh7091 { } + static inline void zeroize(void * out_addr, + int length, + const uint32_t value) __attribute__((always_inline)); + static inline void zeroize(void * out_addr, int length, const uint32_t value) @@ -46,7 +54,7 @@ namespace sh7091 { sh7091.CCN.QACR0 = ((out >> 24) & 0b11100); sh7091.CCN.QACR1 = ((out >> 24) & 0b11100); - volatile uint32_t * base = &store_queue[(out & 0x03ffffe0)]; + volatile uint32_t * base = (volatile uint32_t *)&store_queue[(out & 0x03ffffe0)]; length = (length + 31) & ~31; // round up to nearest multiple of 32 while (length > 0) { diff --git a/dreamcast2/start.s b/dreamcast2/start.s new file mode 100644 index 0000000..a5e32ff --- /dev/null +++ b/dreamcast2/start.s @@ -0,0 +1,41 @@ + .section .text.start + .global _start +_start: + /* set stack pointer */ + mov.l stack_end_ptr,r15 + + /* mask all interrupts */ + mov.l imask_all,r0 + mov.l zero_rb,r2 + stc sr,r1 + or r1,r0 + and r0,r2 + ldc r2,sr + + /* save pr */ + sts.l pr,@-r15 + + /* jump to runtime_init */ + mov.l runtime_init_ptr,r0 + jsr @r0 + nop + + /* restore pr */ + lds.l @r15+,pr + + /* jump to main */ + mov.l main_ptr,r0 + jmp @r0 + nop + + .align 4 +stack_end_ptr: + .long __stack_end +imask_all: + .long 0xf0 +zero_rb: + .long ~(1 << 29) +runtime_init_ptr: + .long __Z12runtime_initv +main_ptr: + .long _main diff --git a/dreamcast2/symbols.lds b/dreamcast2/symbols.lds new file mode 100644 index 0000000..3c1faa6 --- /dev/null +++ b/dreamcast2/symbols.lds @@ -0,0 +1,21 @@ +__text_link_start = ADDR(.text); +__text_link_end = ADDR(.text) + SIZEOF(.text); +__text_load_start = LOADADDR(.text); + +__data_link_start = ADDR(.data); +__data_link_end = ADDR(.data) + SIZEOF(.data); +__data_load_start = LOADADDR(.data); + +__rodata_link_start = ADDR(.rodata); +__rodata_link_end = ADDR(.rodata) + SIZEOF(.rodata); +__rodata_load_start = LOADADDR(.rodata); + +__ctors_link_start = ADDR(.ctors); +__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); + +__bss_link_start = ADDR(.bss); +__bss_link_end = ADDR(.bss) + SIZEOF(.bss); + +__vbr_link_start = ADDR(.text.vbr); +__vbr_link_end = ADDR(.text.vbr) + SIZEOF(.text.vbr); +__vbr_load_end = LOADADDR(.text.vbr); diff --git a/dreamcast2/systembus/systembus.hpp b/dreamcast2/systembus/systembus.hpp index efbc170..6805f6c 100644 --- a/dreamcast2/systembus/systembus.hpp +++ b/dreamcast2/systembus/systembus.hpp @@ -2,307 +2,308 @@ #include "reg.hpp" -struct systembus_reg { - 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 */ - 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 */ - 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 */ - reg8 _pad3[8]; - 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 */ - reg8 _pad5[4]; - 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 */ - reg8 _pad7[4]; - 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 */ - reg8 _pad9[8]; - reg32 G2DTNRM; /* Normal interrupt G2-DMA startup mask */ - reg32 G2DTEXT; /* External interrupt G2-DMA startup mask */ -}; +namespace systembus { + struct systembus_reg { + 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 */ + 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 */ + 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 */ + reg8 _pad3[8]; + 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 */ + reg8 _pad5[4]; + 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 */ + reg8 _pad7[4]; + 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 */ + reg8 _pad9[8]; + reg32 G2DTNRM; /* Normal interrupt G2-DMA startup mask */ + reg32 G2DTEXT; /* External interrupt G2-DMA startup mask */ + }; + static_assert((offsetof (struct systembus_reg, C2DSTAT)) == 0x0); + static_assert((offsetof (struct systembus_reg, C2DLEN)) == 0x4); + static_assert((offsetof (struct systembus_reg, C2DST)) == 0x8); + static_assert((offsetof (struct systembus_reg, SDSTAW)) == 0x10); + static_assert((offsetof (struct systembus_reg, SDBAAW)) == 0x14); + static_assert((offsetof (struct systembus_reg, SDWLT)) == 0x18); + static_assert((offsetof (struct systembus_reg, SDLAS)) == 0x1c); + static_assert((offsetof (struct systembus_reg, SDST)) == 0x20); + static_assert((offsetof (struct systembus_reg, DBREQM)) == 0x40); + static_assert((offsetof (struct systembus_reg, BAVLWC)) == 0x44); + static_assert((offsetof (struct systembus_reg, C2DPYRC)) == 0x48); + static_assert((offsetof (struct systembus_reg, DMAXL)) == 0x4c); + static_assert((offsetof (struct systembus_reg, TFREM)) == 0x80); + static_assert((offsetof (struct systembus_reg, LMMODE0)) == 0x84); + static_assert((offsetof (struct systembus_reg, LMMODE1)) == 0x88); + static_assert((offsetof (struct systembus_reg, FFST)) == 0x8c); + static_assert((offsetof (struct systembus_reg, SFRES)) == 0x90); + static_assert((offsetof (struct systembus_reg, SBREV)) == 0x9c); + static_assert((offsetof (struct systembus_reg, RBSPLT)) == 0xa0); + static_assert((offsetof (struct systembus_reg, ISTNRM)) == 0x100); + static_assert((offsetof (struct systembus_reg, ISTEXT)) == 0x104); + static_assert((offsetof (struct systembus_reg, ISTERR)) == 0x108); + static_assert((offsetof (struct systembus_reg, IML2NRM)) == 0x110); + static_assert((offsetof (struct systembus_reg, IML2EXT)) == 0x114); + static_assert((offsetof (struct systembus_reg, IML2ERR)) == 0x118); + static_assert((offsetof (struct systembus_reg, IML4NRM)) == 0x120); + static_assert((offsetof (struct systembus_reg, IML4EXT)) == 0x124); + static_assert((offsetof (struct systembus_reg, IML4ERR)) == 0x128); + static_assert((offsetof (struct systembus_reg, IML6NRM)) == 0x130); + static_assert((offsetof (struct systembus_reg, IML6EXT)) == 0x134); + static_assert((offsetof (struct systembus_reg, IML6ERR)) == 0x138); + static_assert((offsetof (struct systembus_reg, PDTNRM)) == 0x140); + static_assert((offsetof (struct systembus_reg, PDTEXT)) == 0x144); + static_assert((offsetof (struct systembus_reg, G2DTNRM)) == 0x150); + static_assert((offsetof (struct systembus_reg, G2DTEXT)) == 0x154); -static_assert((offsetof (struct systembus_reg, C2DSTAT)) == 0x0); -static_assert((offsetof (struct systembus_reg, C2DLEN)) == 0x4); -static_assert((offsetof (struct systembus_reg, C2DST)) == 0x8); -static_assert((offsetof (struct systembus_reg, SDSTAW)) == 0x10); -static_assert((offsetof (struct systembus_reg, SDBAAW)) == 0x14); -static_assert((offsetof (struct systembus_reg, SDWLT)) == 0x18); -static_assert((offsetof (struct systembus_reg, SDLAS)) == 0x1c); -static_assert((offsetof (struct systembus_reg, SDST)) == 0x20); -static_assert((offsetof (struct systembus_reg, DBREQM)) == 0x40); -static_assert((offsetof (struct systembus_reg, BAVLWC)) == 0x44); -static_assert((offsetof (struct systembus_reg, C2DPYRC)) == 0x48); -static_assert((offsetof (struct systembus_reg, DMAXL)) == 0x4c); -static_assert((offsetof (struct systembus_reg, TFREM)) == 0x80); -static_assert((offsetof (struct systembus_reg, LMMODE0)) == 0x84); -static_assert((offsetof (struct systembus_reg, LMMODE1)) == 0x88); -static_assert((offsetof (struct systembus_reg, FFST)) == 0x8c); -static_assert((offsetof (struct systembus_reg, SFRES)) == 0x90); -static_assert((offsetof (struct systembus_reg, SBREV)) == 0x9c); -static_assert((offsetof (struct systembus_reg, RBSPLT)) == 0xa0); -static_assert((offsetof (struct systembus_reg, ISTNRM)) == 0x100); -static_assert((offsetof (struct systembus_reg, ISTEXT)) == 0x104); -static_assert((offsetof (struct systembus_reg, ISTERR)) == 0x108); -static_assert((offsetof (struct systembus_reg, IML2NRM)) == 0x110); -static_assert((offsetof (struct systembus_reg, IML2EXT)) == 0x114); -static_assert((offsetof (struct systembus_reg, IML2ERR)) == 0x118); -static_assert((offsetof (struct systembus_reg, IML4NRM)) == 0x120); -static_assert((offsetof (struct systembus_reg, IML4EXT)) == 0x124); -static_assert((offsetof (struct systembus_reg, IML4ERR)) == 0x128); -static_assert((offsetof (struct systembus_reg, IML6NRM)) == 0x130); -static_assert((offsetof (struct systembus_reg, IML6EXT)) == 0x134); -static_assert((offsetof (struct systembus_reg, IML6ERR)) == 0x138); -static_assert((offsetof (struct systembus_reg, PDTNRM)) == 0x140); -static_assert((offsetof (struct systembus_reg, PDTEXT)) == 0x144); -static_assert((offsetof (struct systembus_reg, G2DTNRM)) == 0x150); -static_assert((offsetof (struct systembus_reg, G2DTEXT)) == 0x154); + struct maple_if_reg { + reg8 _pad0[4]; + 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 */ + 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 */ + reg8 _pad3[88]; + 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 */ + }; + static_assert((offsetof (struct maple_if_reg, MDSTAR)) == 0x4); + static_assert((offsetof (struct maple_if_reg, MDTSEL)) == 0x10); + static_assert((offsetof (struct maple_if_reg, MDEN)) == 0x14); + static_assert((offsetof (struct maple_if_reg, MDST)) == 0x18); + static_assert((offsetof (struct maple_if_reg, MSYS)) == 0x80); + static_assert((offsetof (struct maple_if_reg, MST)) == 0x84); + static_assert((offsetof (struct maple_if_reg, MSHTCL)) == 0x88); + static_assert((offsetof (struct maple_if_reg, MDAPRO)) == 0x8c); + static_assert((offsetof (struct maple_if_reg, MMSEL)) == 0xe8); + static_assert((offsetof (struct maple_if_reg, MTXDAD)) == 0xf4); + static_assert((offsetof (struct maple_if_reg, MRXDAD)) == 0xf8); + static_assert((offsetof (struct maple_if_reg, MRXDBD)) == 0xfc); -struct maple_if_reg { - reg8 _pad0[4]; - 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 */ - 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 */ - reg8 _pad3[88]; - 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 */ -}; + struct g1_if_reg { + reg8 _pad0[4]; + 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 */ + 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 */ + reg8 _pad3[8]; + 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 */ + reg8 _pad5[40]; + reg32 GDUNLOCK; /* (undocumented unlock register) */ + reg8 _pad6[12]; + reg32 GDSTARD; /* GD-DMA address count (on Root Bus) */ + reg32 GDLEND; /* GD-DMA transfer counter */ + }; + static_assert((offsetof (struct g1_if_reg, GDSTAR)) == 0x4); + static_assert((offsetof (struct g1_if_reg, GDLEN)) == 0x8); + static_assert((offsetof (struct g1_if_reg, GDDIR)) == 0xc); + static_assert((offsetof (struct g1_if_reg, GDEN)) == 0x14); + static_assert((offsetof (struct g1_if_reg, GDST)) == 0x18); + static_assert((offsetof (struct g1_if_reg, G1RRC)) == 0x80); + static_assert((offsetof (struct g1_if_reg, G1RWC)) == 0x84); + static_assert((offsetof (struct g1_if_reg, G1FRC)) == 0x88); + static_assert((offsetof (struct g1_if_reg, G1FWC)) == 0x8c); + static_assert((offsetof (struct g1_if_reg, G1CRC)) == 0x90); + static_assert((offsetof (struct g1_if_reg, G1CWC)) == 0x94); + static_assert((offsetof (struct g1_if_reg, G1GDRC)) == 0xa0); + static_assert((offsetof (struct g1_if_reg, G1GDWC)) == 0xa4); + static_assert((offsetof (struct g1_if_reg, G1SYSM)) == 0xb0); + static_assert((offsetof (struct g1_if_reg, G1CRDYC)) == 0xb4); + static_assert((offsetof (struct g1_if_reg, GDAPRO)) == 0xb8); + static_assert((offsetof (struct g1_if_reg, GDUNLOCK)) == 0xe4); + static_assert((offsetof (struct g1_if_reg, GDSTARD)) == 0xf4); + static_assert((offsetof (struct g1_if_reg, GDLEND)) == 0xf8); -static_assert((offsetof (struct maple_if_reg, MDSTAR)) == 0x4); -static_assert((offsetof (struct maple_if_reg, MDTSEL)) == 0x10); -static_assert((offsetof (struct maple_if_reg, MDEN)) == 0x14); -static_assert((offsetof (struct maple_if_reg, MDST)) == 0x18); -static_assert((offsetof (struct maple_if_reg, MSYS)) == 0x80); -static_assert((offsetof (struct maple_if_reg, MST)) == 0x84); -static_assert((offsetof (struct maple_if_reg, MSHTCL)) == 0x88); -static_assert((offsetof (struct maple_if_reg, MDAPRO)) == 0x8c); -static_assert((offsetof (struct maple_if_reg, MMSEL)) == 0xe8); -static_assert((offsetof (struct maple_if_reg, MTXDAD)) == 0xf4); -static_assert((offsetof (struct maple_if_reg, MRXDAD)) == 0xf8); -static_assert((offsetof (struct maple_if_reg, MRXDBD)) == 0xfc); + 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 */ + 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 */ + 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 */ + 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 */ + 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 */ + 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 */ + }; + static_assert((offsetof (struct g2_if_reg, ADSTAG)) == 0x0); + static_assert((offsetof (struct g2_if_reg, ADSTAR)) == 0x4); + static_assert((offsetof (struct g2_if_reg, ADLEN)) == 0x8); + static_assert((offsetof (struct g2_if_reg, ADDIR)) == 0xc); + static_assert((offsetof (struct g2_if_reg, ADTSEL)) == 0x10); + static_assert((offsetof (struct g2_if_reg, ADEN)) == 0x14); + static_assert((offsetof (struct g2_if_reg, ADST)) == 0x18); + static_assert((offsetof (struct g2_if_reg, ADSUSP)) == 0x1c); + static_assert((offsetof (struct g2_if_reg, E1STAG)) == 0x20); + static_assert((offsetof (struct g2_if_reg, E1STAR)) == 0x24); + static_assert((offsetof (struct g2_if_reg, E1LEN)) == 0x28); + static_assert((offsetof (struct g2_if_reg, E1DIR)) == 0x2c); + static_assert((offsetof (struct g2_if_reg, E1TSEL)) == 0x30); + static_assert((offsetof (struct g2_if_reg, E1EN)) == 0x34); + static_assert((offsetof (struct g2_if_reg, E1ST)) == 0x38); + static_assert((offsetof (struct g2_if_reg, E1SUSP)) == 0x3c); + static_assert((offsetof (struct g2_if_reg, E2STAG)) == 0x40); + static_assert((offsetof (struct g2_if_reg, E2STAR)) == 0x44); + static_assert((offsetof (struct g2_if_reg, E2LEN)) == 0x48); + static_assert((offsetof (struct g2_if_reg, E2DIR)) == 0x4c); + static_assert((offsetof (struct g2_if_reg, E2TSEL)) == 0x50); + static_assert((offsetof (struct g2_if_reg, E2EN)) == 0x54); + static_assert((offsetof (struct g2_if_reg, E2ST)) == 0x58); + static_assert((offsetof (struct g2_if_reg, E2SUSP)) == 0x5c); + static_assert((offsetof (struct g2_if_reg, DDSTAG)) == 0x60); + static_assert((offsetof (struct g2_if_reg, DDSTAR)) == 0x64); + static_assert((offsetof (struct g2_if_reg, DDLEN)) == 0x68); + static_assert((offsetof (struct g2_if_reg, DDDIR)) == 0x6c); + static_assert((offsetof (struct g2_if_reg, DDTSEL)) == 0x70); + static_assert((offsetof (struct g2_if_reg, DDEN)) == 0x74); + static_assert((offsetof (struct g2_if_reg, DDST)) == 0x78); + static_assert((offsetof (struct g2_if_reg, DDSUSP)) == 0x7c); + static_assert((offsetof (struct g2_if_reg, G2ID)) == 0x80); + static_assert((offsetof (struct g2_if_reg, G2DSTO)) == 0x90); + static_assert((offsetof (struct g2_if_reg, G2TRTO)) == 0x94); + static_assert((offsetof (struct g2_if_reg, G2MDMTO)) == 0x98); + static_assert((offsetof (struct g2_if_reg, G2MDMW)) == 0x9c); + static_assert((offsetof (struct g2_if_reg, G2APRO)) == 0xbc); + static_assert((offsetof (struct g2_if_reg, ADSTAGD)) == 0xc0); + static_assert((offsetof (struct g2_if_reg, ADSTARD)) == 0xc4); + static_assert((offsetof (struct g2_if_reg, ADLEND)) == 0xc8); + static_assert((offsetof (struct g2_if_reg, E1STAGD)) == 0xd0); + static_assert((offsetof (struct g2_if_reg, E1STARD)) == 0xd4); + static_assert((offsetof (struct g2_if_reg, E1LEND)) == 0xd8); + static_assert((offsetof (struct g2_if_reg, E2STAGD)) == 0xe0); + static_assert((offsetof (struct g2_if_reg, E2STARD)) == 0xe4); + static_assert((offsetof (struct g2_if_reg, E2LEND)) == 0xe8); + static_assert((offsetof (struct g2_if_reg, DDSTAGD)) == 0xf0); + static_assert((offsetof (struct g2_if_reg, DDSTARD)) == 0xf4); + static_assert((offsetof (struct g2_if_reg, DDLEND)) == 0xf8); -struct g1_if_reg { - reg8 _pad0[4]; - 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 */ - 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 */ - reg8 _pad3[8]; - 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 */ - reg8 _pad5[40]; - reg32 GDUNLOCK; /* (undocumented unlock register) */ - reg8 _pad6[12]; - reg32 GDSTARD; /* GD-DMA address count (on Root Bus) */ - reg32 GDLEND; /* GD-DMA transfer counter */ -}; + 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 */ + reg8 _pad0[100]; + 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 */ + }; + static_assert((offsetof (struct pvr_if_reg, PDSTAP)) == 0x0); + static_assert((offsetof (struct pvr_if_reg, PDSTAR)) == 0x4); + static_assert((offsetof (struct pvr_if_reg, PDLEN)) == 0x8); + static_assert((offsetof (struct pvr_if_reg, PDDIR)) == 0xc); + static_assert((offsetof (struct pvr_if_reg, PDTSEL)) == 0x10); + static_assert((offsetof (struct pvr_if_reg, PDEN)) == 0x14); + static_assert((offsetof (struct pvr_if_reg, PDST)) == 0x18); + static_assert((offsetof (struct pvr_if_reg, PDAPRO)) == 0x80); + static_assert((offsetof (struct pvr_if_reg, PDSTAPD)) == 0xf0); + static_assert((offsetof (struct pvr_if_reg, PDSTARD)) == 0xf4); + static_assert((offsetof (struct pvr_if_reg, PDLEND)) == 0xf8); -static_assert((offsetof (struct g1_if_reg, GDSTAR)) == 0x4); -static_assert((offsetof (struct g1_if_reg, GDLEN)) == 0x8); -static_assert((offsetof (struct g1_if_reg, GDDIR)) == 0xc); -static_assert((offsetof (struct g1_if_reg, GDEN)) == 0x14); -static_assert((offsetof (struct g1_if_reg, GDST)) == 0x18); -static_assert((offsetof (struct g1_if_reg, G1RRC)) == 0x80); -static_assert((offsetof (struct g1_if_reg, G1RWC)) == 0x84); -static_assert((offsetof (struct g1_if_reg, G1FRC)) == 0x88); -static_assert((offsetof (struct g1_if_reg, G1FWC)) == 0x8c); -static_assert((offsetof (struct g1_if_reg, G1CRC)) == 0x90); -static_assert((offsetof (struct g1_if_reg, G1CWC)) == 0x94); -static_assert((offsetof (struct g1_if_reg, G1GDRC)) == 0xa0); -static_assert((offsetof (struct g1_if_reg, G1GDWC)) == 0xa4); -static_assert((offsetof (struct g1_if_reg, G1SYSM)) == 0xb0); -static_assert((offsetof (struct g1_if_reg, G1CRDYC)) == 0xb4); -static_assert((offsetof (struct g1_if_reg, GDAPRO)) == 0xb8); -static_assert((offsetof (struct g1_if_reg, GDUNLOCK)) == 0xe4); -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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ -}; - -static_assert((offsetof (struct g2_if_reg, ADSTAG)) == 0x0); -static_assert((offsetof (struct g2_if_reg, ADSTAR)) == 0x4); -static_assert((offsetof (struct g2_if_reg, ADLEN)) == 0x8); -static_assert((offsetof (struct g2_if_reg, ADDIR)) == 0xc); -static_assert((offsetof (struct g2_if_reg, ADTSEL)) == 0x10); -static_assert((offsetof (struct g2_if_reg, ADEN)) == 0x14); -static_assert((offsetof (struct g2_if_reg, ADST)) == 0x18); -static_assert((offsetof (struct g2_if_reg, ADSUSP)) == 0x1c); -static_assert((offsetof (struct g2_if_reg, E1STAG)) == 0x20); -static_assert((offsetof (struct g2_if_reg, E1STAR)) == 0x24); -static_assert((offsetof (struct g2_if_reg, E1LEN)) == 0x28); -static_assert((offsetof (struct g2_if_reg, E1DIR)) == 0x2c); -static_assert((offsetof (struct g2_if_reg, E1TSEL)) == 0x30); -static_assert((offsetof (struct g2_if_reg, E1EN)) == 0x34); -static_assert((offsetof (struct g2_if_reg, E1ST)) == 0x38); -static_assert((offsetof (struct g2_if_reg, E1SUSP)) == 0x3c); -static_assert((offsetof (struct g2_if_reg, E2STAG)) == 0x40); -static_assert((offsetof (struct g2_if_reg, E2STAR)) == 0x44); -static_assert((offsetof (struct g2_if_reg, E2LEN)) == 0x48); -static_assert((offsetof (struct g2_if_reg, E2DIR)) == 0x4c); -static_assert((offsetof (struct g2_if_reg, E2TSEL)) == 0x50); -static_assert((offsetof (struct g2_if_reg, E2EN)) == 0x54); -static_assert((offsetof (struct g2_if_reg, E2ST)) == 0x58); -static_assert((offsetof (struct g2_if_reg, E2SUSP)) == 0x5c); -static_assert((offsetof (struct g2_if_reg, DDSTAG)) == 0x60); -static_assert((offsetof (struct g2_if_reg, DDSTAR)) == 0x64); -static_assert((offsetof (struct g2_if_reg, DDLEN)) == 0x68); -static_assert((offsetof (struct g2_if_reg, DDDIR)) == 0x6c); -static_assert((offsetof (struct g2_if_reg, DDTSEL)) == 0x70); -static_assert((offsetof (struct g2_if_reg, DDEN)) == 0x74); -static_assert((offsetof (struct g2_if_reg, DDST)) == 0x78); -static_assert((offsetof (struct g2_if_reg, DDSUSP)) == 0x7c); -static_assert((offsetof (struct g2_if_reg, G2ID)) == 0x80); -static_assert((offsetof (struct g2_if_reg, G2DSTO)) == 0x90); -static_assert((offsetof (struct g2_if_reg, G2TRTO)) == 0x94); -static_assert((offsetof (struct g2_if_reg, G2MDMTO)) == 0x98); -static_assert((offsetof (struct g2_if_reg, G2MDMW)) == 0x9c); -static_assert((offsetof (struct g2_if_reg, G2APRO)) == 0xbc); -static_assert((offsetof (struct g2_if_reg, ADSTAGD)) == 0xc0); -static_assert((offsetof (struct g2_if_reg, ADSTARD)) == 0xc4); -static_assert((offsetof (struct g2_if_reg, ADLEND)) == 0xc8); -static_assert((offsetof (struct g2_if_reg, E1STAGD)) == 0xd0); -static_assert((offsetof (struct g2_if_reg, E1STARD)) == 0xd4); -static_assert((offsetof (struct g2_if_reg, E1LEND)) == 0xd8); -static_assert((offsetof (struct g2_if_reg, E2STAGD)) == 0xe0); -static_assert((offsetof (struct g2_if_reg, E2STARD)) == 0xe4); -static_assert((offsetof (struct g2_if_reg, E2LEND)) == 0xe8); -static_assert((offsetof (struct g2_if_reg, DDSTAGD)) == 0xf0); -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 */ - reg8 _pad0[100]; - 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 */ -}; - -static_assert((offsetof (struct pvr_if_reg, PDSTAP)) == 0x0); -static_assert((offsetof (struct pvr_if_reg, PDSTAR)) == 0x4); -static_assert((offsetof (struct pvr_if_reg, PDLEN)) == 0x8); -static_assert((offsetof (struct pvr_if_reg, PDDIR)) == 0xc); -static_assert((offsetof (struct pvr_if_reg, PDTSEL)) == 0x10); -static_assert((offsetof (struct pvr_if_reg, PDEN)) == 0x14); -static_assert((offsetof (struct pvr_if_reg, PDST)) == 0x18); -static_assert((offsetof (struct pvr_if_reg, PDAPRO)) == 0x80); -static_assert((offsetof (struct pvr_if_reg, PDSTAPD)) == 0xf0); -static_assert((offsetof (struct pvr_if_reg, PDSTARD)) == 0xf4); -static_assert((offsetof (struct pvr_if_reg, PDLEND)) == 0xf8); - -extern struct holly_reg holly __asm("holly"); + extern struct systembus_reg systembus __asm("systembus"); + extern struct maple_if_reg maple_if __asm("maple_if"); + extern struct g1_if_reg g1_if __asm("g1_if"); + extern struct g2_if_reg g2_if __asm("g2_if"); + extern struct pvr_if_reg pvr_if __asm("pvr_if"); +} diff --git a/dreamcast2/systembus/systembus_bits.hpp b/dreamcast2/systembus/systembus_bits.hpp new file mode 100644 index 0000000..95ace0c --- /dev/null +++ b/dreamcast2/systembus/systembus_bits.hpp @@ -0,0 +1,89 @@ +#pragma once + +#include + +namespace systembus { + namespace c2dstat { + constexpr uint32_t texture_memory_start_address(uint32_t num) { return (num & 0x13ffffe0) << 0; } + } + + namespace c2dlen { + constexpr uint32_t transfer_length(uint32_t num) { return (num & 0xffffe0) << 0; } + } + + namespace c2dst { + constexpr uint32_t start = 1 << 0; + } + + namespace istnrm { + constexpr uint32_t end_of_transferring_punch_through_list = 1 << 21; + constexpr uint32_t end_of_dma_sort_dma = 1 << 20; + constexpr uint32_t end_of_dma_ch2_dma = 1 << 19; + constexpr uint32_t end_of_dma_dev_dma = 1 << 18; + constexpr uint32_t end_of_dma_ext_dma2 = 1 << 17; + constexpr uint32_t end_of_dma_ext_dma1 = 1 << 16; + constexpr uint32_t end_of_dma_aica_dma = 1 << 15; + constexpr uint32_t end_of_dma_gd_dma = 1 << 14; + constexpr uint32_t maple_v_blank_over = 1 << 13; + constexpr uint32_t end_of_dma_maple_dma = 1 << 12; + constexpr uint32_t end_of_dma_pvr_dma = 1 << 11; + constexpr uint32_t end_of_transferring_translucent_modifier_volume_list = 1 << 10; + constexpr uint32_t end_of_transferring_translucent_list = 1 << 9; + constexpr uint32_t end_of_transferring_opaque_modifier_volume_list = 1 << 8; + constexpr uint32_t end_of_transferring_opaque_list = 1 << 7; + constexpr uint32_t end_of_transferring_yuv = 1 << 6; + constexpr uint32_t h_blank_in = 1 << 5; + constexpr uint32_t v_blank_out = 1 << 4; + constexpr uint32_t v_blank_in = 1 << 3; + constexpr uint32_t end_of_render_tsp = 1 << 2; + constexpr uint32_t end_of_render_isp = 1 << 1; + constexpr uint32_t end_of_render_video = 1 << 0; + } + + namespace isterr { + constexpr uint32_t sh4__if_access_inhibited_area = 1 << 31; + constexpr uint32_t ddt__if_sort_dma_command_error = 1 << 28; + constexpr uint32_t g2__time_out_in_cpu_access = 1 << 27; + constexpr uint32_t g2__dev_dma_time_out = 1 << 26; + constexpr uint32_t g2__ext_dma2_time_out = 1 << 25; + constexpr uint32_t g2__ext_dma1_time_out = 1 << 24; + constexpr uint32_t g2__aica_dma_time_out = 1 << 23; + constexpr uint32_t g2__dev_dma_over_run = 1 << 22; + constexpr uint32_t g2__ext_dma2_over_run = 1 << 21; + constexpr uint32_t g2__ext_dma1_over_run = 1 << 20; + constexpr uint32_t g2__aica_dma_over_run = 1 << 19; + constexpr uint32_t g2__dev_dma_illegal_address_set = 1 << 18; + constexpr uint32_t g2__ext_dma2_illegal_address_set = 1 << 17; + constexpr uint32_t g2__ext_dma1_illegal_address_set = 1 << 16; + constexpr uint32_t g2__aica_dma_illegal_address_set = 1 << 15; + constexpr uint32_t g1__rom_flash_access_at_gd_dma = 1 << 14; + constexpr uint32_t g1__gd_dma_over_run = 1 << 13; + constexpr uint32_t g1__illegal_address_set = 1 << 12; + constexpr uint32_t maple__illegal_command = 1 << 11; + constexpr uint32_t maple__write_fifo_over_flow = 1 << 10; + constexpr uint32_t maple__dma_over_run = 1 << 9; + constexpr uint32_t maple__illegal_address_set = 1 << 8; + constexpr uint32_t pvrif__dma_over_run = 1 << 7; + constexpr uint32_t pvrif__illegal_address_set = 1 << 6; + constexpr uint32_t ta__fifo_overflow = 1 << 5; + constexpr uint32_t ta__illegal_parameter = 1 << 4; + constexpr uint32_t ta__object_list_pointer_overflow = 1 << 3; + constexpr uint32_t ta__isp_tsp_parameter_overflow = 1 << 2; + constexpr uint32_t render__hazard_processing_of_strip_buffer = 1 << 1; + constexpr uint32_t render__isp_out_of_cache = 1 << 0; + } + + namespace ffst { + constexpr uint32_t holly_cpu_if_block_internal_write_buffer(uint32_t reg) { return (reg >> 5) & 0x1; } + constexpr uint32_t holly_g2_if_block_internal_write_buffer(uint32_t reg) { return (reg >> 4) & 0x1; } + constexpr uint32_t aica_internal_write_buffer(uint32_t reg) { return (reg >> 0) & 0x1; } + } + + namespace istext { + constexpr uint32_t external_device = 1 << 3; + constexpr uint32_t modem = 1 << 2; + constexpr uint32_t aica = 1 << 1; + constexpr uint32_t gdrom = 1 << 0; + } + +}