diff --git a/aica/aica.hpp b/aica/aica.hpp index 9704c89..463ed85 100644 --- a/aica/aica.hpp +++ b/aica/aica.hpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include "type.hpp" diff --git a/aica/aica_channel.hpp b/aica/aica_channel.hpp index 5b2e4f0..36af3e0 100644 --- a/aica/aica_channel.hpp +++ b/aica/aica_channel.hpp @@ -1,46 +1,28 @@ -#include -#include +#include +#include #include "type.hpp" struct aica_channel { - reg16 reg_0000; - const reg16 _pad0[1]; - reg16 reg_0004; - const reg16 _pad1[1]; - reg16 reg_0008; - const reg16 _pad2[1]; - reg16 reg_000c; - const reg16 _pad3[1]; - reg16 reg_0010; - const reg16 _pad4[1]; - reg16 reg_0014; - const reg16 _pad5[1]; - reg16 reg_0018; - const reg16 _pad6[1]; - reg16 reg_001c; - const reg16 _pad7[1]; - reg16 reg_0020; - const reg16 _pad8[1]; - reg16 reg_0024; - const reg16 _pad9[1]; - reg16 reg_0028; - const reg16 _pad10[1]; - reg16 reg_002c; - const reg16 _pad11[1]; - reg16 reg_0030; - const reg16 _pad12[1]; - reg16 reg_0034; - const reg16 _pad13[1]; - reg16 reg_0038; - const reg16 _pad14[1]; - reg16 reg_003c; - const reg16 _pad15[1]; - reg16 reg_0040; - const reg16 _pad16[1]; - reg16 reg_0044; - const reg16 _pad17[1]; - const reg16 _pad18[28]; + reg32 reg_0000; + reg32 reg_0004; + reg32 reg_0008; + reg32 reg_000c; + reg32 reg_0010; + reg32 reg_0014; + reg32 reg_0018; + reg32 reg_001c; + reg32 reg_0020; + reg32 reg_0024; + reg32 reg_0028; + reg32 reg_002c; + reg32 reg_0030; + reg32 reg_0034; + reg32 reg_0038; + reg32 reg_003c; + reg32 reg_0040; + reg32 reg_0044; + const reg32 _pad0[14]; uint32_t KYONEX() const { diff --git a/aica/aica_common.hpp b/aica/aica_common.hpp index c4a0508..ac38b2a 100644 --- a/aica/aica_common.hpp +++ b/aica/aica_common.hpp @@ -1,62 +1,37 @@ -#include -#include +#include +#include #include "type.hpp" struct aica_common { - reg16 reg_2800; - const reg16 _pad0[1]; - reg16 reg_2804; - const reg16 _pad1[1]; - reg16 reg_2808; - const reg16 _pad2[1]; - reg16 reg_280c; - const reg16 _pad3[1]; - reg16 reg_2810; - const reg16 _pad4[1]; - reg16 reg_2814; - const reg16 _pad5[1]; - const reg16 _pad6[52]; - reg16 reg_2880; - const reg16 _pad7[1]; - reg16 reg_2884; - const reg16 _pad8[1]; - reg16 reg_2888; - const reg16 _pad9[1]; - reg16 reg_288c; - const reg16 _pad10[1]; - reg16 reg_2890; - const reg16 _pad11[1]; - reg16 reg_2894; - const reg16 _pad12[1]; - reg16 reg_2898; - const reg16 _pad13[1]; - reg16 reg_289c; - const reg16 _pad14[1]; - reg16 reg_28a0; - const reg16 _pad15[1]; - reg16 reg_28a4; - const reg16 _pad16[1]; - reg16 reg_28a8; - const reg16 _pad17[1]; - reg16 reg_28ac; - const reg16 _pad18[1]; - reg16 reg_28b0; - const reg16 _pad19[1]; - reg16 reg_28b4; - const reg16 _pad20[1]; - reg16 reg_28b8; - const reg16 _pad21[1]; - reg16 reg_28bc; - const reg16 _pad22[1]; - const reg16 _pad23[416]; - reg16 reg_2c00; - const reg16 _pad24[1]; - const reg16 _pad25[126]; - reg16 reg_2d00; - const reg16 _pad26[1]; - reg16 reg_2d04; - const reg16 _pad27[1]; + reg32 reg_2800; + reg32 reg_2804; + reg32 reg_2808; + reg32 reg_280c; + reg32 reg_2810; + reg32 reg_2814; + const reg32 _pad0[26]; + reg32 reg_2880; + reg32 reg_2884; + reg32 reg_2888; + reg32 reg_288c; + reg32 reg_2890; + reg32 reg_2894; + reg32 reg_2898; + reg32 reg_289c; + reg32 reg_28a0; + reg32 reg_28a4; + reg32 reg_28a8; + reg32 reg_28ac; + reg32 reg_28b0; + reg32 reg_28b4; + reg32 reg_28b8; + reg32 reg_28bc; + const reg32 _pad1[208]; + reg32 reg_2c00; + const reg32 _pad2[63]; + reg32 reg_2d00; + reg32 reg_2d04; uint32_t MONO() const { diff --git a/aica/aica_dsp_out.hpp b/aica/aica_dsp_out.hpp index 77dffa6..f8c6305 100644 --- a/aica/aica_dsp_out.hpp +++ b/aica/aica_dsp_out.hpp @@ -1,11 +1,10 @@ -#include -#include +#include +#include #include "type.hpp" struct aica_dsp_out { - reg16 reg_0000; - const reg16 _pad0[1]; + reg32 reg_0000; uint32_t EFDSL() const { diff --git a/aica/aica_rtc.hpp b/aica/aica_rtc.hpp index 4c69d8b..cf4598a 100644 --- a/aica/aica_rtc.hpp +++ b/aica/aica_rtc.hpp @@ -1,15 +1,12 @@ -#include -#include +#include +#include #include "type.hpp" struct aica_rtc { - reg16 reg_0000; - const reg16 _pad0[1]; - reg16 reg_0004; - const reg16 _pad1[1]; - reg16 reg_0008; - const reg16 _pad2[1]; + reg32 reg_0000; + reg32 reg_0004; + reg32 reg_0008; uint32_t RTC() const { diff --git a/alt.lds b/alt.lds index 89d4c0b..571618e 100644 --- a/alt.lds +++ b/alt.lds @@ -4,59 +4,4 @@ MEMORY p1ram : ORIGIN = 0x8c020000, LENGTH = 0xff0000 p2ram : ORIGIN = 0xac020000, LENGTH = 0xff0000 } -SECTIONS -{ - . = ORIGIN(p2ram); - - .text ALIGN(4) : SUBALIGN(4) - { - KEEP(*(.text.start)) - *(.text.startup.*) - } > p2ram AT>p1ram - - . = ORIGIN(p1ram) + (. - ORIGIN(p2ram)); - - .text ALIGN(4) : SUBALIGN(4) - { - *(.text.*) - *(.text) - } > p1ram - - .data ALIGN(4) : SUBALIGN(4) - { - *(.data) - *(.data.*) - } > p1ram - - .rodata ALIGN(4) : SUBALIGN(4) - { - *(.rodata) - *(.rodata.*) - } > p1ram - - .ctors ALIGN(4) : SUBALIGN(4) - { - KEEP(*(.ctors)) - KEEP(*(.ctors.*)) - } > p1ram - - .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) - { - *(.bss) - *(.bss.*) - *(COMMON) - } > p1ram - - INCLUDE "debug.lds" -} - -__p1ram_start = ORIGIN(p1ram); -__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); - -__bss_link_start = ADDR(.bss); -__bss_link_end = ADDR(.bss) + SIZEOF(.bss); - -__ctors_link_start = ADDR(.ctors); -__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); - -INCLUDE "addresses.lds" +INCLUDE "common.lds" diff --git a/audio.pcm b/audio.pcm new file mode 100644 index 0000000..86972fa Binary files /dev/null and b/audio.pcm differ diff --git a/base.mk b/base.mk new file mode 100644 index 0000000..f28e5a6 --- /dev/null +++ b/base.mk @@ -0,0 +1,57 @@ +DEBUG = -g -gdwarf-4 + +AFLAGS += --fatal-warnings + +CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib +CFLAGS += -Wall -Werror -Wfatal-errors +CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= -Wno-array-bounds + +CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics + +# --print-gc-sections +LDFLAGS += --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error + +DEPFLAGS = -MMD -MP + +CC = $(TARGET)gcc +CXX = $(TARGET)g++ +AS = $(TARGET)as +LD = $(TARGET)ld +OBJCOPY = $(TARGET)objcopy +OBJDUMP = $(TARGET)objdump + +LIBGCC = $(shell $(CC) -print-file-name=libgcc.a) + +define BUILD_BINARY_O + $(OBJCOPY) \ + -I binary $(OBJARCH) \ + --rename-section .data=.data.$(basename $@) \ + $< $@ +endef + +%.bin.o: %.bin + $(BUILD_BINARY_O) + +%.pcm.o: %.pcm + $(BUILD_BINARY_O) + +%.data.o: %.data + $(BUILD_BINARY_O) + +%.o: %.s + $(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@ + +%.o: %.c + $(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ + +%.o: %.cpp + $(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ + +%.elf: + $(LD) $(LDFLAGS) -T $(LDSCRIPT) $^ -o $@ + +%.bin: %.elf + $(OBJCOPY) -O binary $< $@ + du -b $@ + +-include $(shell find -type f -name '*.d') diff --git a/common.lds b/common.lds new file mode 100644 index 0000000..0cdaac2 --- /dev/null +++ b/common.lds @@ -0,0 +1,56 @@ +SECTIONS +{ + . = ORIGIN(p2ram); + + .text ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.start)) + *(.text.startup.*) + } > p2ram AT>p1ram + + . = ORIGIN(p1ram) + (. - ORIGIN(p2ram)); + + .text ALIGN(4) : SUBALIGN(4) + { + *(.text.*) + *(.text) + } > p1ram + + .data ALIGN(4) : SUBALIGN(4) + { + *(.data) + *(.data.*) + } > p1ram + + .rodata ALIGN(4) : SUBALIGN(4) + { + *(.rodata) + *(.rodata.*) + } > p1ram + + .ctors ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + } > p1ram + + .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) + { + *(.bss) + *(.bss.*) + *(COMMON) + } > p1ram + + INCLUDE "debug.lds" +} + +__p1ram_start = ORIGIN(p1ram); +__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); + +__bss_link_start = ADDR(.bss); +__bss_link_end = ADDR(.bss) + SIZEOF(.bss); + +__ctors_link_start = ADDR(.ctors); +__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); + +INCLUDE "addresses.lds" diff --git a/common.mk b/common.mk index 343e6c0..dfb8362 100644 --- a/common.mk +++ b/common.mk @@ -3,39 +3,19 @@ DIR := $(dir $(MAKEFILE_PATH)) LIB ?= . OPT ?= -O0 -DEBUG ?= -g -gdwarf-4 GENERATED ?= AARCH = --isa=sh4 --little -AFLAGS = --fatal-warnings CARCH = -m4-single-only -ml -CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib -CFLAGS += -Wall -Werror -Wfatal-errors -CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= -Wno-array-bounds CFLAGS += -mfsca -funsafe-math-optimizations -ffast-math CFLAGS += -I$(dir $(MAKEFILE_PATH)) -DEPFLAGS = -MMD -E -# --print-gc-sections -LDFLAGS = --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error -CXXFLAGS = -std=c++23 -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics + +CXXFLAGS += -std=c++23 + +OBJARCH = -O elf32-shl -B sh4 TARGET = sh4-none-elf- -CC = $(TARGET)gcc -CXX = $(TARGET)g++ -AS = $(TARGET)as -LD = $(TARGET)ld -OBJCOPY = $(TARGET)objcopy -OBJDUMP = $(TARGET)objdump - -LIBGCC = $(shell $(CC) -print-file-name=libgcc.a) - -define BUILD_BINARY_O - $(OBJCOPY) \ - -I binary -O elf32-shl -B sh4 \ - --rename-section .data=.data.$(basename $@) \ - $< $@ -endef IP_OBJ = \ systemid.o \ @@ -52,54 +32,31 @@ IP_OBJ = \ sg/sg_ini.o \ sg/aip.o +ip.elf: $(IP_OBJ) + $(LD) --orphan-handling=error --print-memory-usage -T $(LIB)/ip.lds $^ -o $@ + START_OBJ = \ start.o \ runtime.o \ sh7091/cache.o -%.bin.o: %.bin - $(BUILD_BINARY_O) +include base.mk %.o: %.obj $(OBJCOPY) -g \ --rename-section IP=.text.$* \ $< $@ -%.o: %.s - $(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@ - -%.c.d: | $(GENERATED) - $(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -c $(basename $@) -MF $@ -o /dev/null - -%.o: %.c %.c.d - $(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) -c $< -o $@ - -%.cpp.d: | $(GENERATED) - $(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -c $(basename $@) -MF $@ -o /dev/null - -%.o: %.cpp %.cpp.d - $(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) -c $< -o $@ - -%.elf: - $(LD) $(LDFLAGS) -T $(LDSCRIPT) $^ -o $@ - -%.bin: %.elf - $(OBJCOPY) -O binary $< $@ - du -b $@ - -ip.elf: $(IP_OBJ) - $(LD) --orphan-handling=error --print-memory-usage -T $(LIB)/ip.lds $^ -o $@ - -audio.pcm: +sine.pcm: common.mk sox \ --rate 44100 \ --encoding signed-integer \ --bits 16 \ - --channels 2 \ - --endian little \ + --channels 1 \ + --endian big \ --null \ $@.raw \ - synth 1 sin 440 vol -10dB + synth 100s sin 700 vol -10dB mv $@.raw $@ %.scramble: %.bin @@ -127,62 +84,7 @@ audio.pcm: %.cdi: %.iso ./cdi4dc $< $@ >/dev/null -%.data.o: %.data - $(BUILD_BINARY_O) - -%.csv: %.ods - libreoffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":44,34,76,,,,true --outdir $(dir $@) $< - -maple/maple_bus_commands.hpp: regs/maple_bus_commands.csv regs/gen/maple_bus_commands.py - python regs/gen/maple_bus_commands.py $< > $@ - -maple/maple_bus_bits.hpp: regs/maple_bus_bits.csv regs/gen/core_bits.py - python regs/gen/core_bits.py $< > $@ - -holly/core_bits.hpp: regs/core_bits.csv regs/gen/core_bits.py - python regs/gen/core_bits.py $< > $@ - -holly/holly.hpp: regs/holly.csv regs/gen/holly.py - python regs/gen/holly.py $< > $@ - -holly/ta_global_parameter.hpp: regs/global_parameter_format.csv regs/gen/ta_parameter_format.py regs/gen/generic_sparse_struct.py - python regs/gen/ta_parameter_format.py $< ta_global_parameter > $@ - -holly/ta_vertex_parameter.hpp: regs/vertex_parameter_format.csv regs/gen/ta_parameter_format.py regs/gen/generic_sparse_struct.py - python regs/gen/ta_parameter_format.py $< ta_vertex_parameter > $@ - -holly/object_list_data.hpp: regs/object_list.csv regs/gen/core_bits.py - python regs/gen/core_bits.py $< object_list_data > $@ - -sh7091/sh7091.hpp: regs/sh7091.csv regs/gen/sh7091.py - python regs/gen/sh7091.py $< > $@ - -sh7091/sh7091_bits.hpp: regs/sh7091_bits.csv regs/gen/core_bits.py - python regs/gen/core_bits.py $< > $@ - -gdrom/gdrom.hpp: regs/gdrom.csv regs/gen/gdrom.py - python regs/gen/gdrom.py $< gdrom > $@ - -gdrom/gdrom_bits.hpp: regs/gdrom_bits.csv regs/gen/core_bits.py - python regs/gen/core_bits.py $< gdrom > $@ - -gdrom/command_packet_format.hpp: regs/gdrom_command_packet_format.csv regs/gen/gdrom_command_packet_format.py regs/gen/generic_sparse_struct.py - python regs/gen/gdrom_command_packet_format.py $< gdrom_command_packet_format > $@ - -aica/aica_channel.hpp: regs/aica_channel_data.csv regs/gen/aica.py - python regs/gen/aica.py $< aica_channel 0x80 > $@ - -aica/aica_common.hpp: regs/aica_common_data.csv regs/gen/aica.py - python regs/gen/aica.py $< aica_common > $@ - -aica/aica_rtc.hpp: regs/aica_rtc_data.csv regs/gen/aica.py - python regs/gen/aica.py $< aica_rtc > $@ - -aica/aica_dsp_out.hpp: regs/aica_dsp_out_data.csv regs/gen/aica.py - python regs/gen/aica.py $< aica_dsp_out > $@ - -iso9660/%.hpp: iso9660/%.csv iso9660/byte_position.py - python iso9660/byte_position.py $< > $@ +include headers.mk clean: find -P \ diff --git a/example/aica.cpp b/example/aica.cpp new file mode 100644 index 0000000..8df3058 --- /dev/null +++ b/example/aica.cpp @@ -0,0 +1,62 @@ +#include "memorymap.hpp" +#include "aica/aica.hpp" +#include "sh7091/serial.hpp" +#include "systembus.hpp" +#include "systembus_bits.hpp" + +extern void * _binary_start __asm("_binary_example_arm_main_bin_start"); +extern void * _binary_size __asm("_binary_example_arm_main_bin_size"); + +void wait() +{ + while (ffst::aica_internal_write_buffer(system.FFST)); +} + +void wait_read() +{ + uint32_t ffst = ~0; + while ( ffst::holly_cpu_if_block_internal_write_buffer(ffst) + | ffst::holly_g2_if_block_internal_write_buffer(ffst) + | ffst::aica_internal_write_buffer(ffst)) { + ffst = system.FFST; + }; +} + +void main() +{ + const uint32_t * binary = reinterpret_cast(&_binary_start); + const uint32_t binary_size = reinterpret_cast(&_binary_size); + + wait(); aica.common.reg_2c00 = 1; + wait(); aica.common.reg_2880 = 0; + for (uint32_t i = 0; i < binary_size / 4; i++) { + // copy + aica_wave_memory[i] = binary[i]; + if (i % 8 == 7) wait(); + } + wait(); aica.common.reg_2c00 = 0; + + serial::integer(aica_wave_memory[0]); + + wait(); aica.common.MSLC(0); + serial::string("mrwinh: "); + wait_read(); + serial::integer(aica.common.MRWINH()); + while (1) { + wait_read(); + serial::string("sgc: "); + serial::integer(aica.common.SGC(), ' '); + serial::string("; ca: "); + serial::integer(aica.common.CA(), ' '); + serial::string("; eg: "); + serial::integer(aica.common.EG(), ' '); + serial::string("; lp: "); + serial::integer(aica.common.LP(), ' '); + serial::character('\n'); + for (int i = 0; i < 10000000; i++) { + asm volatile ("nop"); + } + } + + while (1); +} diff --git a/example/arm/Makefile b/example/arm/Makefile new file mode 100644 index 0000000..d677f4d --- /dev/null +++ b/example/arm/Makefile @@ -0,0 +1,22 @@ +MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +DIR := $(dir $(MAKEFILE_PATH)) + +LIB ?= . +OPT ?= -Og +GENERATED ?= + +AARCH = -march=armv4 -mlittle-endian + +CARCH = -mno-thumb-interwork -march=armv4 -mtune=arm7di -mlittle-endian +CFLAGS += -I$(dir $(MAKEFILE_PATH))/../.. + +CXXFLAGS += -std=c++2a + +OBJARCH = -O elf32-littlearm -B armv4 + +TARGET = arm-none-eabi- + +include base.mk + +main.elf: LDSCRIPT = main.lds +main.elf: start.o main.o audio.pcm.o diff --git a/example/arm/addresses.lds b/example/arm/addresses.lds new file mode 100644 index 0000000..bd61339 --- /dev/null +++ b/example/arm/addresses.lds @@ -0,0 +1,2 @@ +dram = 0x00000000; +aica = 0x00800000; diff --git a/example/arm/arm.lds b/example/arm/arm.lds new file mode 100644 index 0000000..d72128e --- /dev/null +++ b/example/arm/arm.lds @@ -0,0 +1,8 @@ + .glue_7 0 : { *(.glue_7) } + .glue_7t 0 : { *(.glue_7t) } + .vfp11_veneer 0 : { *(.vfp11_veneer) } + .v4_bx 0 : { *(.v4_bx) } + .ARM.attributes 0 : { *(.ARM.attributes) } + .iplt 0 : { *(.iplt) } + .rel.iplt 0 : { *(.rel.iplt) } + .igot.plt 0 : { *(.igot.plt) } diff --git a/example/arm/audio.pcm b/example/arm/audio.pcm new file mode 120000 index 0000000..5295326 --- /dev/null +++ b/example/arm/audio.pcm @@ -0,0 +1 @@ +../../audio.pcm \ No newline at end of file diff --git a/example/arm/base.mk b/example/arm/base.mk new file mode 120000 index 0000000..4d2c176 --- /dev/null +++ b/example/arm/base.mk @@ -0,0 +1 @@ +../../base.mk \ No newline at end of file diff --git a/example/arm/main.cpp b/example/arm/main.cpp new file mode 100644 index 0000000..7a0fbab --- /dev/null +++ b/example/arm/main.cpp @@ -0,0 +1,57 @@ +#include "aica/aica.hpp" + +extern void * _sine_start __asm("_binary_audio_pcm_start"); + +extern volatile uint32_t * dram __asm("dram"); + +extern "C" +void main() +{ + const uint32_t sine_addr = reinterpret_cast(&_sine_start); + + volatile uint32_t * slot = reinterpret_cast(0x00800000); + for (uint32_t i = 0; i < (sizeof (struct aica_channel)) * 64 / 4; i++) { + slot[i] = 0; + } + + volatile uint32_t * dsp = reinterpret_cast(0x00803000); + for (int i = 0; i < 0xb00 / 4; i++) { + dsp[i] = 0; + } + + aica.channel[0].KYONB(1); + aica.channel[0].LPCTL(1); + aica.channel[0].PCMS(0); + aica.channel[0].SA(sine_addr); + aica.channel[0].LSA(0); + aica.channel[0].LEA(128); + aica.channel[0].D2R(0x0); + aica.channel[0].D1R(0x0); + aica.channel[0].RR(0x0); + aica.channel[0].AR(0x1f); + + aica.channel[0].OCT(0); + aica.channel[0].FNS(0); + aica.channel[0].DISDL(0xf); + aica.channel[0].DIPAN(0x0); + + aica.channel[0].Q(0b00100); + aica.channel[0].TL(0); + aica.channel[0].LPOFF(1); + + aica.common.MVOL(0xf); + + uint32_t segment = 0; + aica.common.TACTL(7); // increment once every 128 samples + aica.common.TIMA(0); + aica.channel[0].KYONEX(1); + + while (1) { + if (aica.common.TIMA() >= 1) { + aica.common.TIMA(0); + segment += 1; + if (segment >= 3440) segment = 0; + aica.channel[0].SA(sine_addr + (128 * 2) * segment); + } + } +} diff --git a/example/arm/main.lds b/example/arm/main.lds new file mode 100644 index 0000000..b825663 --- /dev/null +++ b/example/arm/main.lds @@ -0,0 +1,56 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +MEMORY +{ + ram : ORIGIN = 0x00000000, LENGTH = 0x200000 +} +SECTIONS +{ + . = ORIGIN(ram); + + .text ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.start)) + *(.text.startup.*) + *(.text.*) + *(.text) + } > ram + + .data ALIGN(4) : SUBALIGN(4) + { + *(.data) + *(.data.*) + } > ram + + .rodata ALIGN(4) : SUBALIGN(4) + { + *(.rodata) + *(.rodata.*) + } > ram + + .ctors ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + } > ram + + .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) + { + *(.bss) + *(.bss.*) + *(COMMON) + } > ram + + INCLUDE "../../debug.lds" + INCLUDE "arm.lds" +} + +__ram_start = ORIGIN(ram); +__ram_end = ORIGIN(ram) + LENGTH(ram); + +__bss_link_start = ADDR(.bss); +__bss_link_end = ADDR(.bss) + SIZEOF(.bss); + +__ctors_link_start = ADDR(.ctors); +__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); + +INCLUDE "addresses.lds" diff --git a/example/arm/start.s b/example/arm/start.s new file mode 100644 index 0000000..e4297ed --- /dev/null +++ b/example/arm/start.s @@ -0,0 +1,29 @@ + .macro FILL_ZERO_32_BYTE_ALIGNED + cmp r1, r10 + beq _fill_break.\@ + .irp i, 2, 3, 4, 5, 6, 7, 8, 9 + mov r\i, #0 + .endr +_fill_loop.\@: + stmia r1!, {r2 - r9} + cmp r1, r10 + blt _fill_loop.\@ +_fill_break.\@: + .endm + + .section .text.start + .global _start +_start: + b _reset +_reset: +_link_bss: + /* + ldr r1, =__bss_link_start + ldr r10, =__bss_link_end + FILL_ZERO_32_BYTE_ALIGNED + */ + + /* set stack pointer */ + ldr sp,=__ram_end + + bl main diff --git a/example/example.mk b/example/example.mk index 847933c..37cd118 100644 --- a/example/example.mk +++ b/example/example.mk @@ -364,3 +364,11 @@ GDROM_ISO9660_OBJ = \ example/gdrom_iso9660.elf: LDSCRIPT = $(LIB)/alt.lds example/gdrom_iso9660.elf: $(START_OBJ) $(GDROM_ISO9660_OBJ) + +AICA_OBJ = \ + example/aica.o \ + sh7091/serial.o \ + example/arm/main.bin.o \ + +example/aica.elf: LDSCRIPT = $(LIB)/alt.lds +example/aica.elf: $(START_OBJ) $(AICA_OBJ) diff --git a/example/interrupt.cpp b/example/interrupt.cpp new file mode 100644 index 0000000..29c9e0f --- /dev/null +++ b/example/interrupt.cpp @@ -0,0 +1,17 @@ +#include + +#include "serial.hpp" + +#include "sh7095.hpp" +#include "sh7095_bits.hpp" + +void main() +{ + uint32_t vbr; + + asm ("stc vbr,%0" : "=r" (vbr)); + + serial::integer(vbr); + + while (1); +} diff --git a/headers.mk b/headers.mk new file mode 100644 index 0000000..ec34f63 --- /dev/null +++ b/headers.mk @@ -0,0 +1,70 @@ +%.csv: %.ods + libreoffice --headless --convert-to csv:"Text - txt - csv (StarCalc)":44,34,76,,,,true --outdir $(dir $@) $< + +# SH7091 + +sh7091/sh7091.hpp: regs/sh7091.csv regs/gen/sh7091.py + python regs/gen/sh7091.py $< > $@ + +sh7091/sh7091_bits.hpp: regs/sh7091_bits.csv regs/gen/core_bits.py + python regs/gen/core_bits.py $< > $@ + +# SYSTEMBUS + +systembus_bits.hpp: regs/systembus_bits.csv regs/gen/core_bits.py + python regs/gen/core_bits.py $< > $@ + +# HOLLY + +holly/core_bits.hpp: regs/core_bits.csv regs/gen/core_bits.py + python regs/gen/core_bits.py $< > $@ + +holly/holly.hpp: regs/holly.csv regs/gen/holly.py + python regs/gen/holly.py $< > $@ + +holly/ta_global_parameter.hpp: regs/global_parameter_format.csv regs/gen/ta_parameter_format.py regs/gen/generic_sparse_struct.py + python regs/gen/ta_parameter_format.py $< ta_global_parameter > $@ + +holly/ta_vertex_parameter.hpp: regs/vertex_parameter_format.csv regs/gen/ta_parameter_format.py regs/gen/generic_sparse_struct.py + python regs/gen/ta_parameter_format.py $< ta_vertex_parameter > $@ + +holly/object_list_data.hpp: regs/object_list.csv regs/gen/core_bits.py + python regs/gen/core_bits.py $< object_list_data > $@ + +# MAPLE + +maple/maple_bus_commands.hpp: regs/maple_bus_commands.csv regs/gen/maple_bus_commands.py + python regs/gen/maple_bus_commands.py $< > $@ + +maple/maple_bus_bits.hpp: regs/maple_bus_bits.csv regs/gen/core_bits.py + python regs/gen/core_bits.py $< > $@ + +# AICA + +aica/aica_channel.hpp: regs/aica_channel_data.csv regs/gen/aica.py + python regs/gen/aica.py $< aica_channel 0x80 > $@ + +aica/aica_common.hpp: regs/aica_common_data.csv regs/gen/aica.py + python regs/gen/aica.py $< aica_common > $@ + +aica/aica_rtc.hpp: regs/aica_rtc_data.csv regs/gen/aica.py + python regs/gen/aica.py $< aica_rtc > $@ + +aica/aica_dsp_out.hpp: regs/aica_dsp_out_data.csv regs/gen/aica.py + python regs/gen/aica.py $< aica_dsp_out > $@ + +# GDROM + +gdrom/gdrom.hpp: regs/gdrom.csv regs/gen/gdrom.py + python regs/gen/gdrom.py $< gdrom > $@ + +gdrom/gdrom_bits.hpp: regs/gdrom_bits.csv regs/gen/core_bits.py + python regs/gen/core_bits.py $< gdrom > $@ + +gdrom/command_packet_format.hpp: regs/gdrom_command_packet_format.csv regs/gen/gdrom_command_packet_format.py regs/gen/generic_sparse_struct.py + python regs/gen/gdrom_command_packet_format.py $< gdrom_command_packet_format > $@ + +# ISO9660 + +iso9660/%.hpp: iso9660/%.csv iso9660/byte_position.py + python iso9660/byte_position.py $< > $@ diff --git a/main.lds b/main.lds index 3a8d78a..70cfe91 100644 --- a/main.lds +++ b/main.lds @@ -4,61 +4,4 @@ MEMORY p1ram : ORIGIN = 0x8c010000, LENGTH = 0xff0000 p2ram : ORIGIN = 0xac010000, LENGTH = 0xff0000 } -SECTIONS -{ - . = ORIGIN(p2ram); - - .text ALIGN(4) : SUBALIGN(4) - { - KEEP(*(.text.start)) - *(.text.startup.*) - } > p2ram AT>p1ram - - . = ORIGIN(p1ram) + (. - ORIGIN(p2ram)); - - .text ALIGN(4) : SUBALIGN(4) - { - KEEP(*(.text.start)) - *(.text.startup.*) - *(.text.*) - *(.text) - } > p1ram - - .data ALIGN(4) : SUBALIGN(4) - { - *(.data) - *(.data.*) - } > p1ram - - .rodata ALIGN(4) : SUBALIGN(4) - { - *(.rodata) - *(.rodata.*) - } > p1ram - - .ctors ALIGN(4) : SUBALIGN(4) - { - KEEP(*(.ctors)) - KEEP(*(.ctors.*)) - } > p1ram - - .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) - { - *(.bss) - *(.bss.*) - *(COMMON) - } > p1ram - - INCLUDE "debug.lds" -} - -__p1ram_start = ORIGIN(p1ram); -__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); - -__bss_link_start = ADDR(.bss); -__bss_link_end = ADDR(.bss) + SIZEOF(.bss); - -__ctors_link_start = ADDR(.ctors); -__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); - -INCLUDE "addresses.lds" +INCLUDE "common.lds" diff --git a/regs/gen/aica.py b/regs/gen/aica.py index 7c8e1b8..f9ffb84 100644 --- a/regs/gen/aica.py +++ b/regs/gen/aica.py @@ -142,20 +142,20 @@ def part_get_expression(part): arg_mask = mask_from_bits(part.argument_bits) return f"(static_cast(({format_reg(part.address)} >> {reg_end}) & {hex(arg_mask)}) << {arg_end})" -def part_set_statement(addresses_dict, c_type_size, part): +def part_set_statement(addresses_dict, c_type_real_size, part): _, reg_end = part.register_bits _, arg_end = part.argument_bits arg_mask = mask_from_bits(part.argument_bits) assignment = f"{format_reg(part.address)} = (((v >> {arg_end}) & {hex(arg_mask)}) << {reg_end})" if len(addresses_dict[part.address]) > 1: reg_mask = mask_from_bits(part.register_bits) << reg_end - inverse_mask = (~reg_mask) & ((2 ** (c_type_size * 8)) - 1) + inverse_mask = (~reg_mask) & ((2 ** (c_type_real_size * 8)) - 1) assignment += f" | ({format_reg(part.address)} & {hex(inverse_mask)});" else: assignment += ";" return assignment -def render_struct_accessors(addresses_dict, c_type, c_type_size, registers): +def render_struct_accessors(addresses_dict, c_type, c_type_real_size, registers): for register in registers: yield f"uint32_t {register.name}() const" yield "{" @@ -165,22 +165,22 @@ def render_struct_accessors(addresses_dict, c_type, c_type_size, registers): yield f"void {register.name}(const uint32_t v)" yield "{" for part in register.parts: - yield part_set_statement(addresses_dict, c_type_size, part) + yield part_set_statement(addresses_dict, c_type_real_size, part) yield "}" yield "" -def render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, registers): +def render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, c_type_real_size, registers): yield f"struct {struct_name} {{" yield from render_struct_fields(struct_size, addresses, address_increment, c_type, c_type_size) yield "" addresses_dict = dict(addresses) - yield from render_struct_accessors(addresses_dict, c_type, c_type_size, registers) + yield from render_struct_accessors(addresses_dict, c_type, c_type_real_size, registers) yield "};" yield from render_struct_static_assertions(struct_name, struct_size, addresses, address_increment) def header(): - yield "#include " - yield "#include " + yield '#include ' + yield '#include ' yield "" yield '#include "type.hpp"' yield "" @@ -191,10 +191,11 @@ if __name__ == "__main__": struct_size = int(sys.argv[3], 16) if len(sys.argv) > 3 else None rows = read_input(input_file) address_increment = 4 - c_type = "reg16" - c_type_size = 2 + c_type = "reg32" + c_type_size = 4 + c_type_real_size = 2 addresses, registers = group_parts(rows, address_increment) render, out = renderer() render(header()) - render(render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, registers)) + render(render_struct(struct_name, struct_size, addresses, address_increment, c_type, c_type_size, c_type_real_size, registers)) sys.stdout.write(out.getvalue()) diff --git a/regs/systembus_bits.csv b/regs/systembus_bits.csv new file mode 100644 index 0000000..51ecfc0 --- /dev/null +++ b/regs/systembus_bits.csv @@ -0,0 +1,62 @@ +"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",,, +"ISTNRM",,"20","end_of_dma_sort_dma",,, +"ISTNRM",,"19","end_of_dma_ch2_dma",,, +"ISTNRM",,"18","end_of_dma_dev_dma",,, +"ISTNRM",,"17","end_of_dma_ext_dma2",,, +"ISTNRM",,"16","end_of_dma_ext_dma1",,, +"ISTNRM",,"15","end_of_dma_aica_dma",,, +"ISTNRM",,"14","end_of_dma_gd_dma",,, +"ISTNRM",,"13","maple_v_blank_over_interrupt",,, +"ISTNRM",,"12","end_of_dma_maple_dma",,, +"ISTNRM",,"11","end_of_dma_pvr_dma",,, +"ISTNRM",,"10","end_of_transferring_translucent_modifier_volume_list",,, +"ISTNRM",,"9","end_of_transferring_translucent_list",,, +"ISTNRM",,"8","end_of_transferring_opaque_modifier_volume_list",,, +"ISTNRM",,"7","end_of_transferring_opaque_list",,, +"ISTNRM",,"6","end_of_transferring_yuv",,, +"ISTNRM",,"5","h_blank_in_interrupt",,, +"ISTNRM",,"4","v_blank_out_interrupt",,, +"ISTNRM",,"3","v_blank_in_interrupt",,, +"ISTNRM",,"2","end_of_render_tsp",,, +"ISTNRM",,"1","end_of_render_isp",,, +"ISTNRM",,"0","end_of_render_video",,, +,,,,,, +"ISTERR",,"31","sh4__if_access_inhibited_area",,, +"ISTERR",,"28","ddt__if_sort_dma_command_error",,, +"ISTERR",,"27","g2__time_out_in_cpu_access",,, +"ISTERR",,"26","g2__dev_dma_time_out",,, +"ISTERR",,"25","g2__ext_dma2_time_out",,, +"ISTERR",,"24","g2__ext_dma1_time_out",,, +"ISTERR",,"23","g2__aica_dma_time_out",,, +"ISTERR",,"22","g2__dev_dma_over_run",,, +"ISTERR",,"21","g2__ext_dma2_over_run",,, +"ISTERR",,"20","g2__ext_dma1_over_run",,, +"ISTERR",,"19","g2__aica_dma_over_run",,, +"ISTERR",,"18","g2__dev_dma_illegal_address_set",,, +"ISTERR",,"17","g2__ext_dma2_illegal_address_set",,, +"ISTERR",,"16","g2__ext_dma1_illegal_address_set",,, +"ISTERR",,"15","g2__aica_dma_illegal_address_set",,, +"ISTERR",,"14","g1__rom_flash_access_at_gd_dma",,, +"ISTERR",,"13","g1__gd_dma_over_run",,, +"ISTERR",,"12","g1__illegal_address_set",,, +"ISTERR",,"11","maple__illegal_command",,, +"ISTERR",,"10","maple__write_fifo_over_flow",,, +"ISTERR",,"9","maple__dma_over_run",,, +"ISTERR",,"8","maple__illegal_address_set",,, +"ISTERR",,"7","pvrif__dma_over_run",,, +"ISTERR",,"6","pvrif__illegal_address_set",,, +"ISTERR",,"5","ta__fifo_overflow",,, +"ISTERR",,"4","ta__illegal_parameter",,, +"ISTERR",,"3","ta__object_list_pointer_overflow",,, +"ISTERR",,"2","ta__isp_tsp_parameter_overflow",,, +"ISTERR",,"1","render__hazard_processing_of_strip_buffer",,, +"ISTERR",,"0","render__isp_out_of_cache",,, +,,,,,, +"FFST",,"5","holly_cpu_if_block_internal_write_buffer",,, +"FFST",,"4","holly_g2_if_block_internal_write_buffer",,, +"FFST",,"0","aica_internal_write_buffer",,, diff --git a/regs/systembus_bits.ods b/regs/systembus_bits.ods new file mode 100644 index 0000000..61986b3 Binary files /dev/null and b/regs/systembus_bits.ods differ diff --git a/sh7091/sh7091.hpp b/sh7091/sh7091.hpp index 6119f15..4807594 100644 --- a/sh7091/sh7091.hpp +++ b/sh7091/sh7091.hpp @@ -4,23 +4,23 @@ #include "type.hpp" 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 */ + 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 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 */ + 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 */ + 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); @@ -39,19 +39,19 @@ static_assert((offsetof (struct ccn_reg, QACR0)) == 0x38); static_assert((offsetof (struct ccn_reg, QACR1)) == 0x3c); struct ubc_reg { - reg32 BARA; /* Break address register A */ - reg8 BAMRA; /* Break address mask register A */ + reg32 BARA; /* Break address register A */ + reg8 BAMRA; /* Break address mask register A */ reg8 _pad0[3]; - reg16 BBRA; /* Break bus cycle register A */ + reg16 BBRA; /* Break bus cycle register A */ reg8 _pad1[2]; - reg32 BARB; /* Break address register B */ - reg8 BAMRB; /* Break address mask register B */ + reg32 BARB; /* Break address register B */ + reg8 BAMRB; /* Break address mask register B */ reg8 _pad2[3]; - reg16 BBRB; /* Break bus cycle register B */ + 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 */ + 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); @@ -65,34 +65,34 @@ static_assert((offsetof (struct ubc_reg, BDMRB)) == 0x1c); static_assert((offsetof (struct ubc_reg, BRCR)) == 0x20); struct bsc_reg { - reg32 BCR1; /* Bus control register 1 */ - reg16 BCR2; /* Bus control register 2 */ + 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 */ + 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 */ + reg16 RTCSR; /* Refresh timer control/status register */ reg8 _pad2[2]; - reg16 RTCNT; /* Refresh timer counter */ + reg16 RTCNT; /* Refresh timer counter */ reg8 _pad3[2]; - reg16 RTCOR; /* Refresh timer constant counter */ + reg16 RTCOR; /* Refresh timer constant counter */ reg8 _pad4[2]; - reg16 RFCR; /* Refresh count register */ + reg16 RFCR; /* Refresh count register */ reg8 _pad5[2]; - reg32 PCTRA; /* Port control register A */ - reg16 PDTRA; /* Port data register A */ + 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 */ + reg32 PCTRB; /* Port control register B */ + reg16 PDTRB; /* Port data register B */ reg8 _pad7[2]; - reg16 GPIOIC; /* GPIO interrupt control register */ + reg16 GPIOIC; /* GPIO interrupt control register */ reg8 _pad8[1048502]; - reg32 SDMR2[16384]; /* Synchronous DRAM mode registers */ + reg32 SDMR2[16384]; /* Synchronous DRAM mode registers */ reg8 _pad9[196608]; - reg32 SDMR3[16384]; /* Synchronous DRAM mode registers */ + reg32 SDMR3[16384]; /* Synchronous DRAM mode registers */ }; static_assert((offsetof (struct bsc_reg, BCR1)) == 0x0); @@ -115,23 +115,23 @@ static_assert((offsetof (struct bsc_reg, SDMR2)) == 0x100000); static_assert((offsetof (struct bsc_reg, SDMR3)) == 0x140000); 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 */ + 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); @@ -153,15 +153,15 @@ static_assert((offsetof (struct dmac_reg, CHCR3)) == 0x3c); static_assert((offsetof (struct dmac_reg, DMAOR)) == 0x40); struct cpg_reg { - reg16 FRQCR; /* Frequency control register */ + reg16 FRQCR; /* Frequency control register */ reg8 _pad0[2]; - reg8 STBCR; /* Standby control register */ + reg8 STBCR; /* Standby control register */ reg8 _pad1[3]; - reg16 WTCNT; /* Watchdog timer counter */ + reg16 WTCNT; /* Watchdog timer counter */ reg8 _pad2[2]; - reg16 WTCSR; /* Watchdog timer control/status register */ + reg16 WTCSR; /* Watchdog timer control/status register */ reg8 _pad3[2]; - reg8 STBCR2; /* Standby control register 2 */ + reg8 STBCR2; /* Standby control register 2 */ }; static_assert((offsetof (struct cpg_reg, FRQCR)) == 0x0); @@ -171,37 +171,37 @@ static_assert((offsetof (struct cpg_reg, WTCSR)) == 0xc); static_assert((offsetof (struct cpg_reg, STBCR2)) == 0x10); struct rtc_reg { - reg8 R64CNT; /* 64 Hz counter */ + reg8 R64CNT; /* 64 Hz counter */ reg8 _pad0[3]; - reg8 RSECCNT; /* Second counter */ + reg8 RSECCNT; /* Second counter */ reg8 _pad1[3]; - reg8 RMINCNT; /* Minute counter */ + reg8 RMINCNT; /* Minute counter */ reg8 _pad2[3]; - reg8 RHRCNT; /* Hour counter */ + reg8 RHRCNT; /* Hour counter */ reg8 _pad3[3]; - reg8 RWKCNT; /* Day-of-week counter */ + reg8 RWKCNT; /* Day-of-week counter */ reg8 _pad4[3]; - reg8 RDAYCNT; /* Day counter */ + reg8 RDAYCNT; /* Day counter */ reg8 _pad5[3]; - reg8 RMONCNT; /* Month counter */ + reg8 RMONCNT; /* Month counter */ reg8 _pad6[3]; - reg16 RYRCNT; /* Year counter */ + reg16 RYRCNT; /* Year counter */ reg8 _pad7[2]; - reg8 RSECAR; /* Second alarm register */ + reg8 RSECAR; /* Second alarm register */ reg8 _pad8[3]; - reg8 RMINAR; /* Minute alarm register */ + reg8 RMINAR; /* Minute alarm register */ reg8 _pad9[3]; - reg8 RHRAR; /* Hour alarm register */ + reg8 RHRAR; /* Hour alarm register */ reg8 _pad10[3]; - reg8 RWKAR; /* Day-of-week alarm register */ + reg8 RWKAR; /* Day-of-week alarm register */ reg8 _pad11[3]; - reg8 RDAYAR; /* Day alarm register */ + reg8 RDAYAR; /* Day alarm register */ reg8 _pad12[3]; - reg8 RMONAR; /* Month alarm register */ + reg8 RMONAR; /* Month alarm register */ reg8 _pad13[3]; - reg8 RCR1; /* RTC control register 1 */ + reg8 RCR1; /* RTC control register 1 */ reg8 _pad14[3]; - reg8 RCR2; /* RTC control register 2 */ + reg8 RCR2; /* RTC control register 2 */ }; static_assert((offsetof (struct rtc_reg, R64CNT)) == 0x0); @@ -222,13 +222,13 @@ static_assert((offsetof (struct rtc_reg, RCR1)) == 0x38); static_assert((offsetof (struct rtc_reg, RCR2)) == 0x3c); struct intc_reg { - reg16 ICR; /* Interrupt control register */ + reg16 ICR; /* Interrupt control register */ reg8 _pad0[2]; - reg16 IPRA; /* Interrupt priority register A */ + reg16 IPRA; /* Interrupt priority register A */ reg8 _pad1[2]; - reg16 IPRB; /* Interrupt priority register B */ + reg16 IPRB; /* Interrupt priority register B */ reg8 _pad2[2]; - reg16 IPRC; /* Interrupt priority register C */ + reg16 IPRC; /* Interrupt priority register C */ }; static_assert((offsetof (struct intc_reg, ICR)) == 0x0); @@ -237,23 +237,23 @@ 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 TOCR; /* Timer output control register */ reg8 _pad0[3]; - reg8 TSTR; /* Timer start register */ + 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 */ + 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 */ + 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 */ + 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 */ + reg32 TCPR2; /* Timer input capture register 2 */ }; static_assert((offsetof (struct tmu_reg, TOCR)) == 0x0); @@ -270,21 +270,21 @@ 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 SCSMR1; /* Serial mode register 1 */ reg8 _pad0[3]; - reg8 SCBRR1; /* Bit rate register 1 */ + reg8 SCBRR1; /* Bit rate register 1 */ reg8 _pad1[3]; - reg8 SCSCR1; /* Serial control register 1 */ + reg8 SCSCR1; /* Serial control register 1 */ reg8 _pad2[3]; - reg8 SCTDR1; /* Transmit data register 1 */ + reg8 SCTDR1; /* Transmit data register 1 */ reg8 _pad3[3]; - reg8 SCSSR1; /* Serial status register 1 */ + reg8 SCSSR1; /* Serial status register 1 */ reg8 _pad4[3]; - reg8 SCRDR1; /* Receive data register 1 */ + reg8 SCRDR1; /* Receive data register 1 */ reg8 _pad5[3]; - reg8 SCSCMR1; /* Smart card mode register 1 */ + reg8 SCSCMR1; /* Smart card mode register 1 */ reg8 _pad6[3]; - reg8 SCSPTR1; /* Serial port register */ + reg8 SCSPTR1; /* Serial port register */ }; static_assert((offsetof (struct sci_reg, SCSMR1)) == 0x0); @@ -297,25 +297,25 @@ 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 */ + reg16 SCSMR2; /* Serial mode register 2 */ reg8 _pad0[2]; - reg8 SCBRR2; /* Bit rate register 2 */ + reg8 SCBRR2; /* Bit rate register 2 */ reg8 _pad1[3]; - reg16 SCSCR2; /* Serial control register 2 */ + reg16 SCSCR2; /* Serial control register 2 */ reg8 _pad2[2]; - reg8 SCFTDR2; /* Transmit FIFO data register 2 */ + reg8 SCFTDR2; /* Transmit FIFO data register 2 */ reg8 _pad3[3]; - reg16 SCFSR2; /* Serial status register 2 */ + reg16 SCFSR2; /* Serial status register 2 */ reg8 _pad4[2]; - reg8 SCFRDR2; /* Receive FIFO data register 2 */ + reg8 SCFRDR2; /* Receive FIFO data register 2 */ reg8 _pad5[3]; - reg16 SCFCR2; /* FIFO control register */ + reg16 SCFCR2; /* FIFO control register */ reg8 _pad6[2]; - reg16 SCFDR2; /* FIFO data count register */ + reg16 SCFDR2; /* FIFO data count register */ reg8 _pad7[2]; - reg16 SCSPTR2; /* Serial port register 2 */ + reg16 SCSPTR2; /* Serial port register 2 */ reg8 _pad8[2]; - reg16 SCLSR2; /* Line status register 2 */ + reg16 SCLSR2; /* Line status register 2 */ }; static_assert((offsetof (struct scif_reg, SCSMR2)) == 0x0); @@ -330,9 +330,9 @@ static_assert((offsetof (struct scif_reg, SCSPTR2)) == 0x20); static_assert((offsetof (struct scif_reg, SCLSR2)) == 0x24); struct udi_reg { - reg16 SDIR; /* Instruction register */ + reg16 SDIR; /* Instruction register */ reg8 _pad0[6]; - reg32 SDDR; /* Data register */ + reg32 SDDR; /* Data register */ }; static_assert((offsetof (struct udi_reg, SDIR)) == 0x0); diff --git a/systembus_bits.hpp b/systembus_bits.hpp index 8d42927..f458bdf 100644 --- a/systembus_bits.hpp +++ b/systembus_bits.hpp @@ -1,59 +1,80 @@ -#define C2DST__STATUS (1 << 0) +#pragma once -#define CD2LEN__LENGTH(n) (((n) & 0xffffe0) << 0) +#include -#define C2DSTAT__ADDRESS(n) ((((n) & 0x13ffffe0) | 0x10000000) << 0) +namespace c2dstat { + constexpr uint32_t texture_memory_start_address(uint32_t num) { return (num & 0x13ffffe0) << 0; } +} -#define ISTNRM__END_OF_TRANSFERRING_PUNCH_THROUGH_LIST (1 << 21) -#define ISTNRM__END_OF_DMA_SORT_DMA (1 << 20) -#define ISTNRM__END_OF_DMA_CH2_DMA (1 << 19) -#define ISTNRM__END_OF_DMA_DEV_DMA (1 << 18) -#define ISTNRM__END_OF_DMA_EXT_DMA2 (1 << 17) -#define ISTNRM__END_OF_DMA_EXT_DMA1 (1 << 16) -#define ISTNRM__END_OF_DMA_AICA_DMA (1 << 15) -#define ISTNRM__END_OF_DMA_GD_DMA (1 << 14) -#define ISTNRM__MAPLE_V_BLANK_OVER_INTERRUPT (1 << 13) -#define ISTNRM__END_OF_DMA_MAPLE_DMA (1 << 12) -#define ISTNRM__END_OF_DMA_PVR_DMA (1 << 11) -#define ISTNRM__END_OF_TRANSFERRING_TRANSLUCENT_MODIFIER_VOLUME_LIST (1 << 10) -#define ISTNRM__END_OF_TRANSFERRING_TRANSLUCENT_LIST (1 << 9) -#define ISTNRM__END_OF_TRANSFERRING_OPAQUE_MODIFIER_VOLUME_LIST (1 << 8) -#define ISTNRM__END_OF_TRANSFERRING_OPAQUE_LIST (1 << 7) -#define ISTNRM__END_OF_TRANSFERRING_YUV (1 << 6) -#define ISTNRM__H_BLANK_IN_INTERRUPT (1 << 5) -#define ISTNRM__V_BLANK_OUT_INTERRUPT (1 << 4) -#define ISTNRM__V_BLANK_IN_INTERRUPT (1 << 3) -#define ISTNRM__END_OF_RENDER_TSP (1 << 2) -#define ISTNRM__END_OF_RENDER_ISP (1 << 1) -#define ISTNRM__END_OF_RENDER_VIDEO (1 << 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(uint32_t reg) { return (reg >> 21) & 0x1; } + constexpr uint32_t end_of_dma_sort_dma(uint32_t reg) { return (reg >> 20) & 0x1; } + constexpr uint32_t end_of_dma_ch2_dma(uint32_t reg) { return (reg >> 19) & 0x1; } + constexpr uint32_t end_of_dma_dev_dma(uint32_t reg) { return (reg >> 18) & 0x1; } + constexpr uint32_t end_of_dma_ext_dma2(uint32_t reg) { return (reg >> 17) & 0x1; } + constexpr uint32_t end_of_dma_ext_dma1(uint32_t reg) { return (reg >> 16) & 0x1; } + constexpr uint32_t end_of_dma_aica_dma(uint32_t reg) { return (reg >> 15) & 0x1; } + constexpr uint32_t end_of_dma_gd_dma(uint32_t reg) { return (reg >> 14) & 0x1; } + constexpr uint32_t maple_v_blank_over_interrupt(uint32_t reg) { return (reg >> 13) & 0x1; } + constexpr uint32_t end_of_dma_maple_dma(uint32_t reg) { return (reg >> 12) & 0x1; } + constexpr uint32_t end_of_dma_pvr_dma(uint32_t reg) { return (reg >> 11) & 0x1; } + constexpr uint32_t end_of_transferring_translucent_modifier_volume_list(uint32_t reg) { return (reg >> 10) & 0x1; } + constexpr uint32_t end_of_transferring_translucent_list(uint32_t reg) { return (reg >> 9) & 0x1; } + constexpr uint32_t end_of_transferring_opaque_modifier_volume_list(uint32_t reg) { return (reg >> 8) & 0x1; } + constexpr uint32_t end_of_transferring_opaque_list(uint32_t reg) { return (reg >> 7) & 0x1; } + constexpr uint32_t end_of_transferring_yuv(uint32_t reg) { return (reg >> 6) & 0x1; } + constexpr uint32_t h_blank_in_interrupt(uint32_t reg) { return (reg >> 5) & 0x1; } + constexpr uint32_t v_blank_out_interrupt(uint32_t reg) { return (reg >> 4) & 0x1; } + constexpr uint32_t v_blank_in_interrupt(uint32_t reg) { return (reg >> 3) & 0x1; } + constexpr uint32_t end_of_render_tsp(uint32_t reg) { return (reg >> 2) & 0x1; } + constexpr uint32_t end_of_render_isp(uint32_t reg) { return (reg >> 1) & 0x1; } + constexpr uint32_t end_of_render_video(uint32_t reg) { return (reg >> 0) & 0x1; } +} + +namespace isterr { + constexpr uint32_t sh4__if_access_inhibited_area(uint32_t reg) { return (reg >> 31) & 0x1; } + constexpr uint32_t ddt__if_sort_dma_command_error(uint32_t reg) { return (reg >> 28) & 0x1; } + constexpr uint32_t g2__time_out_in_cpu_access(uint32_t reg) { return (reg >> 27) & 0x1; } + constexpr uint32_t g2__dev_dma_time_out(uint32_t reg) { return (reg >> 26) & 0x1; } + constexpr uint32_t g2__ext_dma2_time_out(uint32_t reg) { return (reg >> 25) & 0x1; } + constexpr uint32_t g2__ext_dma1_time_out(uint32_t reg) { return (reg >> 24) & 0x1; } + constexpr uint32_t g2__aica_dma_time_out(uint32_t reg) { return (reg >> 23) & 0x1; } + constexpr uint32_t g2__dev_dma_over_run(uint32_t reg) { return (reg >> 22) & 0x1; } + constexpr uint32_t g2__ext_dma2_over_run(uint32_t reg) { return (reg >> 21) & 0x1; } + constexpr uint32_t g2__ext_dma1_over_run(uint32_t reg) { return (reg >> 20) & 0x1; } + constexpr uint32_t g2__aica_dma_over_run(uint32_t reg) { return (reg >> 19) & 0x1; } + constexpr uint32_t g2__dev_dma_illegal_address_set(uint32_t reg) { return (reg >> 18) & 0x1; } + constexpr uint32_t g2__ext_dma2_illegal_address_set(uint32_t reg) { return (reg >> 17) & 0x1; } + constexpr uint32_t g2__ext_dma1_illegal_address_set(uint32_t reg) { return (reg >> 16) & 0x1; } + constexpr uint32_t g2__aica_dma_illegal_address_set(uint32_t reg) { return (reg >> 15) & 0x1; } + constexpr uint32_t g1__rom_flash_access_at_gd_dma(uint32_t reg) { return (reg >> 14) & 0x1; } + constexpr uint32_t g1__gd_dma_over_run(uint32_t reg) { return (reg >> 13) & 0x1; } + constexpr uint32_t g1__illegal_address_set(uint32_t reg) { return (reg >> 12) & 0x1; } + constexpr uint32_t maple__illegal_command(uint32_t reg) { return (reg >> 11) & 0x1; } + constexpr uint32_t maple__write_fifo_over_flow(uint32_t reg) { return (reg >> 10) & 0x1; } + constexpr uint32_t maple__dma_over_run(uint32_t reg) { return (reg >> 9) & 0x1; } + constexpr uint32_t maple__illegal_address_set(uint32_t reg) { return (reg >> 8) & 0x1; } + constexpr uint32_t pvrif__dma_over_run(uint32_t reg) { return (reg >> 7) & 0x1; } + constexpr uint32_t pvrif__illegal_address_set(uint32_t reg) { return (reg >> 6) & 0x1; } + constexpr uint32_t ta__fifo_overflow(uint32_t reg) { return (reg >> 5) & 0x1; } + constexpr uint32_t ta__illegal_parameter(uint32_t reg) { return (reg >> 4) & 0x1; } + constexpr uint32_t ta__object_list_pointer_overflow(uint32_t reg) { return (reg >> 3) & 0x1; } + constexpr uint32_t ta__isp_tsp_parameter_overflow(uint32_t reg) { return (reg >> 2) & 0x1; } + constexpr uint32_t render__hazard_processing_of_strip_buffer(uint32_t reg) { return (reg >> 1) & 0x1; } + constexpr uint32_t render__isp_out_of_cache(uint32_t reg) { return (reg >> 0) & 0x1; } +} + +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; } +} -#define ISTERR__SH4__IF_ACCESS_INHIBITED_AREA (1 << 31) -#define ISTERR__DDT__IF_SORT_DMA_COMMAND_ERROR (1 << 28) -#define ISTERR__G2__TIME_OUT_IN_CPU_ACCESS (1 << 27) -#define ISTERR__G2__DEV_DMA_TIME_OUT (1 << 26) -#define ISTERR__G2__EXT_DMA2_TIME_OUT (1 << 25) -#define ISTERR__G2__EXT_DMA1_TIME_OUT (1 << 24) -#define ISTERR__G2__AICA_DMA_TIME_OUT (1 << 23) -#define ISTERR__G2__DEV_DMA_OVER_RUN (1 << 22) -#define ISTERR__G2__EXT_DMA2_OVER_RUN (1 << 21) -#define ISTERR__G2__EXT_DMA1_OVER_RUN (1 << 20) -#define ISTERR__G2__AICA_DMA_OVER_RUN (1 << 19) -#define ISTERR__G2__DEV_DMA_ILLEGAL_ADDRESS_SET (1 << 18) -#define ISTERR__G2__EXT_DMA2_ILLEGAL_ADDRESS_SET (1 << 17) -#define ISTERR__G2__EXT_DMA1_ILLEGAL_ADDRESS_SET (1 << 16) -#define ISTERR__G2__AICA_DMA_ILLEGAL_ADDRESS_SET (1 << 15) -#define ISTERR__G1__ROM_FLASH_ACCESS_AT_GD_DMA (1 << 14) -#define ISTERR__G1__GD_DMA_OVER_RUN (1 << 13) -#define ISTERR__G1__ILLEGAL_ADDRESS_SET (1 << 12) -#define ISTERR__MAPLE__ILLEGAL_COMMAND (1 << 11) -#define ISTERR__MAPLE__WRITE_FIFO_OVER_FLOW (1 << 10) -#define ISTERR__MAPLE__DMA_OVER_RUN (1 << 9) -#define ISTERR__MAPLE__ILLEGAL_ADDRESS_SET (1 << 8) -#define ISTERR__PVRIF__DMA_OVER_RUN (1 << 7) -#define ISTERR__PVRIF__ILLEGAL_ADDRESS_SET (1 << 6) -#define ISTERR__TA__FIFO_OVERFLOW (1 << 5) -#define ISTERR__TA__ILLEGAL_PARAMETER (1 << 4) -#define ISTERR__TA__OBJECT_LIST_POINTER_OVERFLOW (1 << 3) -#define ISTERR__TA__ISP_TSP_PARAMETER_OVERFLOW (1 << 2) -#define ISTERR__RENDER__HAZARD_PROCESSING_OF_STRIP_BUFFER (1 << 1) -#define ISTERR__RENDER__ISP_OUT_OF_CACHE (1 << 0) diff --git a/type.hpp b/type.hpp index fad568b..6113b3d 100644 --- a/type.hpp +++ b/type.hpp @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #ifndef __cplusplus #ifndef static_assert