diff --git a/Makefile b/Makefile index 918c5d9..8cf8989 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,31 @@ OPT = -Os +all: cartridge.bin + +phony: + +arm9/%.bin: phony + make -C arm9/ $(notdir $@) + +arm7/%.bin: phony + make -C arm7/ $(notdir $@) + OBJ = \ header.o \ arm9/arm9.bin.o \ arm7/arm7.bin.o - -all: cartridge.bin - -arm9/arm9.bin: - make -C arm9/ - -arm7/arm7.bin: - make -C arm7/ - cartridge.elf: $(OBJ) +TRIANGLE_OBJ = \ + header.o \ + arm9/triangle.bin.o \ + arm7/arm7.bin.o +triangle.elf: $(TRIANGLE_OBJ) + TARGET = arm-none-eabi- AARCH = -march=armv4t -mlittle-endian OBJARCH = -O elf32-littlearm -B armv4t LDSCRIPT = cartridge.lds include common.mk -.PHONY: arm9/arm9.bin arm7/arm7.bin +.PHONY: phony diff --git a/arm9/Makefile b/arm9/Makefile index 85797a7..1c37242 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -1,5 +1,11 @@ OPT = -Os +ALL = \ + arm9.bin \ + triangle.bin + +all: arm9.bin + OBJ = \ start.o \ main.o \ @@ -8,10 +14,11 @@ OBJ = \ ../res/bowser.data.o \ ../res/bowser.data.pal.o -all: arm9.bin - arm9.elf: $(OBJ) +foo = start.o examples/triangle.o +triangle.elf: $(foo) + CFLAGS += -I../include include arm9.mk diff --git a/arm9/examples/triangle.c b/arm9/examples/triangle.c new file mode 100644 index 0000000..ddc2ce2 --- /dev/null +++ b/arm9/examples/triangle.c @@ -0,0 +1,123 @@ +#include "io_registers.h" +#include "bits.h" + +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 + ; + + // 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; + + 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; + + // 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; + + // 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 and are not + // backface-culled + io_registers.a.POLYGON_ATTR = 0 + | POLYGON_ATTR__alpha_value(31) + | POLYGON_ATTR__render_front_surface__enable + | POLYGON_ATTR__render_back_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); + + // VTX_10 uses signed 4.6 floating point (10 bit) + // | 9 | 8 7 6 | 5 4 3 2 1 0 | + // | s | int | decimal | + int fixed_point_divisor = 64; // == 2⁶ + + // equilateral triangle; centered around the display origin in NDC + /* + A + / \ + B---C + + */ + + // fixed point constants; these are converted from floating-point to + // integer at compile-time + int ax = 0.0 * fixed_point_divisor; + int ay = 1.0 * fixed_point_divisor; + + int bx = -0.86602540378 * fixed_point_divisor; // - sqrt(3) / 2 + int by = -0.5 * fixed_point_divisor; + + int cx = 0.86602540378 * fixed_point_divisor; // + sqrt(3) / 2 + int cy = -0.5 * fixed_point_divisor; + + int z = 1.0 * fixed_point_divisor; + + // the following vertices are a triangle + io_registers.a.BEGIN_VTXS = BEGIN_VTXS__type__triangle; + + io_registers.a.COLOR = COLOR__blue(31); + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(z) + | VTX_10__y_coordinate(ay) + | VTX_10__x_coordinate(ax); + + io_registers.a.COLOR = COLOR__green(31); + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(z) + | VTX_10__y_coordinate(by) + | VTX_10__x_coordinate(bx); + + io_registers.a.COLOR = COLOR__red(31); + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(z) + | VTX_10__y_coordinate(cy) + | VTX_10__x_coordinate(cx); + + // end of the triangle + io_registers.a.END_VTXS = 0; + + // wait for the geometry engine + while (io_registers.a.GXSTAT & GXSTAT__geometry_engine_busy); + + // swap buffers + io_registers.a.SWAP_BUFFERS = 0; +} diff --git a/cartridge.lds b/cartridge.lds index ec36204..559990a 100644 --- a/cartridge.lds +++ b/cartridge.lds @@ -21,7 +21,7 @@ SECTIONS .text.arm9 ALIGN(4) : { - KEEP(*(.data.arm9/arm9.bin)) + KEEP(*(.data.arm9*.bin)) } AT>rom . = 0x02000000 + 0x8000; @@ -30,7 +30,7 @@ SECTIONS .text.arm7 ALIGN(4) : { - KEEP(*(.data.arm7/arm7.bin)) + KEEP(*(.data.arm7*.bin)) } AT>rom /DISCARD/ : diff --git a/include/bits.h b/include/bits.h index adcab53..68085ee 100644 --- a/include/bits.h +++ b/include/bits.h @@ -164,6 +164,9 @@ #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) diff --git a/registers/graphics_engine_bits.csv b/registers/graphics_engine_bits.csv index 1844aa1..139d2dc 100644 --- a/registers/graphics_engine_bits.csv +++ b/registers/graphics_engine_bits.csv @@ -183,6 +183,10 @@ ,,,,,, "MTX_RESTORE",,"4-0","position",,"0b11111", ,,,,,, +"COLOR",,"14-10","blue",,"0b11111", +"COLOR",,"9-5","green",,"0b11111", +"COLOR",,"4-0","red",,"0b11111", +,,,,,, "NORMAL",,"29-20","z_component",,"0x7ff", "NORMAL",,"19-10","y_component",,"0x7ff", "NORMAL",,"9-0","x_component",,"0x7ff", diff --git a/registers/graphics_engine_bits.ods b/registers/graphics_engine_bits.ods index fec6c17..d6ace6e 100644 Binary files a/registers/graphics_engine_bits.ods and b/registers/graphics_engine_bits.ods differ