aica: initial working example

This plays 10 seconds of PCM audio via the AICA ARM CPU.
This commit is contained in:
Zack Buhman 2024-02-29 16:51:25 +08:00
parent 5b696f7c0d
commit 3338b611c1
29 changed files with 789 additions and 516 deletions

View File

@ -1,5 +1,5 @@
#include <cstdint>
#include <cstddef>
#include <stdint.h>
#include <stddef.h>
#include "type.hpp"

View File

@ -1,46 +1,28 @@
#include <cstdint>
#include <cstddef>
#include <stdint.h>
#include <stddef.h>
#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
{

View File

@ -1,62 +1,37 @@
#include <cstdint>
#include <cstddef>
#include <stdint.h>
#include <stddef.h>
#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
{

View File

@ -1,11 +1,10 @@
#include <cstdint>
#include <cstddef>
#include <stdint.h>
#include <stddef.h>
#include "type.hpp"
struct aica_dsp_out {
reg16 reg_0000;
const reg16 _pad0[1];
reg32 reg_0000;
uint32_t EFDSL() const
{

View File

@ -1,15 +1,12 @@
#include <cstdint>
#include <cstddef>
#include <stdint.h>
#include <stddef.h>
#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
{

57
alt.lds
View File

@ -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"

BIN
audio.pcm Normal file

Binary file not shown.

57
base.mk Normal file
View File

@ -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')

56
common.lds Normal file
View File

@ -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"

124
common.mk
View File

@ -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 \

62
example/aica.cpp Normal file
View File

@ -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<uint32_t *>(&_binary_start);
const uint32_t binary_size = reinterpret_cast<uint32_t>(&_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<uint32_t>(aica_wave_memory[0]);
wait(); aica.common.MSLC(0);
serial::string("mrwinh: ");
wait_read();
serial::integer<uint8_t>(aica.common.MRWINH());
while (1) {
wait_read();
serial::string("sgc: ");
serial::integer<uint8_t>(aica.common.SGC(), ' ');
serial::string("; ca: ");
serial::integer<uint8_t>(aica.common.CA(), ' ');
serial::string("; eg: ");
serial::integer<uint8_t>(aica.common.EG(), ' ');
serial::string("; lp: ");
serial::integer<uint8_t>(aica.common.LP(), ' ');
serial::character('\n');
for (int i = 0; i < 10000000; i++) {
asm volatile ("nop");
}
}
while (1);
}

22
example/arm/Makefile Normal file
View File

@ -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

View File

@ -0,0 +1,2 @@
dram = 0x00000000;
aica = 0x00800000;

8
example/arm/arm.lds Normal file
View File

@ -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) }

1
example/arm/audio.pcm Symbolic link
View File

@ -0,0 +1 @@
../../audio.pcm

1
example/arm/base.mk Symbolic link
View File

@ -0,0 +1 @@
../../base.mk

57
example/arm/main.cpp Normal file
View File

@ -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<uint32_t>(&_sine_start);
volatile uint32_t * slot = reinterpret_cast<volatile uint32_t*>(0x00800000);
for (uint32_t i = 0; i < (sizeof (struct aica_channel)) * 64 / 4; i++) {
slot[i] = 0;
}
volatile uint32_t * dsp = reinterpret_cast<volatile uint32_t*>(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);
}
}
}

56
example/arm/main.lds Normal file
View File

@ -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"

29
example/arm/start.s Normal file
View File

@ -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

View File

@ -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)

17
example/interrupt.cpp Normal file
View File

@ -0,0 +1,17 @@
#include <cstdint>
#include "serial.hpp"
#include "sh7095.hpp"
#include "sh7095_bits.hpp"
void main()
{
uint32_t vbr;
asm ("stc vbr,%0" : "=r" (vbr));
serial::integer<uint32_t>(vbr);
while (1);
}

70
headers.mk Normal file
View File

@ -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 $< > $@

View File

@ -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"

View File

@ -142,20 +142,20 @@ def part_get_expression(part):
arg_mask = mask_from_bits(part.argument_bits)
return f"(static_cast<uint32_t>(({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 <cstdint>"
yield "#include <cstddef>"
yield '#include <stdint.h>'
yield '#include <stddef.h>'
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())

