diff --git a/.gitignore b/.gitignore index 2fd2ed4..4daae4d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ __pycache__ *.elf *.bin *.nds -.~lock* \ No newline at end of file +.~lock* +*.csv \ No newline at end of file diff --git a/Makefile b/Makefile index a8fc0b2..bc412f3 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,19 @@ +OPT = -Os + all: main.nds +res/%.h: res/%.data + $(BUILD_BINARY_H) + +res/%.pal.h: res/%.data.pal + $(BUILD_BINARY_H) + MAIN_OBJ = \ header.o \ start.o \ - main.o + main.o \ + res/player.data.o \ + res/player.data.pal.o main.elf: $(MAIN_OBJ) diff --git a/addresses_arm9.lds b/addresses_arm9.lds index efc9d5d..2714bde 100644 --- a/addresses_arm9.lds +++ b/addresses_arm9.lds @@ -1,4 +1,4 @@ io_registers = 0x04000000; pram = 0x05000000; -vram = 0x06000000; oam = 0x07000000; +bg_vram = 0x06000000; diff --git a/arm9.lds b/arm9.lds index b61d403..9978cd9 100644 --- a/arm9.lds +++ b/arm9.lds @@ -9,14 +9,19 @@ SECTIONS { . = ORIGIN(rom); - .text.header ALIGN(4) : SUBALIGN(4) + .text.header ALIGN(4) : { KEEP(*(.text.header)) } > rom . = ORIGIN(ram); - .text.arm9 ALIGN(4) : SUBALIGN(4) + .text.arm7 ALIGN(4) : + { + KEEP(*(.text.7start)) + } > ram AT> rom + + .text ALIGN(4) : { KEEP(*(.text.9start)) *(.text) @@ -27,12 +32,6 @@ SECTIONS *(.v4_bx) } > ram AT> rom - .text ALIGN(4) : SUBALIGN(4) - { - *(.text.*) - *(.text) - } > ram AT> rom - .data ALIGN(4) : { *(.data) @@ -45,24 +44,19 @@ SECTIONS *(.rodata.*) } > ram AT> rom - .ctors ALIGN(4) : SUBALIGN(4) + .ctors ALIGN(4) : { KEEP(*(.ctors)) KEEP(*(.ctors.*)) } > ram AT> rom - .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) + .bss ALIGN(4) (NOLOAD) : { *(.bss) *(.bss.*) *(COMMON) } > ram AT> rom - .text.arm7 ALIGN(4) : SUBALIGN(4) - { - KEEP(*(.text.7start)) - } > ram AT> rom - INCLUDE "debug.lds" } diff --git a/bg.h b/bg.h new file mode 100644 index 0000000..fe015f8 --- /dev/null +++ b/bg.h @@ -0,0 +1,56 @@ +#pragma once + +#include + +#define static_assert _Static_assert + +union screen_block { + uint8_t u8[0x800 / 1]; + uint16_t u16[0x800 / 2]; + uint32_t u32[0x800 / 4]; +}; +static_assert((sizeof (union screen_block)) == 0x800); + +struct screen_offset { + union screen_block block[32]; +}; +static_assert((sizeof (struct screen_offset)) == 0x10000); + +struct screen_data { + struct screen_offset offset[8]; +}; +static_assert((sizeof (struct screen_data)) == 0x80000); + +union character_block { + uint16_t u8[0x4000 / 2]; + uint16_t u16[0x4000 / 2]; + uint32_t u32[0x4000 / 4]; +}; +static_assert((sizeof (union character_block)) == 0x4000); + +struct character_offset { + union character_block block[4]; // is actually 16 +}; + +struct character_data { + struct character_offset offset[8]; +}; +static_assert((sizeof (struct character_data)) == 0x80000); + +struct bg { + union { + struct screen_data screen; + struct 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/bits.h b/bits.h index b285648..0ee698d 100644 --- a/bits.h +++ b/bits.h @@ -39,8 +39,8 @@ #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__2d_3d_display_selection_for_bg0__display_2d_graphics (0x0 << 3) -#define DISPCNT__2d_3d_display_selection_for_bg0__display_3d_graphics (0x1 << 3) +#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) @@ -129,3 +129,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/common.mk b/common.mk index fd67be6..06c3767 100644 --- a/common.mk +++ b/common.mk @@ -14,8 +14,8 @@ CFLAGS += -Wno-error=unused-variable CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics -# --print-gc-sections -LDFLAGS += --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error +# +LDFLAGS += --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error --print-gc-sections DEPFLAGS = -MMD -MP @@ -40,7 +40,7 @@ as_obj_binary = _binary_$(subst .,_,$(subst /,_,$(1))) define BUILD_BINARY_H @echo gen $@ @echo '#pragma once' > $@ - @echo '#include ' >> $@ + @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");' >> $@ diff --git a/main.c b/main.c index 9236345..e1dc00d 100644 --- a/main.c +++ b/main.c @@ -1,9 +1,84 @@ #include "io_registers.h" +#include "bits.h" +#include "bg.h" + +#include "res/player.h" +#include "res/player.pal.h" + +static inline uint16_t rgb555(const uint8_t * buf) +{ + uint8_t r = buf[0] >> 3; + uint8_t g = buf[1] >> 3; + uint8_t b = buf[2] >> 3; + + return (b << 10) | (g << 5) | (r << 0); +} void main() { - io_registers.a.DISPCNT = (1 << 16); // DISPLAY_ON + io_registers.a.VRAMCNT = (1 << 31) | (1 << 24); + io_registers.a.WVRAMCNT = 0; + + io_registers.a.DISPCNT = 0 + | DISPCNT__bg_screen_base_offset(0) + | DISPCNT__bg_character_base_offset(0) + | DISPCNT__display_mode__graphics_display + | DISPCNT__bg0__enable + | DISPCNT__display_selection_for_bg0__2d_graphics + | DISPCNT__bg_mode__text0_text1_text2_text3 + ; + + io_registers.a.BG0CNT = 0 + | BG0CNT__screen_size__256x256 + | BG0CNT__screen_base_block(31) + | BG0CNT__color_mode__16_color_mode + | BG0CNT__character_base_block(0) + | BG0CNT__priority(0) + ; + + uint32_t pal_size = (uint32_t)&_binary_res_player_data_pal_size; + const uint8_t * pal = (const uint8_t *)&_binary_res_player_data_pal_start; // palette ram - *((volatile uint16_t *)(0x05000000)) = (7 << 10) | (31 << 5) | (19 << 0); + for (int i = 0; i < 15; i++) { + ((volatile uint16_t *)(0x05000000))[i] = rgb555(&pal[i * 3]); + } + + + const uint8_t * data = (const uint8_t *)&_binary_res_player_data_start; + + + + for (int y = 0; y < 48; y++) { + uint8_t a = data[y * 8 + 0]; + uint8_t b = data[y * 8 + 1]; + uint8_t c = data[y * 8 + 2]; + uint8_t d = data[y * 8 + 3]; + uint8_t e = data[y * 8 + 4]; + uint8_t f = data[y * 8 + 5]; + uint8_t g = data[y * 8 + 6]; + uint8_t h = data[y * 8 + 7]; + + bg_vram.a.character.offset[0].block[0].u32[y] = 0 + | (a << 28) + | (b << 24) + | (c << 20) + | (d << 16) + | (e << 12) + | (f << 8) + | (g << 4) + | (h << 0); + } + + for (int i = 0; i < 32 * 32; i++) { + bg_vram.a.screen.offset[0].block[31].u16[i] = 30; + } + bg_vram.a.screen.offset[0].block[31].u16[32 * 0] = 3; + bg_vram.a.screen.offset[0].block[31].u16[32 * 1] = 4; + bg_vram.a.screen.offset[0].block[31].u16[32 * 2] = 5; + bg_vram.a.screen.offset[0].block[31].u16[32 * 0 + 1] = 0; + bg_vram.a.screen.offset[0].block[31].u16[32 * 1 + 1] = 1; + bg_vram.a.screen.offset[0].block[31].u16[32 * 2 + 1] = 2; + + while (1); } diff --git a/registers/graphics_engine_bits.ods b/registers/graphics_engine_bits.ods index 4368000..a7c21c5 100644 Binary files a/registers/graphics_engine_bits.ods and b/registers/graphics_engine_bits.ods differ diff --git a/res/player.data b/res/player.data new file mode 100644 index 0000000..e180546 Binary files /dev/null and b/res/player.data differ diff --git a/res/player.data.pal b/res/player.data.pal new file mode 100644 index 0000000..838f34a Binary files /dev/null and b/res/player.data.pal differ diff --git a/res/player.h b/res/player.h new file mode 100644 index 0000000..9e3857d --- /dev/null +++ b/res/player.h @@ -0,0 +1,5 @@ +#pragma once +#include +extern uint32_t _binary_res_player_data_start __asm("_binary_res_player_data_start"); +extern uint32_t _binary_res_player_data_end __asm("_binary_res_player_data_end"); +extern uint32_t _binary_res_player_data_size __asm("_binary_res_player_data_size"); diff --git a/res/player.pal.h b/res/player.pal.h new file mode 100644 index 0000000..8e3ada5 --- /dev/null +++ b/res/player.pal.h @@ -0,0 +1,5 @@ +#pragma once +#include +extern uint32_t _binary_res_player_data_pal_start __asm("_binary_res_player_data_pal_start"); +extern uint32_t _binary_res_player_data_pal_end __asm("_binary_res_player_data_pal_end"); +extern uint32_t _binary_res_player_data_pal_size __asm("_binary_res_player_data_pal_size"); diff --git a/res/player.xcf b/res/player.xcf new file mode 100644 index 0000000..abad8b0 Binary files /dev/null and b/res/player.xcf differ diff --git a/symbols.lds b/symbols.lds index 0f700e6..475a96e 100644 --- a/symbols.lds +++ b/symbols.lds @@ -19,15 +19,15 @@ __bss_link_start = ADDR(.bss); __bss_link_end = ADDR(.bss) + SIZEOF(.bss); /* header symbols */ -_arm9_offset = LOADADDR(.text.arm9); -_arm9_entry = ADDR(.text.arm9); -_arm9_addr = ADDR(.text.arm9); -_arm9_size = SIZEOF(.text.arm9); +_arm9_offset = LOADADDR(.text); +_arm9_entry = ADDR(.text); +_arm9_addr = ADDR(.text); +_arm9_size = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata) + SIZEOF(.ctors); _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); +_rom_size = SIZEOF(.text.header) + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.text.arm7); _header_size = SIZEOF(.text.header);