This commit is contained in:
Zack Buhman 2024-08-31 07:13:36 -05:00
parent ec85edbc14
commit 9e9764ef38
15 changed files with 182 additions and 30 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@ __pycache__
*.elf
*.bin
*.nds
.~lock*
.~lock*
*.csv

View File

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

View File

@ -1,4 +1,4 @@
io_registers = 0x04000000;
pram = 0x05000000;
vram = 0x06000000;
oam = 0x07000000;
bg_vram = 0x06000000;

View File

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

56
bg.h Normal file
View File

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

10
bits.h
View File

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

View File

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

79
main.c
View File

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

Binary file not shown.

BIN
res/player.data Normal file

Binary file not shown.

BIN
res/player.data.pal Normal file

Binary file not shown.

5
res/player.h Normal file
View File

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

5
res/player.pal.h Normal file
View File

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

BIN
res/player.xcf Normal file

Binary file not shown.

View File

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