This commit is contained in:
Zack Buhman 2024-10-15 04:55:31 -05:00
commit a0fb0f4cd2
32 changed files with 2268 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*.o
*.bin
*.d
*.elf
*.nds

0
Makefile Normal file
View File

53
arm7.lds Normal file
View File

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

5
arm7.mk Normal file
View File

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

53
arm9.lds Normal file
View File

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

5
arm9.mk Normal file
View File

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

5
arm9_addresses.lds Normal file
View File

@ -0,0 +1,5 @@
io_registers = 0x04000000;
palette_ram = 0x05000000;
bg_vram = 0x06000000;
obj_vram = 0x06400000;
oam = 0x07000000;

58
cartridge.lds Normal file
View File

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

5
cartridge.mk Normal file
View File

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

104
common.mk Normal file
View File

@ -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 <stdint.h>' >> $@
@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.%

94
debug.lds Normal file
View File

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

53
header.s Normal file
View File

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

66
include/bg.h Normal file
View File

@ -0,0 +1,66 @@
#pragma once
#include <stdint.h>
#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");

381
include/bits.h Normal file
View File

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

464
include/graphics_engine_a.h Normal file
View File

@ -0,0 +1,464 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#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);

View File

@ -0,0 +1,85 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#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);

11
include/io_registers.h Normal file
View File

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

37
include/oam.h Normal file
View File

@ -0,0 +1,37 @@
#include <stdint.h>
#include <stddef.h>
#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");

32
include/obj.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include <stdint.h>
#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");

30
include/palette.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <stdint.h>
#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");

20
logo.s Normal file
View File

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

68
patch.py Normal file
View File

@ -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('<H', secure_area_crc)
buf[0x06c] = secure_area_crc_b[0]
buf[0x06d] = secure_area_crc_b[1]
header_crc = crc16_modbus(buf[0:0x15d + 1])
print("header", hex(header_crc))
header_crc_b = struct.pack('<H', header_crc)
buf[0x15e] = header_crc_b[0]
buf[0x15f] = header_crc_b[1]
with open(sys.argv[2], 'wb') as f:
f.write(buf)

14
symbols.lds Normal file
View File

@ -0,0 +1,14 @@
__text_link_start = ADDR(.text);
__text_link_end = ADDR(.text) + SIZEOF(.text);
__text_load_start = LOADADDR(.text);
__data_link_start = ADDR(.data);
__data_link_end = ADDR(.data) + SIZEOF(.data);
__data_load_start = LOADADDR(.data);
__rodata_link_start = ADDR(.rodata);
__rodata_link_end = ADDR(.rodata) + SIZEOF(.rodata);
__rodata_load_start = LOADADDR(.rodata);
__bss_link_start = ADDR(.bss);
__bss_link_end = ADDR(.bss) + SIZEOF(.bss);

35
template/Makefile Normal file
View File

@ -0,0 +1,35 @@
MAKEDIR ?= $(realpath $(dir $(realpath $(firstword $(MAKEFILE_LIST))))/..)
OPT ?= -Og
OBJ := ../header.o src/arm7/arm7.bin.o src/arm9/arm9.bin.o
include ../cartridge.mk
include ../common.mk
phony:
ARM9_OBJ := \
start.o \
cube.o \
cos_table_fp12.o \
cos.o
src/arm9/%.bin: phony
make \
-f $(MAKEDIR)/arm9.mk \
-f $(MAKEDIR)/common.mk \
-C $(dir $@) \
$(notdir $@) \
OBJ="$(ARM9_OBJ)"
ARM7_OBJ := \
start.o
src/arm7/%.bin: phony
make \
-f $(MAKEDIR)/arm7.mk \
-f $(MAKEDIR)/common.mk \
-C $(dir $@) \
$(notdir $@) \
OBJ="$(ARM7_OBJ)"
.PHONY: phony

26
template/src/arm7/start.s Normal file
View File

@ -0,0 +1,26 @@
.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:
// copy .text to internal ram
ldr r0, =__text_load_start
ldr r1, =__text_link_start
ldr r10, =__text_link_end
COPY_32_BYTE_ALIGNED
// jump to internal ram
ldr r3,=_loop_forever
bx r3
_loop_forever:
b _loop_forever

23
template/src/arm9/cos.c Normal file
View File

@ -0,0 +1,23 @@
#include <stdint.h>
#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];
}
}

View File

@ -0,0 +1,95 @@
#include <stdint.h>
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
};

210
template/src/arm9/cube.c Normal file
View File

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

71
template/src/arm9/cube.h Normal file
View File

@ -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},
}},
};

10
template/src/arm9/math.h Normal file
View File

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

66
template/src/arm9/model.h Normal file
View File

@ -0,0 +1,66 @@
#pragma once
#include <stdint.h>
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;
};

84
template/src/arm9/start.s Normal file
View File

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