62
regs/systembus_bits.csv Normal file
View File

@ -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",,,
1 register_name enum_name bits bit_name value mask description
2 C2DSTAT 31-0 texture_memory_start_address 0x13ffffe0
3 C2DLEN 23-0 transfer_length 0xffffe0
4 C2DST 0 start 1
5
6 ISTNRM 21 end_of_transferring_punch_through_list
7 ISTNRM 20 end_of_dma_sort_dma
8 ISTNRM 19 end_of_dma_ch2_dma
9 ISTNRM 18 end_of_dma_dev_dma
10 ISTNRM 17 end_of_dma_ext_dma2
11 ISTNRM 16 end_of_dma_ext_dma1
12 ISTNRM 15 end_of_dma_aica_dma
13 ISTNRM 14 end_of_dma_gd_dma
14 ISTNRM 13 maple_v_blank_over_interrupt
15 ISTNRM 12 end_of_dma_maple_dma
16 ISTNRM 11 end_of_dma_pvr_dma
17 ISTNRM 10 end_of_transferring_translucent_modifier_volume_list
18 ISTNRM 9 end_of_transferring_translucent_list
19 ISTNRM 8 end_of_transferring_opaque_modifier_volume_list
20 ISTNRM 7 end_of_transferring_opaque_list
21 ISTNRM 6 end_of_transferring_yuv
22 ISTNRM 5 h_blank_in_interrupt
23 ISTNRM 4 v_blank_out_interrupt
24 ISTNRM 3 v_blank_in_interrupt
25 ISTNRM 2 end_of_render_tsp
26 ISTNRM 1 end_of_render_isp
27 ISTNRM 0 end_of_render_video
28
29 ISTERR 31 sh4__if_access_inhibited_area
30 ISTERR 28 ddt__if_sort_dma_command_error
31 ISTERR 27 g2__time_out_in_cpu_access
32 ISTERR 26 g2__dev_dma_time_out
33 ISTERR 25 g2__ext_dma2_time_out
34 ISTERR 24 g2__ext_dma1_time_out
35 ISTERR 23 g2__aica_dma_time_out
36 ISTERR 22 g2__dev_dma_over_run
37 ISTERR 21 g2__ext_dma2_over_run
38 ISTERR 20 g2__ext_dma1_over_run
39 ISTERR 19 g2__aica_dma_over_run
40 ISTERR 18 g2__dev_dma_illegal_address_set
41 ISTERR 17 g2__ext_dma2_illegal_address_set
42 ISTERR 16 g2__ext_dma1_illegal_address_set
43 ISTERR 15 g2__aica_dma_illegal_address_set
44 ISTERR 14 g1__rom_flash_access_at_gd_dma
45 ISTERR 13 g1__gd_dma_over_run
46 ISTERR 12 g1__illegal_address_set
47 ISTERR 11 maple__illegal_command
48 ISTERR 10 maple__write_fifo_over_flow
49 ISTERR 9 maple__dma_over_run
50 ISTERR 8 maple__illegal_address_set
51 ISTERR 7 pvrif__dma_over_run
52 ISTERR 6 pvrif__illegal_address_set
53 ISTERR 5 ta__fifo_overflow
54 ISTERR 4 ta__illegal_parameter
55 ISTERR 3 ta__object_list_pointer_overflow
56 ISTERR 2 ta__isp_tsp_parameter_overflow
57 ISTERR 1 render__hazard_processing_of_strip_buffer
58 ISTERR 0 render__isp_out_of_cache
59
60 FFST 5 holly_cpu_if_block_internal_write_buffer
61 FFST 4 holly_g2_if_block_internal_write_buffer
62 FFST 0 aica_internal_write_buffer

BIN
regs/systembus_bits.ods Normal file

Binary file not shown.

View File

@ -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);

View File

@ -1,59 +1,80 @@
#define C2DST__STATUS (1 << 0)
#pragma once
#define CD2LEN__LENGTH(n) (((n) & 0xffffe0) << 0)
#include <cstdint>
#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)

View File

@ -1,7 +1,7 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <stddef.h>
#include <stdint.h>
#ifndef __cplusplus
#ifndef static_assert