commit e198768b7fee24ed64a5d2831f115f56cce76d84 Author: Zack Buhman Date: Tue Oct 15 04:55:31 2024 -0500 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9abd1f6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.bin +*.d +*.elf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/arm7.lds b/arm7.lds new file mode 100644 index 0000000..4c54aeb --- /dev/null +++ b/arm7.lds @@ -0,0 +1,53 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +MEMORY +{ + main_memory : ORIGIN = 0x02390000, LENGTH = 256K + arm7_exclusive_internal_work_ram : ORIGIN = 0x03800000, LENGTH = 64K +} +SECTIONS +{ + . = ORIGIN(arm7_exclusive_internal_work_ram); + + .text ALIGN(4) : + { + KEEP(*(.text.start)) + *(.text) + *(.text.*) + . = ALIGN(32); + } > arm7_exclusive_internal_work_ram AT> main_memory + + .data ALIGN(4) : + { + *(.data) + *(.data.*) + } > arm7_exclusive_internal_work_ram AT> main_memory + + .rodata ALIGN(4) : + { + *(.rodata) + *(.rodata.*) + } > arm7_exclusive_internal_work_ram AT> main_memory + + .ctors ALIGN(4) : + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + } > arm7_exclusive_internal_work_ram AT> main_memory + + .bss ALIGN(4) (NOLOAD) : + { + *(.bss) + *(.bss.*) + *(COMMON) + } > arm7_exclusive_internal_work_ram + + /DISCARD/ : + { + *(.glue_7) *(.glue_7t) *(.vfp11_veneer) *(.v4_bx) + } + + INCLUDE "debug.lds" +} + +INCLUDE "symbols.lds" diff --git a/arm7.mk b/arm7.mk new file mode 100644 index 0000000..17d949b --- /dev/null +++ b/arm7.mk @@ -0,0 +1,5 @@ +TARGET ?= arm-none-eabi- +AARCH ?= -march=armv4t -mlittle-endian +CARCH ?= -march=armv4t -mtune=arm7tdmi -mlittle-endian -mno-thumb-interwork +OBJARCH ?= -O elf32-littlearm -B armv4t +LDSCRIPT ?= arm7.lds diff --git a/arm9.lds b/arm9.lds new file mode 100644 index 0000000..bc6ce25 --- /dev/null +++ b/arm9.lds @@ -0,0 +1,53 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +MEMORY +{ + main_memory : ORIGIN = 0x02000000, LENGTH = 4M - 256K + arm9_instruction_tcm : ORIGIN = 0x01000000, LENGTH = 32K + arm9_data_tcm : ORIGIN = 0x027e0000, LENGTH = 16K +} +SECTIONS +{ + . = ORIGIN(arm9_instruction_tcm); + + .text ALIGN(4) : + { + KEEP(*(.text.start)) + *(.text) + *(.text.*) + . = ALIGN(32); + } > arm9_instruction_tcm AT> main_memory + + . = ORIGIN(main_memory) + SIZEOF(.text); + + .data ALIGN(4) : + { + *(.data) + *(.data.*) + } > main_memory + + .rodata ALIGN(4) : + { + *(.rodata) + *(.rodata.*) + } > main_memory + + .bss ALIGN(4) (NOLOAD) : + { + *(.bss) + *(.bss.*) + *(COMMON) + } > main_memory + + /DISCARD/ : + { + *(.glue_7) *(.glue_7t) *(.vfp11_veneer) *(.v4_bx) + } + + INCLUDE "debug.lds" +} + +INCLUDE "symbols.lds" +INCLUDE "arm9_addresses.lds" + +__stack_end = ORIGIN(main_memory) + LENGTH(main_memory) - 4; diff --git a/arm9.mk b/arm9.mk new file mode 100644 index 0000000..cf60f8e --- /dev/null +++ b/arm9.mk @@ -0,0 +1,5 @@ +TARGET ?= arm-none-eabi- +AARCH ?= -march=armv5te+nofp -mlittle-endian +CARCH ?= -march=armv5te+nofp -mtune=arm946e-s -mlittle-endian -mno-thumb-interwork +OBJARCH ?= -O elf32-littlearm -B armv5te +LDSCRIPT ?= arm9.lds diff --git a/arm9_addresses.lds b/arm9_addresses.lds new file mode 100644 index 0000000..ea8bcbf --- /dev/null +++ b/arm9_addresses.lds @@ -0,0 +1,5 @@ +io_registers = 0x04000000; +palette_ram = 0x05000000; +bg_vram = 0x06000000; +obj_vram = 0x06400000; +oam = 0x07000000; diff --git a/cartridge.lds b/cartridge.lds new file mode 100644 index 0000000..0559cc0 --- /dev/null +++ b/cartridge.lds @@ -0,0 +1,58 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 4M +} +SECTIONS +{ + . = 0x00000000; + + _start = .; + + .text.header ALIGN(4) : + { + KEEP(*(.text.header)) + } AT>rom + + . = 0x02000000; + + _arm9 = .; + + .text.arm9 ALIGN(4) : + { + KEEP(*(.data.*arm9*.bin)) + . = ALIGN(32); + } AT>rom + + . = 0x02000000 + 0x390000; + + _arm7 = .; + + .text.arm7 ALIGN(4) : + { + KEEP(*(.data.*arm7*.bin)) + . = ALIGN(32); + } AT>rom + + /DISCARD/ : + { + *(.glue_7) *(.glue_7t) *(.vfp11_veneer) *(.v4_bx) + } + + INCLUDE "debug.lds" +} + +/* header symbols */ +_arm9_offset = LOADADDR(.text.arm9); +_arm9_entry = ADDR(.text.arm9); +_arm9_addr = ADDR(.text.arm9); +_arm9_size = SIZEOF(.text.arm9); + +_arm7_offset = LOADADDR(.text.arm7); +_arm7_entry = ADDR(.text.arm7); +_arm7_addr = ADDR(.text.arm7); +_arm7_size = SIZEOF(.text.arm7); + +_rom_size = SIZEOF(.text.header) + SIZEOF(.text.arm9) + SIZEOF(.text.arm7); +_header_size = SIZEOF(.text.header); diff --git a/cartridge.mk b/cartridge.mk new file mode 100644 index 0000000..4d99f99 --- /dev/null +++ b/cartridge.mk @@ -0,0 +1,5 @@ +TARGET ?= arm-none-eabi- +AARCH ?= -march=armv4t -mlittle-endian +CARCH ?= -march=armv4t -mtune=arm7tdmi -mlittle-endian -mno-thumb-interwork +OBJARCH ?= -O elf32-littlearm -B armv4t +LDSCRIPT ?= cartridge.lds diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..61af3d9 --- /dev/null +++ b/common.mk @@ -0,0 +1,104 @@ +MAKEDIR ?= $(realpath $(dir $(realpath $(firstword $(MAKEFILE_LIST))))) + +OPT ?= -Og +DEBUG = -g -gdwarf-4 + +AFLAGS += --fatal-warnings +AFLAGS += -I$(MAKEDIR) + +CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib -fno-builtin +#-finline-stringops +CFLAGS += -Wall -Werror -Wfatal-errors +CFLAGS += -Wno-array-bounds +#CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=unused-variable +CFLAGS += -Wno-aggressive-loop-optimizations +CFLAGS += -fno-inline-small-functions +CFLAGS += -I$(MAKEDIR)/include + +CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics + +# +LDFLAGS += --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error --print-gc-sections + +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 + cd $(dir $<) ; \ + $(OBJCOPY) \ + -I binary $(OBJARCH) \ + --rename-section .data=.data.$(basename $@) \ + $(notdir $<) $(notdir $@) +endef + +as_obj_binary = _binary_$(subst .,_,$(subst /,_,$(notdir $(1)))) + +define BUILD_BINARY_H + @echo gen $@ + @echo '#pragma once' > $@ + @echo '#include ' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$<)_start __asm("$(call as_obj_binary,$<)_start");' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$<)_end __asm("$(call as_obj_binary,$<)_end");' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$<)_size __asm("$(call as_obj_binary,$<)_size");' >> $@ +endef + +%.bin.o: %.bin + $(BUILD_BINARY_O) + +%.pcm.o: %.pcm + $(BUILD_BINARY_O) + +%.data.o: %.data + $(BUILD_BINARY_O) + +%.data.pal.o: %.data.pal + $(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: $(OBJ) + $(LD) $(LDFLAGS) -L $(MAKEDIR) -T $(LDSCRIPT) $^ -o $@ + +%.bin: %.elf + $(OBJCOPY) -O binary $< $@ + du -b $@ + +%.nds: %.bin + python $(MAKEDIR)/patch.py $< $@ + +-include $(shell find -type f -name '*.d') + +clean: + find -P \ + -regextype posix-egrep \ + -regex '.*\.(nds|o|d|bin|elf|gch)$$' \ + -exec rm {} \; + +.SUFFIXES: +.INTERMEDIATE: +.SECONDARY: +.PHONY: all clean + +%: RCS/%,v +%: RCS/% +%: %,v +%: s.% +%: SCCS/s.% diff --git a/debug.lds b/debug.lds new file mode 100644 index 0000000..d7d682a --- /dev/null +++ b/debug.lds @@ -0,0 +1,94 @@ + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .plt : { *(.plt) } + .iplt : { *(.iplt) } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.rela.*) } diff --git a/header.s b/header.s new file mode 100644 index 0000000..4d9637a --- /dev/null +++ b/header.s @@ -0,0 +1,53 @@ + .section .text.header + + .ascii "game title " /* Game Title */ + .ascii "####" /* Game Code */ + .ascii "00" /* Maker Code */ + .byte 0x0 /* Unit Code */ + .byte 0x0 /* Device type */ + .byte 0x1 /* Device capacity */ + .fill 7,1,0x0 /* Reserved */ + .byte 0x0 /* Reserved */ + .byte 0x0 /* NDS region */ + .byte 0x0 /* ROM version */ + .byte 0x0 /* Autostart */ + .long _arm9_offset /* ARM9 rom offset */ + .long _arm9_entry /* ARM9 entry address */ + .long _arm9_addr /* ARM9 ram address */ + .long _arm9_size /* ARM9 size */ + .long _arm7_offset /* ARM7 rom offset */ + .long _arm7_entry /* ARM7 entry address */ + .long _arm7_addr /* ARM7 ram address */ + .long _arm7_size /* ARM7 size */ + .long 0x00000000 /* File name table offset */ + .long 0x00000000 /* File name table size */ + .long 0x00000000 /* File allocation table offset */ + .long 0x00000000 /* file allocation table size */ + .long 0x00000000 /* ARM9 overlay offset */ + .long 0x00000000 /* ARM9 overlay size */ + .long 0x00000000 /* ARM7 overlay offset */ + .long 0x00000000 /* ARM7 overlay size */ + .long 0x00586000 /* 040001a4 setting for normal commands */ + .long 0x001808F8 /* 040001a4 setting for KEY1 commands */ + .long 0x00000000 /* Icon/Title offset */ + .short 0x4bff /* Secure Area Checksum */ + .short 0x0d7e /* Secure Area Delay */ + .long 0x00000000 /* ARM9 auto load list hook ram address */ + .long 0x00000000 /* ARM7 auto load list hook ram address */ + .fill 8,1,0x0 /* Secure Area Disable */ + .long _rom_size /* Total used rom size */ + .long _header_size /* ROM header size */ + .fill 4,1,0x0 /* Reserved */ + .fill 8,1,0x0 /* Reserved */ + .short 0x0000 /* NAND end of ROM area */ + .short 0x0000 /* NAND start of RW area */ + .fill 24,1,0x0 /* Reserved */ + .fill 16,1,0x0 /* Reserved */ + .include "logo.s" /* Nintendo logo */ + .short 0xcf56 /* Nintendo logo checksum */ + .short 0xffff /* Header checksum */ + .long 0x00000000 /* Debug rom offset */ + .long 0x00000000 /* Debug rom size */ + .long 0x00000000 /* Debug ram address */ + .fill 4,1,0x0 /* Reserved */ + .balign 0x8000,0x0 /* Padding */ diff --git a/include/bg.h b/include/bg.h new file mode 100644 index 0000000..164d9d8 --- /dev/null +++ b/include/bg.h @@ -0,0 +1,66 @@ +#pragma once + +#include + +#define static_assert _Static_assert + +union bg_screen_block { + uint8_t u8[0x800 / 1]; + uint16_t u16[0x800 / 2]; + uint32_t u32[0x800 / 4]; +}; +static_assert((sizeof (union bg_screen_block)) == 0x800); + +struct bg_screen_offset { + union bg_screen_block block[32]; +}; +static_assert((sizeof (struct bg_screen_offset)) == 0x10000); + +struct bg_screen_data { + struct bg_screen_offset offset[8]; +}; +static_assert((sizeof (struct bg_screen_data)) == 0x80000); + +union bg_character { + uint8_t u8[32 / 1]; + uint16_t u16[32 / 2]; + uint32_t u32[32 / 4]; +}; +static_assert((sizeof (union bg_character)) == 32); + +union bg_character_block { + union bg_character character[0x4000 / (sizeof (union bg_character))]; + union { + uint8_t u8[0x4000 / 1]; + uint16_t u16[0x4000 / 2]; + uint32_t u32[0x4000 / 4]; + }; +}; +static_assert((sizeof (union bg_character_block)) == 0x4000); + +struct bg_character_offset { + union bg_character_block block[4]; // is actually 16 +}; + +struct bg_character_data { + struct bg_character_offset offset[8]; +}; +static_assert((sizeof (struct bg_character_data)) == 0x80000); + +struct bg { + union { + struct bg_screen_data screen; + struct bg_character_data character; + }; +}; +static_assert((sizeof (struct bg)) == 0x80000); + +struct bg_vram { + struct bg a; + uint8_t _pad[0x200000 - (sizeof (struct bg))]; + struct bg b; +}; +static_assert((offsetof (struct bg_vram, a)) == 0); +static_assert((offsetof (struct bg_vram, b)) == 0x200000); + +extern struct bg_vram bg_vram __asm("bg_vram"); diff --git a/include/bits.h b/include/bits.h new file mode 100644 index 0000000..d783545 --- /dev/null +++ b/include/bits.h @@ -0,0 +1,381 @@ +#define DISPCNT__obj_extended_palette (0x1 << 31) +#define DISPCNT__bg_extended_palette (0x1 << 30) +#define DISPCNT__bg_screen_base_offset(v) (((v) & 0x7) << 27) +#define DISPCNT__bg_character_base_offset(v) (((v) & 0x7) << 24) +#define DISPCNT__obj_processing_during_h_blank_period (0x1 << 23) +#define DISPCNT__obj_vram_capacity__128kb (0x0 << 22) +#define DISPCNT__obj_vram_capacity__256kb (0x1 << 22) +#define DISPCNT__character_vram_capacity__32kb (0x0 << 20) +#define DISPCNT__character_vram_capacity__64kb (0x1 << 20) +#define DISPCNT__character_vram_capacity__128kb (0x2 << 20) +#define DISPCNT__character_vram_capacity__256kb (0x3 << 20) +#define DISPCNT__display_vram_block__vram_a (0x0 << 18) +#define DISPCNT__display_vram_block__vram_b (0x1 << 18) +#define DISPCNT__display_vram_block__vram_c (0x2 << 18) +#define DISPCNT__display_vram_block__vram_d (0x3 << 18) +#define DISPCNT__display_mode__display_off (0x0 << 16) +#define DISPCNT__display_mode__graphics_display (0x1 << 16) +#define DISPCNT__display_mode__vram_display (0x2 << 16) +#define DISPCNT__display_mode__main_memory_display (0x3 << 16) +#define DISPCNT__obj_window__disable (0x0 << 15) +#define DISPCNT__obj_window__enable (0x1 << 15) +#define DISPCNT__window_1__disable (0x0 << 14) +#define DISPCNT__window_1__enable (0x1 << 14) +#define DISPCNT__window_0__disable (0x0 << 13) +#define DISPCNT__window_0__enable (0x1 << 13) +#define DISPCNT__obj__disable (0x0 << 12) +#define DISPCNT__obj__enable (0x1 << 12) +#define DISPCNT__bg3__disable (0x0 << 11) +#define DISPCNT__bg3__enable (0x1 << 11) +#define DISPCNT__bg2__disable (0x0 << 10) +#define DISPCNT__bg2__enable (0x1 << 10) +#define DISPCNT__bg1__disable (0x0 << 9) +#define DISPCNT__bg1__enable (0x1 << 9) +#define DISPCNT__bg0__disable (0x0 << 8) +#define DISPCNT__bg0__enable (0x1 << 8) +#define DISPCNT__2d_display_forced_blank (0x1 << 7) +#define DISPCNT__bitmap_obj_mapping_mode__2d_mapping_with_128_horizontal_dots (0x0 << 5) +#define DISPCNT__bitmap_obj_mapping_mode__2d_mapping_with_256_horizontal_dots (0x1 << 5) +#define DISPCNT__bitmap_obj_mapping_mode__1d_mapping (0x2 << 5) +#define DISPCNT__character_obj_mapping_mode__2d_mapping (0x0 << 4) +#define DISPCNT__character_obj_mapping_mode__1d_mapping (0x1 << 4) +#define DISPCNT__display_selection_for_bg0__2d_graphics (0x0 << 3) +#define DISPCNT__display_selection_for_bg0__3d_graphics (0x1 << 3) +#define DISPCNT__bg_mode__text0_text1_text2_text3 (0x0 << 0) +#define DISPCNT__bg_mode__text0_text1_text2_affine3 (0x1 << 0) +#define DISPCNT__bg_mode__text0_text1_affine2_affine3 (0x2 << 0) +#define DISPCNT__bg_mode__text0_text1_text2_extended3 (0x3 << 0) +#define DISPCNT__bg_mode__text0_text1_affine2_extended3 (0x4 << 0) +#define DISPCNT__bg_mode__text0_text1_extended2_extended3 (0x5 << 0) +#define DISPCNT__bg_mode__3d_large_screen_256_color_bitmap (0x6 << 0) +#define DISPSTAT__v_counter_match_interrupt_request__disable (0x0 << 5) +#define DISPSTAT__v_counter_match_interrupt_request__enable (0x1 << 5) +#define DISPSTAT__h_blank_interrupt_request__disable (0x0 << 4) +#define DISPSTAT__h_blank_interrupt_request__enable (0x1 << 4) +#define DISPSTAT__v_blank_interrupt_request__disable (0x0 << 3) +#define DISPSTAT__v_blank_interrupt_request__enable (0x1 << 3) +#define DISPSTAT__v_counter_match_detection__outside_a_matching_interval (0x0 << 2) +#define DISPSTAT__v_counter_match_detection__during_a_matching_interval (0x1 << 2) +#define DISPSTAT__h_blank_detection__outside_h_blank_interval (0x0 << 1) +#define DISPSTAT__h_blank_detection__during_h_blank_interval (0x1 << 1) +#define DISPSTAT__v_blank_detection__outside_v_blank_interval (0x0 << 0) +#define DISPSTAT__v_blank_detection__during_v_blank_interval (0x1 << 0) +#define VCOUNT__v_counter_value(v) (((v) >> 0) & 0x1ff) +#define BG0CNT__screen_size__256x256 (0x0 << 14) +#define BG0CNT__screen_size__512x256 (0x1 << 14) +#define BG0CNT__screen_size__256x512 (0x2 << 14) +#define BG0CNT__screen_size__512x512 (0x3 << 14) +#define BG0CNT__bg_extended_palette_slot__slot_0 (0x0 << 13) +#define BG0CNT__bg_extended_palette_slot__slot_2 (0x1 << 13) +#define BG0CNT__screen_base_block(v) (((v) & 0x1f) << 8) +#define BG0CNT__color_mode__16_color_mode (0x0 << 7) +#define BG0CNT__color_mode__256_color_mode (0x1 << 7) +#define BG0CNT__mosaic__disable (0x0 << 6) +#define BG0CNT__mosaic__enable (0x1 << 6) +#define BG0CNT__character_base_block(v) (((v) & 0xf) << 2) +#define BG0CNT__priority(v) (((v) & 0x3) << 0) +#define BG1CNT__screen_size__256x256 (0x0 << 14) +#define BG1CNT__screen_size__512x256 (0x1 << 14) +#define BG1CNT__screen_size__256x512 (0x2 << 14) +#define BG1CNT__screen_size__512x512 (0x3 << 14) +#define BG1CNT__bg_extended_palette_slot__slot_1 (0x0 << 13) +#define BG1CNT__bg_extended_palette_slot__slot_3 (0x1 << 13) +#define BG1CNT__screen_base_block(v) (((v) & 0x1f) << 8) +#define BG1CNT__color_mode__16_color_mode (0x0 << 7) +#define BG1CNT__color_mode__256_color_mode (0x1 << 7) +#define BG1CNT__mosaic__disable (0x0 << 6) +#define BG1CNT__mosaic__enable (0x1 << 6) +#define BG1CNT__character_base_block(v) (((v) & 0xf) << 2) +#define BG1CNT__priority(v) (((v) & 0x3) << 0) +#define BG2CNT__screen_size__256x256 (0x0 << 14) +#define BG2CNT__screen_size__512x256 (0x1 << 14) +#define BG2CNT__screen_size__256x512 (0x2 << 14) +#define BG2CNT__screen_size__512x512 (0x3 << 14) +#define BG2CNT__out_of_area_processing__transparent_display (0x0 << 13) +#define BG2CNT__out_of_area_processing__wraparound_display (0x1 << 13) +#define BG2CNT__screen_base_block(v) (((v) & 0x1f) << 8) +#define BG2CNT__color_mode__16_color_mode (0x0 << 7) +#define BG2CNT__color_mode__256_color_mode (0x1 << 7) +#define BG2CNT__mosaic__disable (0x0 << 6) +#define BG2CNT__mosaic__enable (0x1 << 6) +#define BG2CNT__character_base_block(v) (((v) & 0xf) << 2) +#define BG2CNT__priority(v) (((v) & 0x3) << 0) +#define BG3CNT__screen_size__256x256 (0x0 << 14) +#define BG3CNT__screen_size__512x256 (0x1 << 14) +#define BG3CNT__screen_size__256x512 (0x2 << 14) +#define BG3CNT__screen_size__512x512 (0x3 << 14) +#define BG3CNT__out_of_area_processing__transparent_display (0x0 << 13) +#define BG3CNT__out_of_area_processing__wraparound_display (0x1 << 13) +#define BG3CNT__screen_base_block(v) (((v) & 0x1f) << 8) +#define BG3CNT__color_mode__16_color_mode (0x0 << 7) +#define BG3CNT__color_mode__256_color_mode (0x1 << 7) +#define BG3CNT__mosaic__disable (0x0 << 6) +#define BG3CNT__mosaic__enable (0x1 << 6) +#define BG3CNT__character_base_block(v) (((v) & 0xf) << 2) +#define BG3CNT__priority(v) (((v) & 0x3) << 0) +#define VRAMCNT__vram_d__disable (0x0 << 31) +#define VRAMCNT__vram_d__enable (0x1 << 31) +#define VRAMCNT__vram_d__ofs(v) (((v) & 0x3) << 27) +#define VRAMCNT__vram_d__mst(v) (((v) & 0x7) << 24) +#define VRAMCNT__vram_c__disable (0x0 << 23) +#define VRAMCNT__vram_c__enable (0x1 << 23) +#define VRAMCNT__vram_c__ofs(v) (((v) & 0x3) << 19) +#define VRAMCNT__vram_c__mst(v) (((v) & 0x7) << 16) +#define VRAMCNT__vram_b__disable (0x0 << 15) +#define VRAMCNT__vram_b__enable (0x1 << 15) +#define VRAMCNT__vram_b__ofs(v) (((v) & 0x3) << 11) +#define VRAMCNT__vram_b__mst(v) (((v) & 0x3) << 8) +#define VRAMCNT__vram_a__disable (0x0 << 7) +#define VRAMCNT__vram_a__enable (0x1 << 7) +#define VRAMCNT__vram_a__ofs(v) (((v) & 0x3) << 3) +#define VRAMCNT__vram_a__mst(v) (((v) & 0x3) << 0) +#define WVRAMCNT__wram__bank(v) (((v) & 0x3) << 24) +#define WVRAMCNT__vram_g__disable (0x0 << 23) +#define WVRAMCNT__vram_g__enable (0x1 << 23) +#define WVRAMCNT__vram_g__ofs(v) (((v) & 0x3) << 19) +#define WVRAMCNT__vram_g__mst(v) (((v) & 0x7) << 16) +#define WVRAMCNT__vram_f__disable (0x0 << 15) +#define WVRAMCNT__vram_f__enable (0x1 << 15) +#define WVRAMCNT__vram_f__ofs(v) (((v) & 0x3) << 11) +#define WVRAMCNT__vram_f__mst(v) (((v) & 0x7) << 8) +#define WVRAMCNT__vram_e__disable (0x0 << 7) +#define WVRAMCNT__vram_e__enable (0x1 << 7) +#define WVRAMCNT__vram_e__mst(v) (((v) & 0x7) << 0) +#define VRAM_HI_CNT__vram_i__disable (0x0 << 15) +#define VRAM_HI_CNT__vram_i__enable (0x1 << 15) +#define VRAM_HI_CNT__vram_i__mst(v) (((v) & 0x3) << 8) +#define VRAM_HI_CNT__vram_h__disable (0x0 << 7) +#define VRAM_HI_CNT__vram_h__enable (0x1 << 7) +#define VRAM_HI_CNT__vram_h__mst(v) (((v) & 0x3) << 0) +#define POWCNT__lcd_output_destination__a_to_lower__b_to_upper (0x0 << 15) +#define POWCNT__lcd_output_destination__a_to_upper__b_to_lower (0x1 << 15) +#define POWCNT__2d_graphics_engine_b__disable (0x0 << 9) +#define POWCNT__2d_graphics_engine_b__enable (0x1 << 9) +#define POWCNT__geometry_engine__disable (0x0 << 3) +#define POWCNT__geometry_engine__enable (0x1 << 3) +#define POWCNT__rendering_engine__disable (0x0 << 2) +#define POWCNT__rendering_engine__enable (0x1 << 2) +#define POWCNT__2d_graphics_engine_a__disable (0x0 << 1) +#define POWCNT__2d_graphics_engine_a__enable (0x1 << 1) +#define POWCNT__lcd__disable (0x0 << 0) +#define POWCNT__lcd__enable (0x1 << 0) +#define RDLINES_COUNT__rendered_lines_min(v) (((v) >> 0) & 0x3f) +#define ALPHA_TEST_REF__comparison_value(v) (((v) & 0x1f) << 0) +#define CLEAR_COLOR__clear_polygon_id(v) (((v) & 0x3f) << 24) +#define CLEAR_COLOR__alpha_value(v) (((v) & 0x1f) << 16) +#define CLEAR_COLOR__fog_enable (0x1 << 15) +#define CLEAR_COLOR__blue(v) (((v) & 0x1f) << 10) +#define CLEAR_COLOR__green(v) (((v) & 0x1f) << 5) +#define CLEAR_COLOR__red(v) (((v) & 0x1f) << 0) +#define CLEAR_DEPTH__value(v) (((v) & 0x7fff) << 0) +#define CLRIMAGE_OFFSET__y_offset(v) (((v) & 0xff) << 8) +#define CLRIMAGE_OFFSET__x_offset(v) (((v) & 0xff) << 0) +#define DISP3DCNT__clear_image__disable (0x0 << 14) +#define DISP3DCNT__clear_image__enable (0x1 << 14) +#define DISP3DCNT__polygon_list_ram_and_vertex_ram_overflow (0x1 << 13) +#define DISP3DCNT__color_buffer_underflow (0x1 << 12) +#define DISP3DCNT__fog_shift(v) (((v) & 0xf) << 8) +#define DISP3DCNT__fog_master__disable (0x0 << 7) +#define DISP3DCNT__fog_master__enable (0x1 << 7) +#define DISP3DCNT__fog_mode__blending_using_pixel_color_value_and_alpha_value (0x0 << 6) +#define DISP3DCNT__fog_mode__blending_using_only_pixel_alpha_value (0x1 << 6) +#define DISP3DCNT__edge_marking__disable (0x0 << 5) +#define DISP3DCNT__edge_marking__enable (0x1 << 5) +#define DISP3DCNT__anti_aliasing__disable (0x0 << 4) +#define DISP3DCNT__anti_aliasing__enable (0x1 << 4) +#define DISP3DCNT__alpha_blending__disable (0x0 << 3) +#define DISP3DCNT__alpha_blending__enable (0x1 << 3) +#define DISP3DCNT__alpha_test__disable (0x0 << 2) +#define DISP3DCNT__alpha_test__enable (0x1 << 2) +#define DISP3DCNT__toon_highlight__toon_shading (0x0 << 1) +#define DISP3DCNT__toon_highlight__highlight_shading (0x1 << 1) +#define DISP3DCNT__texture_mapping__disable (0x0 << 0) +#define DISP3DCNT__texture_mapping__enable (0x1 << 0) +#define MTX_MODE__matrix_mode__projection (0x0 << 0) +#define MTX_MODE__matrix_mode__position (0x1 << 0) +#define MTX_MODE__matrix_mode__position_and_vector (0x2 << 0) +#define MTX_MODE__matrix_mode__texture (0x3 << 0) +#define MTX_POP__number_of_pops(v) (((v) & 0x3f) << 0) +#define MTX_STORE__index(v) (((v) & 0x1f) << 0) +#define MTX_RESTORE__position(v) (((v) & 0x1f) << 0) +#define COLOR__blue(v) (((v) & 0x1f) << 10) +#define COLOR__green(v) (((v) & 0x1f) << 5) +#define COLOR__red(v) (((v) & 0x1f) << 0) +#define NORMAL__z_component(v) (((v) & 0x3ff) << 20) +#define NORMAL__y_component(v) (((v) & 0x3ff) << 10) +#define NORMAL__x_component(v) (((v) & 0x3ff) << 0) +#define TEXCOORD__t_coordinate(v) (((v) & 0xffff) << 16) +#define TEXCOORD__s_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_16__0__y_coordinate(v) (((v) & 0xffff) << 16) +#define VTX_16__0__x_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_16__1__z_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_10__z_coordinate(v) (((v) & 0x3ff) << 20) +#define VTX_10__y_coordinate(v) (((v) & 0x3ff) << 10) +#define VTX_10__x_coordinate(v) (((v) & 0x3ff) << 0) +#define VTX_XY__y_coordinate(v) (((v) & 0xffff) << 16) +#define VTX_XY__x_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_XZ__z_coordinate(v) (((v) & 0xffff) << 16) +#define VTX_XZ__x_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_YZ__z_coordinate(v) (((v) & 0xffff) << 16) +#define VTX_YZ__y_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_DIFF__z_coordinate(v) (((v) & 0x3ff) << 20) +#define VTX_DIFF__y_coordinate(v) (((v) & 0x3ff) << 10) +#define VTX_DIFF__x_coordinate(v) (((v) & 0x3ff) << 0) +#define POLYGON_ATTR__polygon_id(v) (((v) & 0x3f) << 24) +#define POLYGON_ATTR__alpha_value(v) (((v) & 0x1f) << 16) +#define POLYGON_ATTR__fog__disable (0x0 << 15) +#define POLYGON_ATTR__fog__enable (0x1 << 15) +#define POLYGON_ATTR__depth_test_condition__render_when_depth_value_is_smaller_than_buffer_value (0x0 << 14) +#define POLYGON_ATTR__depth_test_condition__render_when_depth_value_is_equal_to_buffer_value (0x1 << 14) +#define POLYGON_ATTR__one_dot_polygon__do_not_render (0x0 << 13) +#define POLYGON_ATTR__one_dot_polygon__render (0x1 << 13) +#define POLYGON_ATTR__far_plane_intersection__delete (0x0 << 12) +#define POLYGON_ATTR__far_plane_intersection__clip (0x1 << 12) +#define POLYGON_ATTR__translucent_depth_value_update__do_not_update (0x0 << 11) +#define POLYGON_ATTR__translucent_depth_value_update__update (0x1 << 11) +#define POLYGON_ATTR__render_front_surface__disable (0x0 << 7) +#define POLYGON_ATTR__render_front_surface__enable (0x1 << 7) +#define POLYGON_ATTR__render_back_surface__disable (0x0 << 6) +#define POLYGON_ATTR__render_back_surface__enable (0x1 << 6) +#define POLYGON_ATTR__polygon_mode__modulation (0x0 << 4) +#define POLYGON_ATTR__polygon_mode__decal (0x1 << 4) +#define POLYGON_ATTR__polygon_mode__toon (0x2 << 4) +#define POLYGON_ATTR__polygon_mode__shadow (0x3 << 4) +#define POLYGON_ATTR__light_3__disable (0x0 << 3) +#define POLYGON_ATTR__light_3__enable (0x1 << 3) +#define POLYGON_ATTR__light_2__disable (0x0 << 2) +#define POLYGON_ATTR__light_2__enable (0x1 << 2) +#define POLYGON_ATTR__light_1__disable (0x0 << 1) +#define POLYGON_ATTR__light_1__enable (0x1 << 1) +#define POLYGON_ATTR__light_0__disable (0x0 << 0) +#define POLYGON_ATTR__light_0__enable (0x1 << 0) +#define TEXIMAGE_PARAM__texture_coordinate_transformation_mode__do_not_transform_texture_coordinates (0x0 << 30) +#define TEXIMAGE_PARAM__texture_coordinate_transformation_mode__texcoord_source (0x1 << 30) +#define TEXIMAGE_PARAM__texture_coordinate_transformation_mode__normal_source (0x2 << 30) +#define TEXIMAGE_PARAM__texture_coordinate_transformation_mode__vertex_source (0x3 << 30) +#define TEXIMAGE_PARAM__palette_color0_transparency__palette_setting (0x0 << 29) +#define TEXIMAGE_PARAM__palette_color0_transparency__always_transparent (0x1 << 29) +#define TEXIMAGE_PARAM__texture_format__no_texture (0x0 << 26) +#define TEXIMAGE_PARAM__texture_format__a3i5_translucent (0x1 << 26) +#define TEXIMAGE_PARAM__texture_format__4_color_palette (0x2 << 26) +#define TEXIMAGE_PARAM__texture_format__16_color_palette (0x3 << 26) +#define TEXIMAGE_PARAM__texture_format__256_color_palette (0x4 << 26) +#define TEXIMAGE_PARAM__texture_format__4x4_texel_compressed (0x5 << 26) +#define TEXIMAGE_PARAM__texture_format__a5i3_translucent (0x6 << 26) +#define TEXIMAGE_PARAM__texture_format__direct (0x7 << 26) +#define TEXIMAGE_PARAM__t_size__8_texels (0x0 << 23) +#define TEXIMAGE_PARAM__t_size__16_texels (0x1 << 23) +#define TEXIMAGE_PARAM__t_size__32_texels (0x2 << 23) +#define TEXIMAGE_PARAM__t_size__64_texels (0x3 << 23) +#define TEXIMAGE_PARAM__t_size__128_texels (0x4 << 23) +#define TEXIMAGE_PARAM__t_size__256_texels (0x5 << 23) +#define TEXIMAGE_PARAM__t_size__512_texels (0x6 << 23) +#define TEXIMAGE_PARAM__t_size__1024_texels (0x7 << 23) +#define TEXIMAGE_PARAM__s_size__8_texels (0x0 << 20) +#define TEXIMAGE_PARAM__s_size__16_texels (0x1 << 20) +#define TEXIMAGE_PARAM__s_size__32_texels (0x2 << 20) +#define TEXIMAGE_PARAM__s_size__64_texels (0x3 << 20) +#define TEXIMAGE_PARAM__s_size__128_texels (0x4 << 20) +#define TEXIMAGE_PARAM__s_size__256_texels (0x5 << 20) +#define TEXIMAGE_PARAM__s_size__512_texels (0x6 << 20) +#define TEXIMAGE_PARAM__s_size__1024_texels (0x7 << 20) +#define TEXIMAGE_PARAM__flip_t__do_not_flip (0x0 << 19) +#define TEXIMAGE_PARAM__flip_t__flip (0x1 << 19) +#define TEXIMAGE_PARAM__flip_s__do_not_flip (0x0 << 18) +#define TEXIMAGE_PARAM__flip_s__flip (0x1 << 18) +#define TEXIMAGE_PARAM__repeat_t__do_not_repeat (0x0 << 17) +#define TEXIMAGE_PARAM__repeat_t__repeat (0x1 << 17) +#define TEXIMAGE_PARAM__repeat_s__do_not_repeat (0x0 << 16) +#define TEXIMAGE_PARAM__repeat_s__repeat (0x1 << 16) +#define TEXIMAGE_PARAM__texture_starting_address(v) (((v) & 0xffff) << 0) +#define TEXPLTT_BASE__base_address(v) (((v) & 0x1fff) << 0) +#define DIF_AMB__ambient_blue(v) (((v) & 0x1f) << 26) +#define DIF_AMB__ambient_green(v) (((v) & 0x1f) << 21) +#define DIF_AMB__ambient_red(v) (((v) & 0x1f) << 16) +#define DIF_AMB__vertex_color__do_not_set_vertex_color (0x0 << 15) +#define DIF_AMB__vertex_color__set_diffuse_reflection_color_as_vertex_color (0x1 << 15) +#define DIF_AMB__diffuse_blue(v) (((v) & 0x1f) << 10) +#define DIF_AMB__diffuse_green(v) (((v) & 0x1f) << 5) +#define DIF_AMB__diffuse_red(v) (((v) & 0x1f) << 0) +#define SPE_EMI__emission_blue(v) (((v) & 0x1f) << 26) +#define SPE_EMI__emission_green(v) (((v) & 0x1f) << 21) +#define SPE_EMI__emission_red(v) (((v) & 0x1f) << 16) +#define SPE_EMI__shininess__disable (0x0 << 15) +#define SPE_EMI__shininess__enable (0x1 << 15) +#define SPE_EMI__specular_blue(v) (((v) & 0x1f) << 10) +#define SPE_EMI__specular_green(v) (((v) & 0x1f) << 5) +#define SPE_EMI__specular_red(v) (((v) & 0x1f) << 0) +#define LIGHT_VECTOR__light_number(v) (((v) & 0x3) << 30) +#define LIGHT_VECTOR__decimal_z(v) (((v) & 0x3ff) << 20) +#define LIGHT_VECTOR__decimal_y(v) (((v) & 0x3ff) << 10) +#define LIGHT_VECTOR__decimal_x(v) (((v) & 0x3ff) << 0) +#define LIGHT_COLOR__light_number(v) (((v) & 0x3) << 30) +#define LIGHT_COLOR__blue(v) (((v) & 0x1f) << 10) +#define LIGHT_COLOR__green(v) (((v) & 0x1f) << 5) +#define LIGHT_COLOR__red(v) (((v) & 0x1f) << 0) +#define SHININESS__4x_3(v) (((v) & 0xff) << 24) +#define SHININESS__4x_2(v) (((v) & 0xff) << 16) +#define SHININESS__4x_1(v) (((v) & 0xff) << 8) +#define SHININESS__4x_0(v) (((v) & 0xff) << 0) +#define BEGIN_VTXS__type__triangle (0x0 << 0) +#define BEGIN_VTXS__type__quadrilateral (0x1 << 0) +#define BEGIN_VTXS__type__triangle_strip (0x2 << 0) +#define BEGIN_VTXS__type__quadrilateral_strip (0x3 << 0) +#define SWAP_BUFFERS__depth_buffering__z_value (0x0 << 1) +#define SWAP_BUFFERS__depth_buffering__w_value (0x1 << 1) +#define SWAP_BUFFERS__translucent_polygon_y_sorting__auto_sort (0x0 << 0) +#define SWAP_BUFFERS__translucent_polygon_y_sorting__manual_sort (0x1 << 0) +#define VIEWPORT__y2(v) (((v) & 0xff) << 24) +#define VIEWPORT__x2(v) (((v) & 0xff) << 16) +#define VIEWPORT__y1(v) (((v) & 0xff) << 8) +#define VIEWPORT__x1(v) (((v) & 0xff) << 0) +#define BOX_TEST__0__y_coordinate(v) (((v) & 0xffff) << 16) +#define BOX_TEST__0__x_coordinate(v) (((v) & 0xffff) << 0) +#define BOX_TEST__1__width(v) (((v) & 0xffff) << 16) +#define BOX_TEST__1__z_coordinate(v) (((v) & 0xffff) << 0) +#define BOX_TEST__2__depth(v) (((v) & 0xffff) << 16) +#define BOX_TEST__2__height(v) (((v) & 0xffff) << 0) +#define POS_TEST__0__y_coordinate(v) (((v) & 0xffff) << 16) +#define POS_TEST__0__x_coordinate(v) (((v) & 0xffff) << 0) +#define POS_TEST__1__z_coordinate(v) (((v) & 0xffff) << 0) +#define VEC_TEST__decimal_z(v) (((v) & 0x3ff) << 20) +#define VEC_TEST__decimal_y(v) (((v) & 0x3ff) << 10) +#define VEC_TEST__decimal_x(v) (((v) & 0x3ff) << 0) +#define GXSTAT__command_fifo_interrupt_condition__disable (0x0 << 30) +#define GXSTAT__command_fifo_interrupt_condition__half_full (0x1 << 30) +#define GXSTAT__command_fifo_interrupt_condition__empty (0x2 << 30) +#define GXSTAT__geometry_engine_busy (0x1 << 27) +#define GXSTAT__fifo_status__empty (0x1 << 26) +#define GXSTAT__fifo_status__less_than_half_full (0x1 << 25) +#define GXSTAT__fifo_status__full (0x1 << 24) +#define GXSTAT__command_fifo_count(v) (((v) >> 16) & 0xff) +#define GXSTAT__matrix_stack_status__overflow_or_underflow (0x1 << 15) +#define GXSTAT__matrix_stack_status__busy (0x1 << 14) +#define GXSTAT__matrix_stack_status__projection_stack_level(v) (((v) >> 13) & 0x1) +#define GXSTAT__matrix_stack_status__position_and_vector_stack_level(v) (((v) >> 8) & 0x1f) +#define GXSTAT__test_status (0x1 << 1) +#define GXSTAT__test_busy (0x1 << 0) +#define LISTRAM_COUNT__counter(v) (((v) >> 0) & 0xfff) +#define VTXRAM_COUNT__counter(v) (((v) >> 0) & 0x1fff) +#define OBJ_ATTRIBUTE_0__obj_shape__square (0x0 << 14) +#define OBJ_ATTRIBUTE_0__obj_shape__long_rectangle (0x1 << 14) +#define OBJ_ATTRIBUTE_0__obj_shape__tall_rectangle (0x2 << 14) +#define OBJ_ATTRIBUTE_0__color_mode__16_color_mode (0x0 << 13) +#define OBJ_ATTRIBUTE_0__color_mode__256_color_mode (0x1 << 13) +#define OBJ_ATTRIBUTE_0__mosaic__off (0x0 << 12) +#define OBJ_ATTRIBUTE_0__mosaic__on (0x1 << 12) +#define OBJ_ATTRIBUTE_0__obj_mode__normal (0x0 << 10) +#define OBJ_ATTRIBUTE_0__obj_mode__translucent (0x1 << 10) +#define OBJ_ATTRIBUTE_0__obj_mode__obj_window (0x2 << 10) +#define OBJ_ATTRIBUTE_0__obj_mode__bitmap_obj (0x3 << 10) +#define OBJ_ATTRIBUTE_0__double_size__disable (0x0 << 9) +#define OBJ_ATTRIBUTE_0__double_size__enable (0x1 << 9) +#define OBJ_ATTRIBUTE_0__affine_transformation__disable (0x0 << 8) +#define OBJ_ATTRIBUTE_0__affine_transformation__enable (0x1 << 8) +#define OBJ_ATTRIBUTE_0__y_coordinate(v) (((v) & 0xff) << 0) +#define OBJ_ATTRIBUTE_1__obj_size(v) (((v) & 0x3) << 14) +#define OBJ_ATTRIBUTE_1__affine_transformation_parameter(v) (((v) & 0x1f) << 9) +#define OBJ_ATTRIBUTE_1__x_coordinate(v) (((v) & 0x1ff) << 0) +#define OBJ_ATTRIBUTE_2__color_parameter(v) (((v) & 0xf) << 12) +#define OBJ_ATTRIBUTE_2__display_priority(v) (((v) & 0x3) << 10) +#define OBJ_ATTRIBUTE_2__character_name(v) (((v) & 0x3ff) << 0) diff --git a/include/graphics_engine_a.h b/include/graphics_engine_a.h new file mode 100644 index 0000000..2e7e70c --- /dev/null +++ b/include/graphics_engine_a.h @@ -0,0 +1,464 @@ +#pragma once + +#include +#include +#define static_assert _Static_assert + +struct graphics_engine_a { + volatile uint32_t DISPCNT; + volatile uint16_t DISPSTAT; + volatile uint16_t VCOUNT; + volatile uint16_t BG0CNT; + volatile uint16_t BG1CNT; + volatile uint16_t BG2CNT; + volatile uint16_t BG3CNT; + volatile uint16_t BG0HOFS; + volatile uint16_t BG0VOFS; + volatile uint16_t BG1HOFS; + volatile uint16_t BG1VOFS; + volatile uint16_t BG2HOFS; + volatile uint16_t BG2VOFS; + volatile uint16_t BG3HOFS; + volatile uint16_t BG3VOFS; + volatile uint16_t BG2PA; + volatile uint16_t BG2PB; + volatile uint16_t BG2PC; + volatile uint16_t BG2PD; + volatile uint32_t BG2X; + volatile uint32_t BG2Y; + volatile uint16_t BG3PA; + volatile uint16_t BG3PB; + volatile uint16_t BG3PC; + volatile uint16_t BG3PD; + volatile uint32_t BG3X; + volatile uint32_t BG3Y; + volatile uint16_t WIN0H; + volatile uint16_t WIN1H; + volatile uint16_t WIN0V; + volatile uint16_t WIN1V; + volatile uint16_t WININ; + volatile uint16_t WINOUT; + volatile uint16_t MOSAIC; + volatile uint8_t _pad0[2]; + volatile uint16_t BLDCNT; + volatile uint16_t BLDALPHA; + volatile uint16_t BLDY; + volatile uint8_t _pad1[10]; + volatile uint16_t DISP3DCNT; + volatile uint8_t _pad2[2]; + volatile uint32_t DISPCAPCNT; + volatile uint32_t DISP_MMEM_FIFO; + volatile uint16_t MASTER_BRIGHT; + volatile uint8_t _pad3[66]; + volatile uint32_t DMA0SAD; + volatile uint32_t DMA0DAD; + volatile uint32_t DMA0CNT; + volatile uint32_t DMA1SAD; + volatile uint32_t DMA1DAD; + volatile uint32_t DMA1CNT; + volatile uint32_t DMA2SAD; + volatile uint32_t DMA2DAD; + volatile uint32_t DMA2CNT; + volatile uint32_t DMA3SAD; + volatile uint32_t DMA3DAD; + volatile uint32_t DMA3CNT; + volatile uint8_t _pad4[32]; + volatile uint16_t TM0CNT_L; + volatile uint16_t TM0CNT_H; + volatile uint16_t TM1CNT_L; + volatile uint16_t TM1CNT_H; + volatile uint16_t TM2CNT_L; + volatile uint16_t TM2CNT_H; + volatile uint16_t TM3CNT_L; + volatile uint16_t TM3CNT_H; + volatile uint8_t _pad5[32]; + volatile uint16_t KEYINPUT; + volatile uint16_t KEYCNT; + volatile uint8_t _pad6[208]; + volatile uint16_t EXMEMCNT; + volatile uint8_t _pad7[2]; + volatile uint16_t IME; + volatile uint8_t _pad8[6]; + volatile uint32_t IE; + volatile uint32_t IF; + volatile uint8_t _pad9[40]; + volatile uint32_t VRAMCNT; + volatile uint32_t WVRAMCNT; + volatile uint16_t VRAM_HI_CNT; + volatile uint8_t _pad10[54]; + volatile uint16_t DIVCNT; + volatile uint8_t _pad11[14]; + volatile uint64_t DIV_NUMER; + volatile uint64_t DIV_DENOM; + volatile uint64_t DIV_RESULT; + volatile uint64_t DIVREM_RESULT; + volatile uint16_t SQRTCNT; + volatile uint8_t _pad12[2]; + volatile uint32_t SQRT_RESULT; + volatile uint64_t SQRT_PARAM; + volatile uint8_t _pad13[68]; + volatile uint16_t POWCNT; + volatile uint8_t _pad14[26]; + volatile uint16_t RDLINES_COUNT; + volatile uint8_t _pad15[14]; + volatile uint32_t EDGE_COLOR_0; + volatile uint32_t EDGE_COLOR_1; + volatile uint32_t EDGE_COLOR_2; + volatile uint32_t EDGE_COLOR_3; + volatile uint16_t ALPHA_TEST_REF; + volatile uint8_t _pad16[14]; + volatile uint32_t CLEAR_COLOR; + volatile uint16_t CLEAR_DEPTH; + volatile uint16_t CLRIMAGE_OFFSET; + volatile uint32_t FOG_COLOR; + volatile uint16_t FOG_OFFSET; + volatile uint8_t _pad17[2]; + volatile uint16_t FOG_TABLE_0_L; + volatile uint16_t FOG_TABLE_0_H; + volatile uint16_t FOG_TABLE_1_L; + volatile uint16_t FOG_TABLE_1_H; + volatile uint16_t FOG_TABLE_2_L; + volatile uint16_t FOG_TABLE_2_H; + volatile uint16_t FOG_TABLE_3_L; + volatile uint16_t FOG_TABLE_3_H; + volatile uint16_t FOG_TABLE_4_L; + volatile uint16_t FOG_TABLE_4_H; + volatile uint16_t FOG_TABLE_5_L; + volatile uint16_t FOG_TABLE_5_H; + volatile uint16_t FOG_TABLE_6_L; + volatile uint16_t FOG_TABLE_6_H; + volatile uint16_t FOG_TABLE_7_L; + volatile uint16_t FOG_TABLE_7_H; + volatile uint16_t TOON_TABLE_0_L; + volatile uint16_t TOON_TABLE_0_H; + volatile uint16_t TOON_TABLE_1_L; + volatile uint16_t TOON_TABLE_1_H; + volatile uint16_t TOON_TABLE_2_L; + volatile uint16_t TOON_TABLE_2_H; + volatile uint16_t TOON_TABLE_3_L; + volatile uint16_t TOON_TABLE_3_H; + volatile uint16_t TOON_TABLE_4_L; + volatile uint16_t TOON_TABLE_4_H; + volatile uint16_t TOON_TABLE_5_L; + volatile uint16_t TOON_TABLE_5_H; + volatile uint16_t TOON_TABLE_6_L; + volatile uint16_t TOON_TABLE_6_H; + volatile uint16_t TOON_TABLE_7_L; + volatile uint16_t TOON_TABLE_7_H; + volatile uint16_t TOON_TABLE_8_L; + volatile uint16_t TOON_TABLE_8_H; + volatile uint16_t TOON_TABLE_9_L; + volatile uint16_t TOON_TABLE_9_H; + volatile uint16_t TOON_TABLE_10_L; + volatile uint16_t TOON_TABLE_10_H; + volatile uint16_t TOON_TABLE_11_L; + volatile uint16_t TOON_TABLE_11_H; + volatile uint16_t TOON_TABLE_12_L; + volatile uint16_t TOON_TABLE_12_H; + volatile uint16_t TOON_TABLE_13_L; + volatile uint16_t TOON_TABLE_13_H; + volatile uint16_t TOON_TABLE_14_L; + volatile uint16_t TOON_TABLE_14_H; + volatile uint16_t TOON_TABLE_15_L; + volatile uint16_t TOON_TABLE_15_H; + volatile uint8_t _pad18[64]; + volatile uint32_t GXFIFO; + volatile uint8_t _pad19[60]; + volatile uint32_t MTX_MODE; + volatile uint32_t MTX_PUSH; + volatile uint32_t MTX_POP; + volatile uint32_t MTX_STORE; + volatile uint32_t MTX_RESTORE; + volatile uint32_t MTX_IDENTITY; + volatile uint32_t MTX_LOAD_4X4; + volatile uint32_t MTX_LOAD_4X3; + volatile uint32_t MTX_MULT_4X4; + volatile uint32_t MTX_MULT_4X3; + volatile uint32_t MTX_MULT_3X3; + volatile uint32_t MTX_SCALE; + volatile uint32_t MTX_TRANS; + volatile uint8_t _pad20[12]; + volatile uint32_t COLOR; + volatile uint32_t NORMAL; + volatile uint32_t TEXCOORD; + volatile uint32_t VTX_16; + volatile uint32_t VTX_10; + volatile uint32_t VTX_XY; + volatile uint32_t VTX_XZ; + volatile uint32_t VTX_YZ; + volatile uint32_t VTX_DIFF; + volatile uint32_t POLYGON_ATTR; + volatile uint32_t TEXIMAGE_PARAM; + volatile uint32_t TEXPLTT_BASE; + volatile uint8_t _pad21[16]; + volatile uint32_t DIF_AMB; + volatile uint32_t SPE_EMI; + volatile uint32_t LIGHT_VECTOR; + volatile uint32_t LIGHT_COLOR; + volatile uint32_t SHININESS; + volatile uint8_t _pad22[44]; + volatile uint32_t BEGIN_VTXS; + volatile uint32_t END_VTXS; + volatile uint8_t _pad23[56]; + volatile uint32_t SWAP_BUFFERS; + volatile uint8_t _pad24[60]; + volatile uint32_t VIEWPORT; + volatile uint8_t _pad25[60]; + volatile uint32_t BOX_TEST; + volatile uint32_t POS_TEST; + volatile uint32_t VEC_TEST; + volatile uint8_t _pad26[52]; + volatile uint32_t GXSTAT; + volatile uint16_t LISTRAM_COUNT; + volatile uint16_t VTXRAM_COUNT; + volatile uint8_t _pad27[8]; + volatile uint16_t DISP_1DOT_DEPTH; + volatile uint8_t _pad28[14]; + volatile uint32_t POS_RESULT_X; + volatile uint32_t POS_RESULT_Y; + volatile uint32_t POS_RESULT_Z; + volatile uint32_t POS_RESULT_W; + volatile uint16_t VEC_RESULT_X; + volatile uint16_t VEC_RESULT_Y; + volatile uint16_t VEC_RESULT_Z; + volatile uint8_t _pad29[10]; + volatile uint32_t CLIPMTX_RESULT_0; + volatile uint32_t CLIPMTX_RESULT_1; + volatile uint32_t CLIPMTX_RESULT_2; + volatile uint32_t CLIPMTX_RESULT_3; + volatile uint32_t CLIPMTX_RESULT_4; + volatile uint32_t CLIPMTX_RESULT_5; + volatile uint32_t CLIPMTX_RESULT_6; + volatile uint32_t CLIPMTX_RESULT_7; + volatile uint32_t CLIPMTX_RESULT_8; + volatile uint32_t CLIPMTX_RESULT_9; + volatile uint32_t CLIPMTX_RESULT_10; + volatile uint32_t CLIPMTX_RESULT_11; + volatile uint32_t CLIPMTX_RESULT_12; + volatile uint32_t CLIPMTX_RESULT_13; + volatile uint32_t CLIPMTX_RESULT_14; + volatile uint32_t CLIPMTX_RESULT_15; + volatile uint32_t VECMTX_RESULT_0; + volatile uint32_t VECMTX_RESULT_1; + volatile uint32_t VECMTX_RESULT_2; + volatile uint32_t VECMTX_RESULT_3; + volatile uint32_t VECMTX_RESULT_4; + volatile uint32_t VECMTX_RESULT_5; + volatile uint32_t VECMTX_RESULT_6; + volatile uint32_t VECMTX_RESULT_7; + volatile uint32_t VECMTX_RESULT_8; + volatile uint8_t _pad30[2396]; +}; +static_assert((offsetof (struct graphics_engine_a, DISPCNT)) == 0x000); +static_assert((offsetof (struct graphics_engine_a, DISPSTAT)) == 0x004); +static_assert((offsetof (struct graphics_engine_a, VCOUNT)) == 0x006); +static_assert((offsetof (struct graphics_engine_a, BG0CNT)) == 0x008); +static_assert((offsetof (struct graphics_engine_a, BG1CNT)) == 0x00a); +static_assert((offsetof (struct graphics_engine_a, BG2CNT)) == 0x00c); +static_assert((offsetof (struct graphics_engine_a, BG3CNT)) == 0x00e); +static_assert((offsetof (struct graphics_engine_a, BG0HOFS)) == 0x010); +static_assert((offsetof (struct graphics_engine_a, BG0VOFS)) == 0x012); +static_assert((offsetof (struct graphics_engine_a, BG1HOFS)) == 0x014); +static_assert((offsetof (struct graphics_engine_a, BG1VOFS)) == 0x016); +static_assert((offsetof (struct graphics_engine_a, BG2HOFS)) == 0x018); +static_assert((offsetof (struct graphics_engine_a, BG2VOFS)) == 0x01a); +static_assert((offsetof (struct graphics_engine_a, BG3HOFS)) == 0x01c); +static_assert((offsetof (struct graphics_engine_a, BG3VOFS)) == 0x01e); +static_assert((offsetof (struct graphics_engine_a, BG2PA)) == 0x020); +static_assert((offsetof (struct graphics_engine_a, BG2PB)) == 0x022); +static_assert((offsetof (struct graphics_engine_a, BG2PC)) == 0x024); +static_assert((offsetof (struct graphics_engine_a, BG2PD)) == 0x026); +static_assert((offsetof (struct graphics_engine_a, BG2X)) == 0x028); +static_assert((offsetof (struct graphics_engine_a, BG2Y)) == 0x02c); +static_assert((offsetof (struct graphics_engine_a, BG3PA)) == 0x030); +static_assert((offsetof (struct graphics_engine_a, BG3PB)) == 0x032); +static_assert((offsetof (struct graphics_engine_a, BG3PC)) == 0x034); +static_assert((offsetof (struct graphics_engine_a, BG3PD)) == 0x036); +static_assert((offsetof (struct graphics_engine_a, BG3X)) == 0x038); +static_assert((offsetof (struct graphics_engine_a, BG3Y)) == 0x03c); +static_assert((offsetof (struct graphics_engine_a, WIN0H)) == 0x040); +static_assert((offsetof (struct graphics_engine_a, WIN1H)) == 0x042); +static_assert((offsetof (struct graphics_engine_a, WIN0V)) == 0x044); +static_assert((offsetof (struct graphics_engine_a, WIN1V)) == 0x046); +static_assert((offsetof (struct graphics_engine_a, WININ)) == 0x048); +static_assert((offsetof (struct graphics_engine_a, WINOUT)) == 0x04a); +static_assert((offsetof (struct graphics_engine_a, MOSAIC)) == 0x04c); +static_assert((offsetof (struct graphics_engine_a, BLDCNT)) == 0x050); +static_assert((offsetof (struct graphics_engine_a, BLDALPHA)) == 0x052); +static_assert((offsetof (struct graphics_engine_a, BLDY)) == 0x054); +static_assert((offsetof (struct graphics_engine_a, DISP3DCNT)) == 0x060); +static_assert((offsetof (struct graphics_engine_a, DISPCAPCNT)) == 0x064); +static_assert((offsetof (struct graphics_engine_a, DISP_MMEM_FIFO)) == 0x068); +static_assert((offsetof (struct graphics_engine_a, MASTER_BRIGHT)) == 0x06c); +static_assert((offsetof (struct graphics_engine_a, DMA0SAD)) == 0x0b0); +static_assert((offsetof (struct graphics_engine_a, DMA0DAD)) == 0x0b4); +static_assert((offsetof (struct graphics_engine_a, DMA0CNT)) == 0x0b8); +static_assert((offsetof (struct graphics_engine_a, DMA1SAD)) == 0x0bc); +static_assert((offsetof (struct graphics_engine_a, DMA1DAD)) == 0x0c0); +static_assert((offsetof (struct graphics_engine_a, DMA1CNT)) == 0x0c4); +static_assert((offsetof (struct graphics_engine_a, DMA2SAD)) == 0x0c8); +static_assert((offsetof (struct graphics_engine_a, DMA2DAD)) == 0x0cc); +static_assert((offsetof (struct graphics_engine_a, DMA2CNT)) == 0x0d0); +static_assert((offsetof (struct graphics_engine_a, DMA3SAD)) == 0x0d4); +static_assert((offsetof (struct graphics_engine_a, DMA3DAD)) == 0x0d8); +static_assert((offsetof (struct graphics_engine_a, DMA3CNT)) == 0x0dc); +static_assert((offsetof (struct graphics_engine_a, TM0CNT_L)) == 0x100); +static_assert((offsetof (struct graphics_engine_a, TM0CNT_H)) == 0x102); +static_assert((offsetof (struct graphics_engine_a, TM1CNT_L)) == 0x104); +static_assert((offsetof (struct graphics_engine_a, TM1CNT_H)) == 0x106); +static_assert((offsetof (struct graphics_engine_a, TM2CNT_L)) == 0x108); +static_assert((offsetof (struct graphics_engine_a, TM2CNT_H)) == 0x10a); +static_assert((offsetof (struct graphics_engine_a, TM3CNT_L)) == 0x10c); +static_assert((offsetof (struct graphics_engine_a, TM3CNT_H)) == 0x10e); +static_assert((offsetof (struct graphics_engine_a, KEYINPUT)) == 0x130); +static_assert((offsetof (struct graphics_engine_a, KEYCNT)) == 0x132); +static_assert((offsetof (struct graphics_engine_a, EXMEMCNT)) == 0x204); +static_assert((offsetof (struct graphics_engine_a, IME)) == 0x208); +static_assert((offsetof (struct graphics_engine_a, IE)) == 0x210); +static_assert((offsetof (struct graphics_engine_a, IF)) == 0x214); +static_assert((offsetof (struct graphics_engine_a, VRAMCNT)) == 0x240); +static_assert((offsetof (struct graphics_engine_a, WVRAMCNT)) == 0x244); +static_assert((offsetof (struct graphics_engine_a, VRAM_HI_CNT)) == 0x248); +static_assert((offsetof (struct graphics_engine_a, DIVCNT)) == 0x280); +static_assert((offsetof (struct graphics_engine_a, DIV_NUMER)) == 0x290); +static_assert((offsetof (struct graphics_engine_a, DIV_DENOM)) == 0x298); +static_assert((offsetof (struct graphics_engine_a, DIV_RESULT)) == 0x2a0); +static_assert((offsetof (struct graphics_engine_a, DIVREM_RESULT)) == 0x2a8); +static_assert((offsetof (struct graphics_engine_a, SQRTCNT)) == 0x2b0); +static_assert((offsetof (struct graphics_engine_a, SQRT_RESULT)) == 0x2b4); +static_assert((offsetof (struct graphics_engine_a, SQRT_PARAM)) == 0x2b8); +static_assert((offsetof (struct graphics_engine_a, POWCNT)) == 0x304); +static_assert((offsetof (struct graphics_engine_a, RDLINES_COUNT)) == 0x320); +static_assert((offsetof (struct graphics_engine_a, EDGE_COLOR_0)) == 0x330); +static_assert((offsetof (struct graphics_engine_a, EDGE_COLOR_1)) == 0x334); +static_assert((offsetof (struct graphics_engine_a, EDGE_COLOR_2)) == 0x338); +static_assert((offsetof (struct graphics_engine_a, EDGE_COLOR_3)) == 0x33c); +static_assert((offsetof (struct graphics_engine_a, ALPHA_TEST_REF)) == 0x340); +static_assert((offsetof (struct graphics_engine_a, CLEAR_COLOR)) == 0x350); +static_assert((offsetof (struct graphics_engine_a, CLEAR_DEPTH)) == 0x354); +static_assert((offsetof (struct graphics_engine_a, CLRIMAGE_OFFSET)) == 0x356); +static_assert((offsetof (struct graphics_engine_a, FOG_COLOR)) == 0x358); +static_assert((offsetof (struct graphics_engine_a, FOG_OFFSET)) == 0x35c); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_0_L)) == 0x360); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_0_H)) == 0x362); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_1_L)) == 0x364); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_1_H)) == 0x366); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_2_L)) == 0x368); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_2_H)) == 0x36a); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_3_L)) == 0x36c); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_3_H)) == 0x36e); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_4_L)) == 0x370); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_4_H)) == 0x372); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_5_L)) == 0x374); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_5_H)) == 0x376); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_6_L)) == 0x378); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_6_H)) == 0x37a); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_7_L)) == 0x37c); +static_assert((offsetof (struct graphics_engine_a, FOG_TABLE_7_H)) == 0x37e); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_0_L)) == 0x380); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_0_H)) == 0x382); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_1_L)) == 0x384); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_1_H)) == 0x386); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_2_L)) == 0x388); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_2_H)) == 0x38a); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_3_L)) == 0x38c); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_3_H)) == 0x38e); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_4_L)) == 0x390); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_4_H)) == 0x392); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_5_L)) == 0x394); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_5_H)) == 0x396); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_6_L)) == 0x398); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_6_H)) == 0x39a); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_7_L)) == 0x39c); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_7_H)) == 0x39e); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_8_L)) == 0x3a0); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_8_H)) == 0x3a2); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_9_L)) == 0x3a4); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_9_H)) == 0x3a6); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_10_L)) == 0x3a8); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_10_H)) == 0x3aa); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_11_L)) == 0x3ac); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_11_H)) == 0x3ae); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_12_L)) == 0x3b0); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_12_H)) == 0x3b2); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_13_L)) == 0x3b4); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_13_H)) == 0x3b6); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_14_L)) == 0x3b8); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_14_H)) == 0x3ba); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_15_L)) == 0x3bc); +static_assert((offsetof (struct graphics_engine_a, TOON_TABLE_15_H)) == 0x3be); +static_assert((offsetof (struct graphics_engine_a, GXFIFO)) == 0x400); +static_assert((offsetof (struct graphics_engine_a, MTX_MODE)) == 0x440); +static_assert((offsetof (struct graphics_engine_a, MTX_PUSH)) == 0x444); +static_assert((offsetof (struct graphics_engine_a, MTX_POP)) == 0x448); +static_assert((offsetof (struct graphics_engine_a, MTX_STORE)) == 0x44c); +static_assert((offsetof (struct graphics_engine_a, MTX_RESTORE)) == 0x450); +static_assert((offsetof (struct graphics_engine_a, MTX_IDENTITY)) == 0x454); +static_assert((offsetof (struct graphics_engine_a, MTX_LOAD_4X4)) == 0x458); +static_assert((offsetof (struct graphics_engine_a, MTX_LOAD_4X3)) == 0x45c); +static_assert((offsetof (struct graphics_engine_a, MTX_MULT_4X4)) == 0x460); +static_assert((offsetof (struct graphics_engine_a, MTX_MULT_4X3)) == 0x464); +static_assert((offsetof (struct graphics_engine_a, MTX_MULT_3X3)) == 0x468); +static_assert((offsetof (struct graphics_engine_a, MTX_SCALE)) == 0x46c); +static_assert((offsetof (struct graphics_engine_a, MTX_TRANS)) == 0x470); +static_assert((offsetof (struct graphics_engine_a, COLOR)) == 0x480); +static_assert((offsetof (struct graphics_engine_a, NORMAL)) == 0x484); +static_assert((offsetof (struct graphics_engine_a, TEXCOORD)) == 0x488); +static_assert((offsetof (struct graphics_engine_a, VTX_16)) == 0x48c); +static_assert((offsetof (struct graphics_engine_a, VTX_10)) == 0x490); +static_assert((offsetof (struct graphics_engine_a, VTX_XY)) == 0x494); +static_assert((offsetof (struct graphics_engine_a, VTX_XZ)) == 0x498); +static_assert((offsetof (struct graphics_engine_a, VTX_YZ)) == 0x49c); +static_assert((offsetof (struct graphics_engine_a, VTX_DIFF)) == 0x4a0); +static_assert((offsetof (struct graphics_engine_a, POLYGON_ATTR)) == 0x4a4); +static_assert((offsetof (struct graphics_engine_a, TEXIMAGE_PARAM)) == 0x4a8); +static_assert((offsetof (struct graphics_engine_a, TEXPLTT_BASE)) == 0x4ac); +static_assert((offsetof (struct graphics_engine_a, DIF_AMB)) == 0x4c0); +static_assert((offsetof (struct graphics_engine_a, SPE_EMI)) == 0x4c4); +static_assert((offsetof (struct graphics_engine_a, LIGHT_VECTOR)) == 0x4c8); +static_assert((offsetof (struct graphics_engine_a, LIGHT_COLOR)) == 0x4cc); +static_assert((offsetof (struct graphics_engine_a, SHININESS)) == 0x4d0); +static_assert((offsetof (struct graphics_engine_a, BEGIN_VTXS)) == 0x500); +static_assert((offsetof (struct graphics_engine_a, END_VTXS)) == 0x504); +static_assert((offsetof (struct graphics_engine_a, SWAP_BUFFERS)) == 0x540); +static_assert((offsetof (struct graphics_engine_a, VIEWPORT)) == 0x580); +static_assert((offsetof (struct graphics_engine_a, BOX_TEST)) == 0x5c0); +static_assert((offsetof (struct graphics_engine_a, POS_TEST)) == 0x5c4); +static_assert((offsetof (struct graphics_engine_a, VEC_TEST)) == 0x5c8); +static_assert((offsetof (struct graphics_engine_a, GXSTAT)) == 0x600); +static_assert((offsetof (struct graphics_engine_a, LISTRAM_COUNT)) == 0x604); +static_assert((offsetof (struct graphics_engine_a, VTXRAM_COUNT)) == 0x606); +static_assert((offsetof (struct graphics_engine_a, DISP_1DOT_DEPTH)) == 0x610); +static_assert((offsetof (struct graphics_engine_a, POS_RESULT_X)) == 0x620); +static_assert((offsetof (struct graphics_engine_a, POS_RESULT_Y)) == 0x624); +static_assert((offsetof (struct graphics_engine_a, POS_RESULT_Z)) == 0x628); +static_assert((offsetof (struct graphics_engine_a, POS_RESULT_W)) == 0x62c); +static_assert((offsetof (struct graphics_engine_a, VEC_RESULT_X)) == 0x630); +static_assert((offsetof (struct graphics_engine_a, VEC_RESULT_Y)) == 0x632); +static_assert((offsetof (struct graphics_engine_a, VEC_RESULT_Z)) == 0x634); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_0)) == 0x640); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_1)) == 0x644); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_2)) == 0x648); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_3)) == 0x64c); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_4)) == 0x650); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_5)) == 0x654); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_6)) == 0x658); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_7)) == 0x65c); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_8)) == 0x660); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_9)) == 0x664); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_10)) == 0x668); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_11)) == 0x66c); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_12)) == 0x670); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_13)) == 0x674); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_14)) == 0x678); +static_assert((offsetof (struct graphics_engine_a, CLIPMTX_RESULT_15)) == 0x67c); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_0)) == 0x680); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_1)) == 0x684); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_2)) == 0x688); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_3)) == 0x68c); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_4)) == 0x690); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_5)) == 0x694); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_6)) == 0x698); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_7)) == 0x69c); +static_assert((offsetof (struct graphics_engine_a, VECMTX_RESULT_8)) == 0x6a0); +static_assert((sizeof (struct graphics_engine_a)) == 0x1000); diff --git a/include/graphics_engine_b.h b/include/graphics_engine_b.h new file mode 100644 index 0000000..471550d --- /dev/null +++ b/include/graphics_engine_b.h @@ -0,0 +1,85 @@ +#pragma once + +#include +#include +#define static_assert _Static_assert + +struct graphics_engine_b { + volatile uint32_t DISPCNT; + volatile uint8_t _pad0[4]; + volatile uint16_t BG0CNT; + volatile uint16_t BG1CNT; + volatile uint16_t BG2CNT; + volatile uint16_t BG3CNT; + volatile uint16_t BG0HOFS; + volatile uint16_t BG0VOFS; + volatile uint16_t BG1HOFS; + volatile uint16_t BG1VOFS; + volatile uint16_t BG2HOFS; + volatile uint16_t BG2VOFS; + volatile uint16_t BG3HOFS; + volatile uint16_t BG3VOFS; + volatile uint16_t BG2PA; + volatile uint16_t BG2PB; + volatile uint16_t BG2PC; + volatile uint16_t BG2PD; + volatile uint32_t BG2X; + volatile uint32_t BG2Y; + volatile uint16_t BG3PA; + volatile uint16_t BG3PB; + volatile uint16_t BG3PC; + volatile uint16_t BG3PD; + volatile uint32_t BG3X; + volatile uint32_t BG3Y; + volatile uint16_t WIN0H; + volatile uint16_t WIN1H; + volatile uint16_t WIN0V; + volatile uint16_t WIN1V; + volatile uint16_t WININ; + volatile uint16_t WINOUT; + volatile uint16_t MOSAIC; + volatile uint8_t _pad1[2]; + volatile uint16_t BLDCNT; + volatile uint16_t BLDALPHA; + volatile uint16_t BLDY; + volatile uint8_t _pad2[22]; + volatile uint16_t MASTER_BRIGHT; + volatile uint8_t _pad3[2]; +}; +static_assert((offsetof (struct graphics_engine_b, DISPCNT)) == 0x000); +static_assert((offsetof (struct graphics_engine_b, BG0CNT)) == 0x008); +static_assert((offsetof (struct graphics_engine_b, BG1CNT)) == 0x00a); +static_assert((offsetof (struct graphics_engine_b, BG2CNT)) == 0x00c); +static_assert((offsetof (struct graphics_engine_b, BG3CNT)) == 0x00e); +static_assert((offsetof (struct graphics_engine_b, BG0HOFS)) == 0x010); +static_assert((offsetof (struct graphics_engine_b, BG0VOFS)) == 0x012); +static_assert((offsetof (struct graphics_engine_b, BG1HOFS)) == 0x014); +static_assert((offsetof (struct graphics_engine_b, BG1VOFS)) == 0x016); +static_assert((offsetof (struct graphics_engine_b, BG2HOFS)) == 0x018); +static_assert((offsetof (struct graphics_engine_b, BG2VOFS)) == 0x01a); +static_assert((offsetof (struct graphics_engine_b, BG3HOFS)) == 0x01c); +static_assert((offsetof (struct graphics_engine_b, BG3VOFS)) == 0x01e); +static_assert((offsetof (struct graphics_engine_b, BG2PA)) == 0x020); +static_assert((offsetof (struct graphics_engine_b, BG2PB)) == 0x022); +static_assert((offsetof (struct graphics_engine_b, BG2PC)) == 0x024); +static_assert((offsetof (struct graphics_engine_b, BG2PD)) == 0x026); +static_assert((offsetof (struct graphics_engine_b, BG2X)) == 0x028); +static_assert((offsetof (struct graphics_engine_b, BG2Y)) == 0x02c); +static_assert((offsetof (struct graphics_engine_b, BG3PA)) == 0x030); +static_assert((offsetof (struct graphics_engine_b, BG3PB)) == 0x032); +static_assert((offsetof (struct graphics_engine_b, BG3PC)) == 0x034); +static_assert((offsetof (struct graphics_engine_b, BG3PD)) == 0x036); +static_assert((offsetof (struct graphics_engine_b, BG3X)) == 0x038); +static_assert((offsetof (struct graphics_engine_b, BG3Y)) == 0x03c); +static_assert((offsetof (struct graphics_engine_b, WIN0H)) == 0x040); +static_assert((offsetof (struct graphics_engine_b, WIN1H)) == 0x042); +static_assert((offsetof (struct graphics_engine_b, WIN0V)) == 0x044); +static_assert((offsetof (struct graphics_engine_b, WIN1V)) == 0x046); +static_assert((offsetof (struct graphics_engine_b, WININ)) == 0x048); +static_assert((offsetof (struct graphics_engine_b, WINOUT)) == 0x04a); +static_assert((offsetof (struct graphics_engine_b, MOSAIC)) == 0x04c); +static_assert((offsetof (struct graphics_engine_b, BLDCNT)) == 0x050); +static_assert((offsetof (struct graphics_engine_b, BLDALPHA)) == 0x052); +static_assert((offsetof (struct graphics_engine_b, BLDY)) == 0x054); +static_assert((offsetof (struct graphics_engine_b, MASTER_BRIGHT)) == 0x06c); +static_assert((sizeof (struct graphics_engine_b)) == 0x70); diff --git a/include/io_registers.h b/include/io_registers.h new file mode 100644 index 0000000..e527cd2 --- /dev/null +++ b/include/io_registers.h @@ -0,0 +1,11 @@ +#pragma once + +#include "graphics_engine_a.h" +#include "graphics_engine_b.h" + +struct io_registers { + struct graphics_engine_a a; + struct graphics_engine_b b; +}; + +extern struct io_registers io_registers __asm("io_registers"); diff --git a/include/oam.h b/include/oam.h new file mode 100644 index 0000000..9511782 --- /dev/null +++ b/include/oam.h @@ -0,0 +1,37 @@ +#include +#include + +#define static_assert _Static_assert + +struct oam_obj { + volatile uint16_t attr[3]; + volatile uint16_t _0; +}; +static_assert((sizeof (struct oam_obj)) == 8); + +struct oam_param { + volatile uint16_t _0[3]; + volatile uint16_t pa; + volatile uint16_t _1[3]; + volatile uint16_t pb; + volatile uint16_t _2[3]; + volatile uint16_t pc; + volatile uint16_t _3[3]; + volatile uint16_t pd; +}; +static_assert((sizeof (struct oam_param)) == 32); + +union oam { + struct oam_obj obj[128]; + struct oam_param param[32]; +}; +static_assert((sizeof (union oam)) == 0x400); + +struct oam_a_b { + union oam a; + union oam b; +}; +static_assert((offsetof (struct oam_a_b, a)) == 0x000); +static_assert((offsetof (struct oam_a_b, b)) == 0x400); + +extern struct oam_a_b oam __asm("oam"); diff --git a/include/obj.h b/include/obj.h new file mode 100644 index 0000000..f74e8c1 --- /dev/null +++ b/include/obj.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +#define static_assert _Static_assert + +union obj_character { + uint8_t u8[32 / 1]; + uint16_t u16[32 / 2]; + uint32_t u32[32 / 4]; +}; +static_assert((sizeof (union obj_character)) == 32); + +union obj { + union obj_character character[1024]; + union { + uint8_t u8[0x8000 / 1]; + uint16_t u16[0x8000 / 2]; + uint32_t u32[0x8000 / 4]; + }; +}; +static_assert((sizeof (union obj)) == 0x8000); + +struct obj_vram { + union obj a; + uint8_t _pad[0x200000 - (sizeof (union obj))]; + union obj b; +}; +static_assert((offsetof (struct obj_vram, a)) == 0); +static_assert((offsetof (struct obj_vram, b)) == 0x200000); + +extern struct obj_vram obj_vram __asm("obj_vram"); diff --git a/include/palette.h b/include/palette.h new file mode 100644 index 0000000..a1ed7dd --- /dev/null +++ b/include/palette.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#define static_assert _Static_assert + +struct color16 { + uint16_t color[16]; +}; +static_assert((sizeof (struct color16)) == 0x20); + +union palette { + struct color16 palette[16]; + uint16_t color[256]; +}; +static_assert((sizeof (union palette)) == 0x200); + +struct palette_bg_obj { + union palette bg; + union palette obj; +}; +static_assert((sizeof (struct palette_bg_obj)) == 0x400); + +struct palette_a_b { + struct palette_bg_obj a; + struct palette_bg_obj b; +}; +static_assert((sizeof (struct palette_a_b)) == 0x800); + +extern struct palette_a_b palette_ram __asm("palette_ram"); diff --git a/logo.s b/logo.s new file mode 100644 index 0000000..8875450 --- /dev/null +++ b/logo.s @@ -0,0 +1,20 @@ + .byte 0x24, 0xff, 0xae, 0x51, 0x69, 0x9a, 0xa2, 0x21 + .byte 0x3d, 0x84, 0x82, 0x0a, 0x84, 0xe4, 0x09, 0xad + .byte 0x11, 0x24, 0x8b, 0x98, 0xc0, 0x81, 0x7f, 0x21 + .byte 0xa3, 0x52, 0xbe, 0x19, 0x93, 0x09, 0xce, 0x20 + .byte 0x10, 0x46, 0x4a, 0x4a, 0xf8, 0x27, 0x31, 0xec + .byte 0x58, 0xc7, 0xe8, 0x33, 0x82, 0xe3, 0xce, 0xbf + .byte 0x85, 0xf4, 0xdf, 0x94, 0xce, 0x4b, 0x09, 0xc1 + .byte 0x94, 0x56, 0x8a, 0xc0, 0x13, 0x72, 0xa7, 0xfc + .byte 0x9f, 0x84, 0x4d, 0x73, 0xa3, 0xca, 0x9a, 0x61 + .byte 0x58, 0x97, 0xa3, 0x27, 0xfc, 0x03, 0x98, 0x76 + .byte 0x23, 0x1d, 0xc7, 0x61, 0x03, 0x04, 0xae, 0x56 + .byte 0xbf, 0x38, 0x84, 0x00, 0x40, 0xa7, 0x0e, 0xfd + .byte 0xff, 0x52, 0xfe, 0x03, 0x6f, 0x95, 0x30, 0xf1 + .byte 0x97, 0xfb, 0xc0, 0x85, 0x60, 0xd6, 0x80, 0x25 + .byte 0xa9, 0x63, 0xbe, 0x03, 0x01, 0x4e, 0x38, 0xe2 + .byte 0xf9, 0xa2, 0x34, 0xff, 0xbb, 0x3e, 0x03, 0x44 + .byte 0x78, 0x00, 0x90, 0xcb, 0x88, 0x11, 0x3a, 0x94 + .byte 0x65, 0xc0, 0x7c, 0x63, 0x87, 0xf0, 0x3c, 0xaf + .byte 0xd6, 0x25, 0xe4, 0x8b, 0x38, 0x0a, 0xac, 0x72 + .byte 0x21, 0xd4, 0xf8, 0x07 diff --git a/patch.py b/patch.py new file mode 100644 index 0000000..7d29eb7 --- /dev/null +++ b/patch.py @@ -0,0 +1,68 @@ +def crc16_modbus(b: bytes) -> int: + crc = 0xFFFF + for n in range(len(b)): + crc ^= b[n] + for i in range(8): + if crc & 1: + crc >>= 1 + crc ^= 0xA001 + else: + crc >>= 1 + return crc + +logo = [ + 0x24, 0xff, 0xae, 0x51, 0x69, 0x9a, 0xa2, 0x21, + 0x3d, 0x84, 0x82, 0x0a, 0x84, 0xe4, 0x09, 0xad, + 0x11, 0x24, 0x8b, 0x98, 0xc0, 0x81, 0x7f, 0x21, + 0xa3, 0x52, 0xbe, 0x19, 0x93, 0x09, 0xce, 0x20, + 0x10, 0x46, 0x4a, 0x4a, 0xf8, 0x27, 0x31, 0xec, + 0x58, 0xc7, 0xe8, 0x33, 0x82, 0xe3, 0xce, 0xbf, + 0x85, 0xf4, 0xdf, 0x94, 0xce, 0x4b, 0x09, 0xc1, + 0x94, 0x56, 0x8a, 0xc0, 0x13, 0x72, 0xa7, 0xfc, + 0x9f, 0x84, 0x4d, 0x73, 0xa3, 0xca, 0x9a, 0x61, + 0x58, 0x97, 0xa3, 0x27, 0xfc, 0x03, 0x98, 0x76, + 0x23, 0x1d, 0xc7, 0x61, 0x03, 0x04, 0xae, 0x56, + 0xbf, 0x38, 0x84, 0x00, 0x40, 0xa7, 0x0e, 0xfd, + 0xff, 0x52, 0xfe, 0x03, 0x6f, 0x95, 0x30, 0xf1, + 0x97, 0xfb, 0xc0, 0x85, 0x60, 0xd6, 0x80, 0x25, + 0xa9, 0x63, 0xbe, 0x03, 0x01, 0x4e, 0x38, 0xe2, + 0xf9, 0xa2, 0x34, 0xff, 0xbb, 0x3e, 0x03, 0x44, + 0x78, 0x00, 0x90, 0xcb, 0x88, 0x11, 0x3a, 0x94, + 0x65, 0xc0, 0x7c, 0x63, 0x87, 0xf0, 0x3c, 0xaf, + 0xd6, 0x25, 0xe4, 0x8b, 0x38, 0x0a, 0xac, 0x72, + 0x21, 0xd4, 0xf8, 0x07, +] +logo_b = bytes(logo) +assert crc16_modbus(logo_b) == 0xcf56 + +import struct +import sys +with open(sys.argv[1], 'rb') as f: + buf = bytearray(f.read()) + +#assert buf[0x15c] == 0x56 +#assert buf[0x15d] == 0xcf + +logo_crc = crc16_modbus(buf[0x0c0:0x15b+1]) +print("logo", hex(logo_crc)) +if logo_crc != 0xcf56: + for i, e in enumerate(logo): + print(i, e, hex (0xc0+i)) + buf[0x0c0 + i] = e + logo_crc = crc16_modbus(buf[0x0c0:0x15b+1]) + print("logo2", hex(logo_crc)) + +secure_area_crc = crc16_modbus(buf[0x4000:0x8000]) +print("secure area", hex(secure_area_crc)) +secure_area_crc_b = struct.pack(' + +#include "math.h" + +extern const uint16_t cos_table_fp12[]; + +int cos_fp12(int theta) +{ + theta = abs(theta); + while (theta > 360) { + theta -= 360; + } + + if (theta <= 90) { + return cos_table_fp12[theta]; + } else if (theta <= 180) { + return - cos_table_fp12[180 - theta]; + } else if (theta <= 270) { + return - cos_table_fp12[theta - 180]; + } else { + return cos_table_fp12[360 - theta]; + } +} diff --git a/template/src/arm9/cos_table_fp12.c b/template/src/arm9/cos_table_fp12.c new file mode 100644 index 0000000..11d2352 --- /dev/null +++ b/template/src/arm9/cos_table_fp12.c @@ -0,0 +1,95 @@ +#include + +const uint16_t cos_table_fp12[91] = { + 4096, + 4095, + 4094, + 4090, + 4086, + 4080, + 4074, + 4065, + 4056, + 4046, + 4034, + 4021, + 4006, + 3991, + 3974, + 3956, + 3937, + 3917, + 3896, + 3873, + 3849, + 3824, + 3798, + 3770, + 3742, + 3712, + 3681, + 3650, + 3617, + 3582, + 3547, + 3511, + 3474, + 3435, + 3396, + 3355, + 3314, + 3271, + 3228, + 3183, + 3138, + 3091, + 3044, + 2996, + 2946, + 2896, + 2845, + 2793, + 2741, + 2687, + 2633, + 2578, + 2522, + 2465, + 2408, + 2349, + 2290, + 2231, + 2171, + 2110, + 2048, + 1986, + 1923, + 1860, + 1796, + 1731, + 1666, + 1600, + 1534, + 1468, + 1401, + 1334, + 1266, + 1198, + 1129, + 1060, + 991, + 921, + 852, + 782, + 711, + 641, + 570, + 499, + 428, + 357, + 286, + 214, + 143, + 71, + 0 +}; diff --git a/template/src/arm9/cube.c b/template/src/arm9/cube.c new file mode 100644 index 0000000..03cebdd --- /dev/null +++ b/template/src/arm9/cube.c @@ -0,0 +1,210 @@ +#include "io_registers.h" +#include "bits.h" + +#include "cube.h" +#include "math.h" + +static const uint16_t face_colors[6] = { + COLOR__blue(31), + COLOR__red(31), + COLOR__green(31), + COLOR__red(31) | COLOR__green(31), + COLOR__red(31) | COLOR__blue(31), + COLOR__green(31) | COLOR__blue(31), +}; + +void main() +{ + // power control + io_registers.a.POWCNT = 0 + | POWCNT__lcd_output_destination__a_to_upper__b_to_lower + | POWCNT__geometry_engine__enable + | POWCNT__rendering_engine__enable + | POWCNT__lcd__enable; + + // enable bg0 and 3d graphics + io_registers.a.DISPCNT = 0 + | DISPCNT__display_mode__graphics_display + | DISPCNT__bg0__enable + | DISPCNT__display_selection_for_bg0__3d_graphics + ; + + // disable all 3d effects + io_registers.a.DISP3DCNT = 0 + | DISP3DCNT__clear_image__disable + | DISP3DCNT__fog_master__disable + | DISP3DCNT__edge_marking__disable + | DISP3DCNT__anti_aliasing__disable + | DISP3DCNT__alpha_blending__disable + | DISP3DCNT__alpha_test__disable + | DISP3DCNT__texture_mapping__disable; + + // clear matrix stack status + io_registers.a.GXSTAT |= GXSTAT__matrix_stack_status__overflow_or_underflow; + + // load identity matrices + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__projection; + io_registers.a.MTX_IDENTITY = 0; + + // load a symmetric perspective matrix, with aspect ratio correction + io_registers.a.MTX_LOAD_4X4 = (192 << 12) / 256; + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 0; + + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 1 << 12; + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 0; + + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = -(1 << 12); + + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = 0; + io_registers.a.MTX_LOAD_4X4 = -(1 << 12); + io_registers.a.MTX_LOAD_4X4 = 0; + + // translate the viewpoint + io_registers.a.MTX_TRANS = 0; + io_registers.a.MTX_TRANS = 0; + io_registers.a.MTX_TRANS = -3 << 12; + + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__position; + io_registers.a.MTX_IDENTITY = 0; + + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__position_and_vector; + io_registers.a.MTX_IDENTITY = 0; + + // set the 3d clear color to a dark red + io_registers.a.CLEAR_COLOR = 0 + | CLEAR_COLOR__clear_polygon_id(31) + | CLEAR_COLOR__alpha_value(31) + | CLEAR_COLOR__blue(1) + | CLEAR_COLOR__green(1) + | CLEAR_COLOR__red(10); + + // set the depth buffer clear value to the maximum value + io_registers.a.CLEAR_DEPTH = CLEAR_DEPTH__value(0x7fff); + + // the following polygons are fully opaque; backface culling is + // enabled + io_registers.a.POLYGON_ATTR = 0 + | POLYGON_ATTR__alpha_value(31) + | POLYGON_ATTR__render_front_surface__enable; + + // the 3d viewport is the entire display area + io_registers.a.VIEWPORT = 0 + | VIEWPORT__y2(191) + | VIEWPORT__x2(255) + | VIEWPORT__y1(0) + | VIEWPORT__x1(0); + + // degrees + int theta = 0; + + while (1) { + // calculate sin/cos for 2d rotation; signed fp20.12 result + int cos = cos_fp12(theta); + int sin = sin_fp12(theta); + + int cos2 = cos_fp12(theta >> 1); + int sin2 = sin_fp12(theta >> 1); + + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__position; + // reset position matrix + io_registers.a.MTX_IDENTITY = 0; + + // multiply by a z-axis rotation + io_registers.a.MTX_MULT_3X3 = cos; + io_registers.a.MTX_MULT_3X3 = -sin; + io_registers.a.MTX_MULT_3X3 = 0; + + io_registers.a.MTX_MULT_3X3 = sin; + io_registers.a.MTX_MULT_3X3 = cos; + io_registers.a.MTX_MULT_3X3 = 0; + + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = 1 << 12; + + // multiply by a y-axis rotation + io_registers.a.MTX_MULT_3X3 = cos2; + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = sin2; + + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = 1 << 12; + io_registers.a.MTX_MULT_3X3 = 0; + + io_registers.a.MTX_MULT_3X3 = -sin2; + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = cos2; + + // multiply by a x-axis rotation + io_registers.a.MTX_MULT_3X3 = cos2; + io_registers.a.MTX_MULT_3X3 = -sin2; + io_registers.a.MTX_MULT_3X3 = 0; + + io_registers.a.MTX_MULT_3X3 = sin2; + io_registers.a.MTX_MULT_3X3 = cos2; + io_registers.a.MTX_MULT_3X3 = 0; + + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = 0; + io_registers.a.MTX_MULT_3X3 = 1 << 12; + + // the following vertices are a quadrilateral + io_registers.a.BEGIN_VTXS = BEGIN_VTXS__type__quadrilateral; + + // cube faces + for (int i = 0; i < 6; i++) { + io_registers.a.COLOR = face_colors[i]; + + struct vertex_position * a = &cube_positions[cube_quadrilaterals[i].a.position]; + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(a->z) + | VTX_10__y_coordinate(a->y) + | VTX_10__x_coordinate(a->x); + + struct vertex_position * b = &cube_positions[cube_quadrilaterals[i].b.position]; + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(b->z) + | VTX_10__y_coordinate(b->y) + | VTX_10__x_coordinate(b->x); + + struct vertex_position * c = &cube_positions[cube_quadrilaterals[i].c.position]; + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(c->z) + | VTX_10__y_coordinate(c->y) + | VTX_10__x_coordinate(c->x); + + struct vertex_position * d = &cube_positions[cube_quadrilaterals[i].d.position]; + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(d->z) + | VTX_10__y_coordinate(d->y) + | VTX_10__x_coordinate(d->x); + } + + // end of the quadrilateral + io_registers.a.END_VTXS = 0; + + // wait for the end of the current frame + while (io_registers.a.VCOUNT != 262); + while (io_registers.a.VCOUNT == 262); + + // wait for the geometry engine + while (io_registers.a.GXSTAT & GXSTAT__geometry_engine_busy); + + // swap buffers + io_registers.a.SWAP_BUFFERS = 0; + + // increment theta once per frame + theta += 1; + if (theta >= 360 * 2) { + theta = 0; + } + } +} diff --git a/template/src/arm9/cube.h b/template/src/arm9/cube.h new file mode 100644 index 0000000..7e0a4b0 --- /dev/null +++ b/template/src/arm9/cube.h @@ -0,0 +1,71 @@ +#include "model.h" + +// .6 fixed-point +struct vertex_position cube_positions[] = { + {64, 64, -64}, + {64, -64, -64}, + {64, 64, 64}, + {64, -64, 64}, + {-64, 64, -64}, + {-64, -64, -64}, + {-64, 64, 64}, + {-64, -64, 64}, +}; + +// .15 fixed-point +struct vertex_texture cube_textures[] = { + {32768, 32768}, + {0, 32768}, + {0, 0}, + {32768, 0}, +}; + +// .9 fixed-point +struct vertex_normal cube_normals[] = { + {0, 512, 0}, + {0, 0, 512}, + {-512, 0, 0}, + {0, -512, 0}, + {512, 0, 0}, + {0, 0, -512}, +}; + +union quadrilateral cube_quadrilaterals[] = { + { .v = { + {0, 0, 0}, + {4, 1, 0}, + {6, 2, 0}, + {2, 3, 0}, + }}, + { .v = { + {3, 3, 1}, + {2, 0, 1}, + {6, 1, 1}, + {7, 2, 1}, + }}, + { .v = { + {7, 2, 2}, + {6, 1, 2}, + {4, 0, 2}, + {5, 3, 2}, + }}, + { .v = { + {5, 1, 3}, + {1, 0, 3}, + {3, 3, 3}, + {7, 2, 3}, + }}, + { .v = { + {1, 3, 4}, + {0, 0, 4}, + {2, 1, 4}, + {3, 2, 4}, + }}, + { .v = { + {5, 2, 5}, + {4, 1, 5}, + {0, 0, 5}, + {1, 3, 5}, + }}, +}; + diff --git a/template/src/arm9/math.h b/template/src/arm9/math.h new file mode 100644 index 0000000..ace35d0 --- /dev/null +++ b/template/src/arm9/math.h @@ -0,0 +1,10 @@ +#pragma once + +#define abs __builtin_abs + +int cos_fp12(int theta); + +static inline int sin_fp12(int theta) +{ + return cos_fp12(theta - 90); +} diff --git a/template/src/arm9/model.h b/template/src/arm9/model.h new file mode 100644 index 0000000..7832fcd --- /dev/null +++ b/template/src/arm9/model.h @@ -0,0 +1,66 @@ +#pragma once + +#include + +struct index_ptn { + uint16_t position; + uint16_t texture; + uint16_t normal; +}; + +union triangle { + struct { + struct index_ptn a; + struct index_ptn b; + struct index_ptn c; + }; + struct index_ptn v[3]; +}; + +union quadrilateral { + struct { + struct index_ptn a; + struct index_ptn b; + struct index_ptn c; + struct index_ptn d; + }; + struct index_ptn v[4]; +}; + +struct vertex_position { // signed 4.6 fixed point + int16_t x; + int16_t y; + int16_t z; +}; + +struct vertex_normal { // s.9 fixed point + int16_t x; + int16_t y; + int16_t z; +}; + +struct vertex_texture { // s.15 fixed point + int16_t u; + int16_t v; +}; + +typedef struct vertex_position vertex_position; +typedef struct vertex_normal vertex_normal; +typedef struct vertex_texture vertex_texture; + +struct object { + union triangle * triangle; + union quadrilateral * quadrilateral; + int triangle_count; + int quadrilateral_count; + int material; +}; + +struct model { + vertex_position * position; + vertex_texture * texture; + vertex_normal * normal; + + struct object ** object; + int object_count; +}; diff --git a/template/src/arm9/start.s b/template/src/arm9/start.s new file mode 100644 index 0000000..264d7a6 --- /dev/null +++ b/template/src/arm9/start.s @@ -0,0 +1,84 @@ + /* DDI0201D_arm946es_r1p1_trm.pdf pdf page 40 ; printed page 2-12 */ + .set INSTRUCTION_TCM_LOAD_MODE, (1 << 19) + .set INSTRUCTION_TCM_ENABLE, (1 << 18) + .set DATA_TCM_LOAD_MODE, (1 << 17) + .set DATA_TCM_ENABLE, (1 << 16) + .set DISABLE_LOADING_TBIT, (1 << 15) + .set ROUND_ROBIN_REPLACEMENT, (1 << 14) + .set ALTERNATE_VECTOR_SELET, (1 << 13) + .set INSTRUCTION_CACHE_ENABLE, (1 << 12) + .set BIG_ENDIAN, (1 << 7) + .set DATA_CACHE_ENABLE, (1 << 2) + .set PROTECTION_UNIT_ENABLE, (1 << 0) + + .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 + + .macro COPY_32_BYTE_ALIGNED + cmp r1, r10 + beq _fill_break.\@ +_fill_loop.\@: + ldmia r0!, {r2 - r9} + stmia r1!, {r2 - r9} + cmp r1, r10 + bne _fill_loop.\@ +_fill_break.\@: + .endm + + .section .text.start + .global _start +_start: + // https://developer.arm.com/documentation/ddi0338/g/system-control-coprocessor/system-control-processor-registers/c9--data-tcm-region-register?lang=en + + // set data tcm address + ldr r0, =0x027e0000 + mcr p15, 0, r0, c9, c1, 0 + + // enable instruction and data TCM + mrc p15, 0, r0, c1, c0, 0 + ldr r1, =INSTRUCTION_TCM_ENABLE | DATA_TCM_ENABLE | INSTRUCTION_CACHE_ENABLE | DATA_CACHE_ENABLE + orr r0, r0, r1 + mcr p15, 0, r0, c1, c0, 0 + +_link_text: + ldr r0, =__text_load_start + ldr r1, =__text_link_start + ldr r10, =__text_link_end + COPY_32_BYTE_ALIGNED + + /* +_link_data: + ldr r0, =__data_load_start + ldr r1, =__data_link_start + ldr r10, =__data_link_end + COPY_32_BYTE_ALIGNED + +_link_rodata: + ldr r0, =__rodata_load_start + ldr r1, =__rodata_link_start + ldr r10, =__rodata_link_end + COPY_32_BYTE_ALIGNED + */ + +_link_bss: + ldr r1, =__bss_link_start + ldr r10, =__bss_link_end + FILL_ZERO_32_BYTE_ALIGNED + +_c_runtime: + /* set stack pointer */ + ldr sp, =__stack_end + + /* jump to main */ + ldr r0, =main + bx r0