diff --git a/dreamcast2/Makefile b/dreamcast2/Makefile index 5f4be2d..d2c452f 100644 --- a/dreamcast2/Makefile +++ b/dreamcast2/Makefile @@ -7,3 +7,9 @@ CFLAGS += -I$(MAKEFILE_PATH) LIB ?= $(MAKEFILE_PATH) include example/example.mk + +clean: + find -P \ + -regextype posix-egrep \ + -regex '.*\.(iso|o|d|bin|elf|cue|gch)$$' \ + -exec rm {} \; diff --git a/dreamcast2/addresses.lds b/dreamcast2/addresses.lds index 1cd560c..7a5f752 100644 --- a/dreamcast2/addresses.lds +++ b/dreamcast2/addresses.lds @@ -1,6 +1,6 @@ system_boot_rom = 0xa0000000; -system = 0xa05f6800; +systembus = 0xa05f6800; maple_if = 0xa05f6c00; gdrom_if = 0xa05f7000; g1_if = 0xa05f7400; diff --git a/dreamcast2/common.lds b/dreamcast2/common.lds index ad18b42..19ea551 100644 --- a/dreamcast2/common.lds +++ b/dreamcast2/common.lds @@ -2,15 +2,15 @@ SECTIONS { . = ORIGIN(p2ram); - .text.start : + .text.start ALIGN(4) : { KEEP(*(.text.start)) - *(.text.startup.*) + *(.text.start.*) } > p2ram AT>p1ram . = ORIGIN(p1ram) + (. - ORIGIN(p2ram)); - .text : + .text ALIGN(4) : SUBALIGN(4) { *(.text.*) *(.text) diff --git a/dreamcast2/example/example.mk b/dreamcast2/example/example.mk index 1232778..0934c88 100644 --- a/dreamcast2/example/example.mk +++ b/dreamcast2/example/example.mk @@ -7,3 +7,10 @@ FRAMEBUFFER_SHADED_OBJ = \ example/framebuffer_shaded.elf: LDSCRIPT = $(LIB)/main.lds example/framebuffer_shaded.elf: $(START_OBJ) $(FRAMEBUFFER_SHADED_OBJ) + +TRIANGLE_CORE_OBJ = \ + holly/core/region_array.o \ + example/triangle_core.o + +example/triangle_core.elf: LDSCRIPT = $(LIB)/main.lds +example/triangle_core.elf: $(START_OBJ) $(TRIANGLE_CORE_OBJ) diff --git a/dreamcast2/example/framebuffer_shaded.cpp b/dreamcast2/example/framebuffer_shaded.cpp index 97364be..485bdc3 100644 --- a/dreamcast2/example/framebuffer_shaded.cpp +++ b/dreamcast2/example/framebuffer_shaded.cpp @@ -4,7 +4,7 @@ void main() { - volatile uint32_t * framebuffer = (volatile uint32_t * )texture_memory32; + volatile uint32_t * framebuffer = (volatile uint32_t * )&texture_memory32[0x200000]; for (int y = 0; y < 480; y++) { for (int x = 0; x < 640; x++) { diff --git a/dreamcast2/example/triangle_core.cpp b/dreamcast2/example/triangle_core.cpp new file mode 100644 index 0000000..b9cc291 --- /dev/null +++ b/dreamcast2/example/triangle_core.cpp @@ -0,0 +1,180 @@ +#include "memorymap.hpp" + +#include "holly/core/object_list_bits.hpp" +#include "holly/core/region_array.hpp" +#include "holly/core/region_array_bits.hpp" +#include "holly/core/parameter_bits.hpp" +#include "holly/core/parameter.hpp" +#include "holly/holly.hpp" +#include "holly/holly_bits.hpp" + +void transfer_object_list(uint32_t object_list_start, uint32_t triangle_array_offset) +{ + using namespace holly::core; + + volatile uint32_t * object_list = (volatile uint32_t *)&texture_memory32[object_list_start]; + + object_list[0] = object_list::pointer_type::triangle_array + | object_list::triangle_array::number_of_triangles(0) + | object_list::triangle_array::skip(1) + | object_list::triangle_array::start(triangle_array_offset / 4); + + object_list[1] = object_list::pointer_type::object_pointer_block_link + | object_list::object_pointer_block_link::end_of_list; +} + +void transfer_background_polygon(uint32_t isp_tsp_parameter_start) +{ + using namespace holly::core::parameter; + + using parameter = isp_tsp_parameter<3>; + + volatile parameter * polygon = (volatile parameter *)&texture_memory32[isp_tsp_parameter_start]; + + polygon->isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always + | isp_tsp_instruction_word::culling_mode::no_culling; + + polygon->tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + + polygon->texture_control_word = 0; + + polygon->vertex[0].x = 0.0f; + polygon->vertex[0].y = 0.0f; + polygon->vertex[0].z = 0.00001f; + polygon->vertex[0].base_color = 0xff00ff; + + polygon->vertex[1].x = 32.0f; + polygon->vertex[1].y = 0.0f; + polygon->vertex[1].z = 0.00001f; + polygon->vertex[1].base_color = 0xff00ff; + + polygon->vertex[2].x = 32.0f; + polygon->vertex[2].y = 32.0f; + polygon->vertex[2].z = 0.00001f; + polygon->vertex[2].base_color = 0xff00ff; +} + +void transfer_triangle_polygon(uint32_t isp_tsp_parameter_start) +{ + using namespace holly::core::parameter; + + using parameter = isp_tsp_parameter<3>; + + volatile parameter * polygon = (volatile parameter *)&texture_memory32[isp_tsp_parameter_start]; + + polygon->isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always + | isp_tsp_instruction_word::culling_mode::no_culling + | isp_tsp_instruction_word::gouraud_shading; + + polygon->tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + + polygon->texture_control_word = 0; + + polygon->vertex[0].x = 1.0f; + polygon->vertex[0].y = 29.0f; + polygon->vertex[0].z = 0.1f; + polygon->vertex[0].base_color = 0xff0000; + + polygon->vertex[1].x = 16.0f; + polygon->vertex[1].y = 3.0f; + polygon->vertex[1].z = 0.1f; + polygon->vertex[1].base_color = 0x00ff00; + + polygon->vertex[2].x = 31.0f; + polygon->vertex[2].y = 29.0f; + polygon->vertex[2].z = 0.1f; + polygon->vertex[2].base_color = 0x0000ff; +} + + +void transfer_region_array(uint32_t region_array_start, + uint32_t opaque_list_pointer) +{ + using namespace holly::core::region_array; + /* + Create a minimal region array with a single entry: + - one tile at tile coordinate (0, 0) with one opaque list pointer + */ + + /* + Holly reads the region array from "32-bit" texture memory address space, + so the region array is correspondingly written from "32-bit" address space. + */ + volatile region_array_entry * region_array = (volatile region_array_entry *)&texture_memory32[region_array_start]; + + region_array[0].tile + = tile::last_region + | tile::y_position(0) + | tile::x_position(0); + + /* + list pointers are offsets relative to the beginning of "32-bit" texture memory. + + each list type uses different rasterization steps, "opaque" being the fastest and most efficient. + */ + region_array[0].list_pointer.opaque = list_pointer::object_list(opaque_list_pointer); + region_array[0].list_pointer.opaque_modifier_volume = list_pointer::empty; + region_array[0].list_pointer.translucent = list_pointer::empty; + region_array[0].list_pointer.translucent_modifier_volume = list_pointer::empty; + region_array[0].list_pointer.punch_through = list_pointer::empty; +} + +void main() +{ + uint32_t framebuffer_start = 0x200000; + uint32_t isp_tsp_parameter_start = 0x400000; + uint32_t region_array_start = 0x500000; + uint32_t object_list_start = 0x100000; + + transfer_region_array(region_array_start, + object_list_start); + + using polygon = holly::core::parameter::isp_tsp_parameter<3>; + + uint32_t triangle_offset = (sizeof (polygon)) * 0; + uint32_t background_offset = (sizeof (polygon)) * 1; + + transfer_object_list(object_list_start, + triangle_offset); + + transfer_triangle_polygon(isp_tsp_parameter_start + triangle_offset); + + transfer_background_polygon(isp_tsp_parameter_start + background_offset); + + { + using namespace holly; + using holly::holly; + + // REGION_BASE is the (texture memory-relative) address of the region array. + holly.REGION_BASE = region_array_start; + + // PARAM_BASE is the (texture memory-relative) address of ISP/TSP parameters. + // Anything that references an ISP/TSP parameter does so relative to this + // address (and not relative to the beginning of texture memory). + holly.PARAM_BASE = isp_tsp_parameter_start; + + // Set the offset of the background ISP/TSP parameter, relative to PARAM_BASE + // SKIP is related to the size of each vertex + holly.ISP_BACKGND_T = isp_backgnd_t::tag_address(background_offset / 4) + | isp_backgnd_t::tag_offset(0) + | isp_backgnd_t::skip(1); + + holly.ISP_BACKGND_D = 0.000001f; + + // FB_W_SOF1 is the (texture memory-relative) address of the framebuffer that + // will be written to when a tile is rendered/flushed. + holly.FB_W_SOF1 = framebuffer_start; + + // start the actual render--the rendering process begins by interpreting the + // region array + holly.STARTRENDER = 1; + + // without waiting for rendering to actually complete, immediately display the + // framebuffer. + holly.FB_R_SOF1 = framebuffer_start; + } +} diff --git a/dreamcast2/holly/core/object_list_bits.hpp b/dreamcast2/holly/core/object_list_bits.hpp new file mode 100644 index 0000000..78256a5 --- /dev/null +++ b/dreamcast2/holly/core/object_list_bits.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include + +namespace holly::core::object_list { + namespace pointer_type { + constexpr uint32_t triangle_strip = 0b000 << 29; + constexpr uint32_t triangle_array = 0b100 << 29; + constexpr uint32_t quad_array = 0b101 << 29; + constexpr uint32_t object_pointer_block_link = 0b111 << 29; + + constexpr uint32_t bit_mask = 0x7 << 29; + } + + namespace triangle_strip { + namespace mask { + constexpr uint32_t t0 = 0b100000 << 25; + constexpr uint32_t t1 = 0b010000 << 25; + constexpr uint32_t t2 = 0b001000 << 25; + constexpr uint32_t t3 = 0b000100 << 25; + constexpr uint32_t t4 = 0b000010 << 25; + constexpr uint32_t t5 = 0b000001 << 25; + + constexpr uint32_t bit_mask = 0x3f << 25; + } + + constexpr uint32_t shadow = 1 << 24; + constexpr uint32_t skip(uint32_t num) { return (num & 0x7) << 21; } + constexpr uint32_t start(uint32_t num) { return (num & 0x1fffff) << 0; } + } + + namespace triangle_array { + constexpr uint32_t number_of_triangles(uint32_t num) { return (num & 0xf) << 25; } + constexpr uint32_t shadow = 1 << 24; + constexpr uint32_t skip(uint32_t num) { return (num & 0x7) << 21; } + constexpr uint32_t start(uint32_t num) { return (num & 0x1fffff) << 0; } + } + + namespace quad_array { + constexpr uint32_t number_of_quads(uint32_t num) { return (num & 0xf) << 25; } + constexpr uint32_t shadow = 1 << 24; + constexpr uint32_t skip(uint32_t num) { return (num & 0x7) << 21; } + constexpr uint32_t start(uint32_t num) { return (num & 0x1fffff) << 0; } + } + + namespace object_pointer_block_link { + constexpr uint32_t end_of_list = 1 << 28; + constexpr uint32_t next_pointer_block(uint32_t num) { return (num & 0xfffffc) << 0; } + } + +} diff --git a/dreamcast2/holly/core/parameter.hpp b/dreamcast2/holly/core/parameter.hpp new file mode 100644 index 0000000..0601125 --- /dev/null +++ b/dreamcast2/holly/core/parameter.hpp @@ -0,0 +1,144 @@ +#include + +namespace holly::core::parameter { + + enum struct volume_sel { + one_volume, + two_volumes + }; + + using volume_sel::one_volume; + using volume_sel::two_volumes; + + enum struct offset_sel { + offset, + non_offset + }; + + using offset_sel::offset; + using offset_sel::non_offset; + + enum struct texture_sel { + texture, + non_texture + }; + + using texture_sel::texture; + using texture_sel::non_texture; + + template + struct vertex; + + template <> + struct vertex { + float x; + float y; + float z; + uint32_t base_color; + }; + + template <> + struct vertex { + float x; + float y; + float z; + struct { + uint32_t base_color; + } volume[2]; + }; + + template <> + struct vertex { + float x; + float y; + float z; + uint32_t base_color; + uint32_t offset_color; + }; + + template <> + struct vertex { + float x; + float y; + float z; + struct { + uint32_t base_color; + uint32_t offset_color; + } volume[2]; + }; + + template <> + struct vertex { + float x; + float y; + float z; + float u; + float v; + uint32_t base_color; + }; + + template <> + struct vertex { + float x; + float y; + float z; + struct { + float u; + float v; + uint32_t base_color; + } volume[2]; + }; + + template <> + struct vertex { + float x; + float y; + float z; + float u; + float v; + uint32_t base_color; + uint32_t offset_color; + }; + + template <> + struct vertex { + float x; + float y; + float z; + struct { + float u; + float v; + uint32_t base_color; + uint32_t offset_color; + } volume[2]; + }; + + template + struct isp_tsp_parameter; + + template + struct isp_tsp_parameter { + uint32_t isp_tsp_instruction_word; + uint32_t tsp_instruction_word; + uint32_t texture_control_word; + struct vertex vertex[N]; + }; + + template + struct isp_tsp_parameter { + uint32_t isp_tsp_instruction_word; + struct { + uint32_t tsp_instruction_word; + uint32_t texture_control_word; + } volume[2]; + struct vertex vertex[N]; + }; + + static_assert((sizeof (isp_tsp_parameter<1>)) == 28); + static_assert((sizeof (isp_tsp_parameter<1, texture>)) == 36); + static_assert((sizeof (isp_tsp_parameter<1, texture, two_volumes>)) == 56); + static_assert((sizeof (isp_tsp_parameter<1, texture, two_volumes, offset>)) == 64); + + static_assert((sizeof (isp_tsp_parameter<1, non_texture, two_volumes>)) == 40); + static_assert((sizeof (isp_tsp_parameter<1, non_texture, two_volumes, offset>)) == 48); +} diff --git a/dreamcast2/holly/core/parameter_bits.hpp b/dreamcast2/holly/core/parameter_bits.hpp new file mode 100644 index 0000000..aa10f08 --- /dev/null +++ b/dreamcast2/holly/core/parameter_bits.hpp @@ -0,0 +1,195 @@ +#pragma once + +#include + +namespace holly::core::parameter { + namespace isp_tsp_instruction_word { + namespace depth_compare_mode { + constexpr uint32_t never = 0 << 29; + constexpr uint32_t less = 1 << 29; + constexpr uint32_t equal = 2 << 29; + constexpr uint32_t less_or_equal = 3 << 29; + constexpr uint32_t greater = 4 << 29; + constexpr uint32_t greater_or_equal = 5 << 29; + constexpr uint32_t not_equal = 6 << 29; + constexpr uint32_t always = 7 << 29; + + constexpr uint32_t bit_mask = 0x7 << 29; + } + + namespace volume_instruction { + constexpr uint32_t normal_polygon = 0 << 29; + constexpr uint32_t inside_last_polygon = 1 << 29; + constexpr uint32_t outside_last_polygon = 2 << 29; + + constexpr uint32_t bit_mask = 0x7 << 29; + } + + namespace culling_mode { + constexpr uint32_t no_culling = 0 << 27; + constexpr uint32_t cull_if_small = 1 << 27; + constexpr uint32_t cull_if_negative = 2 << 27; + constexpr uint32_t cull_if_positive = 3 << 27; + + constexpr uint32_t bit_mask = 0x3 << 27; + } + + constexpr uint32_t z_write_disable = 1 << 26; + constexpr uint32_t texture = 1 << 25; + constexpr uint32_t offset = 1 << 24; + constexpr uint32_t gouraud_shading = 1 << 23; + constexpr uint32_t _16bit_uv = 1 << 22; + constexpr uint32_t cache_bypass = 1 << 21; + constexpr uint32_t dcalc_ctrl = 1 << 20; + } + + namespace tsp_instruction_word { + namespace src_alpha_instr { + constexpr uint32_t zero = 0 << 29; + constexpr uint32_t one = 1 << 29; + constexpr uint32_t other_color = 2 << 29; + constexpr uint32_t inverse_other_color = 3 << 29; + constexpr uint32_t src_alpha = 4 << 29; + constexpr uint32_t inverse_src_alpha = 5 << 29; + constexpr uint32_t dst_alpha = 6 << 29; + constexpr uint32_t inverse_dst_alpha = 7 << 29; + + constexpr uint32_t bit_mask = 0x7 << 29; + } + + namespace dst_alpha_instr { + constexpr uint32_t zero = 0 << 26; + constexpr uint32_t one = 1 << 26; + constexpr uint32_t other_color = 2 << 26; + constexpr uint32_t inverse_other_color = 3 << 26; + constexpr uint32_t src_alpha = 4 << 26; + constexpr uint32_t inverse_src_alpha = 5 << 26; + constexpr uint32_t dst_alpha = 6 << 26; + constexpr uint32_t inverse_dst_alpha = 7 << 26; + + constexpr uint32_t bit_mask = 0x7 << 26; + } + + namespace src_select { + constexpr uint32_t primary_accumulation_buffer = 0 << 25; + constexpr uint32_t secondary_accumulation_buffer = 1 << 25; + + constexpr uint32_t bit_mask = 0x1 << 25; + } + + namespace dst_select { + constexpr uint32_t primary_accumulation_buffer = 0 << 24; + constexpr uint32_t secondary_accumulation_buffer = 1 << 24; + + constexpr uint32_t bit_mask = 0x1 << 24; + } + + namespace fog_control { + constexpr uint32_t look_up_table = 0b00 << 22; + constexpr uint32_t per_vertex = 0b01 << 22; + constexpr uint32_t no_fog = 0b10 << 22; + constexpr uint32_t look_up_table_mode_2 = 0b11 << 22; + + constexpr uint32_t bit_mask = 0x3 << 22; + } + + constexpr uint32_t color_clamp = 1 << 21; + constexpr uint32_t use_alpha = 1 << 20; + constexpr uint32_t ignore_texture_alpha = 1 << 19; + + namespace flip_uv { + constexpr uint32_t none = 0 << 17; + constexpr uint32_t v = 1 << 17; + constexpr uint32_t u = 2 << 17; + constexpr uint32_t uv = 3 << 17; + + constexpr uint32_t bit_mask = 0x3 << 17; + } + + namespace clamp_uv { + constexpr uint32_t none = 0 << 15; + constexpr uint32_t v = 1 << 15; + constexpr uint32_t u = 2 << 15; + constexpr uint32_t uv = 3 << 15; + + constexpr uint32_t bit_mask = 0x3 << 15; + } + + namespace filter_mode { + constexpr uint32_t point_sampled = 0b00 << 13; + constexpr uint32_t bilinear_filter = 0b01 << 13; + constexpr uint32_t trilinear_pass_a = 0b10 << 13; + constexpr uint32_t trilinear_pass_b = 0b11 << 13; + + constexpr uint32_t bit_mask = 0x3 << 13; + } + + constexpr uint32_t super_sample_texture = 1 << 12; + constexpr uint32_t mip_map_d_adjust(uint32_t num) { return (num & 0xf) << 8; } + + namespace texture_shading_instruction { + constexpr uint32_t decal = 0 << 6; + constexpr uint32_t modulate = 1 << 6; + constexpr uint32_t decal_alpha = 2 << 6; + constexpr uint32_t modulate_alpha = 3 << 6; + + constexpr uint32_t bit_mask = 0x3 << 6; + } + + namespace texture_u_size { + constexpr uint32_t _8 = 0 << 3; + constexpr uint32_t _16 = 1 << 3; + constexpr uint32_t _32 = 2 << 3; + constexpr uint32_t _64 = 3 << 3; + constexpr uint32_t _128 = 4 << 3; + constexpr uint32_t _256 = 5 << 3; + constexpr uint32_t _512 = 6 << 3; + constexpr uint32_t _1024 = 7 << 3; + + constexpr uint32_t bit_mask = 0x7 << 3; + } + + namespace texture_v_size { + constexpr uint32_t _8 = 0 << 0; + constexpr uint32_t _16 = 1 << 0; + constexpr uint32_t _32 = 2 << 0; + constexpr uint32_t _64 = 3 << 0; + constexpr uint32_t _128 = 4 << 0; + constexpr uint32_t _256 = 5 << 0; + constexpr uint32_t _512 = 6 << 0; + constexpr uint32_t _1024 = 7 << 0; + + constexpr uint32_t bit_mask = 0x7 << 0; + } + } + + namespace texture_control_word { + constexpr uint32_t mip_mapped = 1 << 31; + constexpr uint32_t vq_compressed = 1 << 30; + + namespace pixel_format { + constexpr uint32_t argb1555 = 0 << 27; + constexpr uint32_t rgb565 = 1 << 27; + constexpr uint32_t argb4444 = 2 << 27; + constexpr uint32_t yuv422 = 3 << 27; + constexpr uint32_t bump_map = 4 << 27; + constexpr uint32_t palette_4bpp = 5 << 27; + constexpr uint32_t palette_8bpp = 6 << 27; + + constexpr uint32_t bit_mask = 0x7 << 27; + } + + namespace scan_order { + constexpr uint32_t twiddled = 0 << 26; + constexpr uint32_t non_twiddled = 1 << 26; + + constexpr uint32_t bit_mask = 0x1 << 26; + } + + constexpr uint32_t palette_selector4(uint32_t num) { return (num & 0x3f) << 21; } + constexpr uint32_t palette_selector8(uint32_t num) { return (num & 0x3) << 25; } + constexpr uint32_t stride_select(uint32_t reg) { return (reg >> 25) & 0x1; } + constexpr uint32_t texture_address(uint32_t num) { return (num & 0x1fffff) << 0; } + } + +} diff --git a/dreamcast2/holly/core/region_array.cpp b/dreamcast2/holly/core/region_array.cpp new file mode 100644 index 0000000..8090d10 --- /dev/null +++ b/dreamcast2/holly/core/region_array.cpp @@ -0,0 +1,77 @@ +#include "holly/core/region_array.hpp" +#include "holly/core/region_array_bits.hpp" + +#include "sh7091/store_queue_transfer.hpp" + +#include "systembus/systembus.hpp" + +namespace holly::core::region_array { + void transfer(const int tile_width, + const int tile_height, + const list_block_size& list_block_size, + const uint32_t region_array_start, + const uint32_t object_list_start) + { + const uint32_t ol_base = object_list_start; + const uint32_t num_tiles = tile_width * tile_height; + //region_array_entry region_array[num_tiles]; + volatile region_array_entry * region_array = (volatile region_array_entry * )&texture_memory32[region_array_start]; + + int ix = 0; + + for (int y = 0; y < tile_height; y++) { + for (int x = 0; x < tile_width; x++) { + region_array[ix].tile = tile::y_position(y) + | tile::x_position(x); + + if (y == (tile_height - 1) && x == (tile_width - 1)) + region_array[ix].tile |= tile::last_region; + + region_array[ix].list_pointer.opaque = (list_block_size.opaque == 0) ? list_pointer::empty : + (ol_base + (list_block_size.opaque * ix) + ); + + region_array[ix].list_pointer.opaque_modifier_volume = (list_block_size.opaque_modifier_volume == 0) ? list_pointer::empty : + (ol_base + num_tiles * ( list_block_size.opaque + ) + + (list_block_size.opaque_modifier_volume * ix) + ); + + region_array[ix].list_pointer.translucent = (list_block_size.translucent == 0) ? list_pointer::empty : + (ol_base + num_tiles * ( list_block_size.opaque + + list_block_size.opaque_modifier_volume + ) + + (list_block_size.translucent * ix) + ); + region_array[ix].list_pointer.translucent_modifier_volume = (list_block_size.translucent_modifier_volume == 0) ? list_pointer::empty : + (ol_base + num_tiles * ( list_block_size.opaque + + list_block_size.opaque_modifier_volume + + list_block_size.translucent + ) + + (list_block_size.translucent_modifier_volume * ix) + ); + region_array[ix].list_pointer.punch_through = (list_block_size.punch_through == 0) ? list_pointer::empty : + (ol_base + num_tiles * ( list_block_size.opaque + + list_block_size.opaque_modifier_volume + + list_block_size.translucent + + list_block_size.translucent_modifier_volume + ) + + (list_block_size.punch_through * ix) + ); + + ix += 1; + } + } + + /* + using systembus::systembus; + + systembus.LMMODE0 = 1; // 32-bit address space + systembus.LMMODE1 = 1; // 32-bit address space + + void * dst = (void *)(&ta_fifo_texture_memory[region_array_start]); + void * src = (void *)(region_array); + sh7091::store_queue_transfer::copy(dst, src, (sizeof (region_array_entry)) * num_tiles); + */ + } +} diff --git a/dreamcast2/holly/core/region_array.hpp b/dreamcast2/holly/core/region_array.hpp new file mode 100644 index 0000000..ae28e62 --- /dev/null +++ b/dreamcast2/holly/core/region_array.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace holly::core::region_array { + struct region_array_entry { + uint32_t tile; + struct { + uint32_t opaque; + uint32_t opaque_modifier_volume; + uint32_t translucent; + uint32_t translucent_modifier_volume; + uint32_t punch_through; + } list_pointer; + }; + + struct list_block_size { + uint32_t opaque; + uint32_t opaque_modifier_volume; + uint32_t translucent; + uint32_t translucent_modifier_volume; + uint32_t punch_through; + + uint32_t total() const + { + return opaque + + opaque_modifier_volume + + translucent + + translucent_modifier_volume + + punch_through; + } + }; + + void transfer(const int tile_width, + const int tile_height, + const list_block_size& list_block_size, + const uint32_t region_array_start, + const uint32_t object_list_start); +} diff --git a/dreamcast2/holly/core/region_array_bits.hpp b/dreamcast2/holly/core/region_array_bits.hpp new file mode 100644 index 0000000..0082289 --- /dev/null +++ b/dreamcast2/holly/core/region_array_bits.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace holly::core::region_array { + namespace tile { + constexpr uint32_t last_region = 1 << 31; + constexpr uint32_t z_clear = 1 << 30; + constexpr uint32_t pre_sort = 1 << 29; + constexpr uint32_t flush_accumulate = 1 << 28; + constexpr uint32_t y_position(uint32_t num) { return (num & 0x3f) << 8; } + constexpr uint32_t x_position(uint32_t num) { return (num & 0x3f) << 2; } + } + + namespace list_pointer { + constexpr uint32_t empty = 1 << 31; + constexpr uint32_t object_list(uint32_t num) { return (num & 0xfffffc) << 0; } + } + +} diff --git a/dreamcast2/holly/object_list_bits.hpp b/dreamcast2/holly/object_list_bits.hpp deleted file mode 100644 index 43d6474..0000000 --- a/dreamcast2/holly/object_list_bits.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include - -namespace holly { - namespace object_list { - namespace pointer_type { - constexpr uint32_t triangle_strip = 0b000 << 29; - constexpr uint32_t triangle_array = 0b100 << 29; - constexpr uint32_t quad_array = 0b101 << 29; - constexpr uint32_t object_pointer_block_link = 0b111 << 29; - - constexpr uint32_t bit_mask = 0x7 << 29; - } - - namespace triangle_strip { - namespace mask { - constexpr uint32_t t0 = 0b100000 << 25; - constexpr uint32_t t1 = 0b010000 << 25; - constexpr uint32_t t2 = 0b001000 << 25; - constexpr uint32_t t3 = 0b000100 << 25; - constexpr uint32_t t4 = 0b000010 << 25; - constexpr uint32_t t5 = 0b000001 << 25; - - constexpr uint32_t bit_mask = 0x3f << 25; - } - - constexpr uint32_t shadow = 1 << 24; - constexpr uint32_t skip(uint32_t num) { return (num & 0x7) << 21; } - constexpr uint32_t start(uint32_t num) { return (num & 0x1fffff) << 0; } - } - - namespace triangle_array { - constexpr uint32_t number_of_triangles(uint32_t num) { return (num & 0xf) << 25; } - constexpr uint32_t shadow = 1 << 24; - constexpr uint32_t skip(uint32_t num) { return (num & 0x7) << 21; } - constexpr uint32_t start(uint32_t num) { return (num & 0x1fffff) << 0; } - } - - namespace quad_array { - constexpr uint32_t number_of_quads(uint32_t num) { return (num & 0xf) << 25; } - constexpr uint32_t shadow = 1 << 24; - constexpr uint32_t skip(uint32_t num) { return (num & 0x7) << 21; } - constexpr uint32_t start(uint32_t num) { return (num & 0x1fffff) << 0; } - } - - namespace object_pointer_block_link { - constexpr uint32_t end_of_list = 1 << 28; - constexpr uint32_t next_pointer_block(uint32_t num) { return (num & 0xfffffc) << 0; } - } - - } -} diff --git a/dreamcast2/holly/region_array.cpp b/dreamcast2/holly/region_array.cpp deleted file mode 100644 index e2e99f4..0000000 --- a/dreamcast2/holly/region_array.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "holly/region_array.hpp" -#include "holly/region_array_bits.hpp" - -#incllude "sh7091/store_queue_transfer.hpp" - -namespace holly::region_array { - - void transfer_region_array(const int tile_width, - const int tile_height, - const list_block_size& list_block_size, - const uint32_t region_array_start, - const uint32_t object_list_start); - { - const uint32_t ol_base = object_list_start; - const uint32_t num_tiles = width * height; - region_array_entry region_array[num_tiles]; - - int ix = 0; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - region_array[ix].tile = tile::y_position(y) - | tile::x_position(x); - - if (y == (height - 1) && x == (width - 1)) - region_array[ix].tile |= tile::last_region; - - region_array[ix].list_pointer.opaque = (opb_size.opaque == 0) ? REGION_ARRAY__LIST_POINTER__EMPTY : - (ol_base + (opb_size.opaque * ix) - ); - - region_array[ix].list_pointer.opaque_modifier_volume = (opb_size.opaque_modifier == 0) ? REGION_ARRAY__LIST_POINTER__EMPTY : - (ol_base + num_tiles * ( opb_size.opaque - ) - + (opb_size.opaque_modifier_volume * ix) - ); - - region_array[ix].list_pointer.translucent = (opb_size.translucent == 0) ? REGION_ARRAY__LIST_POINTER__EMPTY : - (ol_base + num_tiles * ( opb_size.opaque - + opb_size.opaque_modifier_volume - ) - + (opb_size.translucent * ix) - ); - region_array[ix].list_pointer.translucent_modifier_volume = (opb_size.translucent_modifier == 0) ? REGION_ARRAY__LIST_POINTER__EMPTY : - (ol_base + num_tiles * ( opb_size.opaque - + opb_size.opaque_modifier_volume - + opb_size.translucent - ) - + (opb_size.translucent_modifier_volume * ix) - ); - region_array[ix].list_pointer.punch_through = (opb_size.punch_through == 0) ? REGION_ARRAY__LIST_POINTER__EMPTY : - (ol_base + num_tiles * ( opb_size.opaque - + opb_size.opaque_modifier_volume - + opb_size.translucent - + opb_size.translucent_modifier_volume - ) - + (opb_size.punch_through * ix) - ); - - ix += 1; - } - } - - system.LMMODE0 = 1; // 32-bit address space - system.LMMODE1 = 1; // 32-bit address space - - void * dst = (void *)(&ta_fifo_texture_memory[region_array_start]); - void * src = (void *)(region_array); - sh7091::store_queue_transfer::copy(dst, src, (sizeof (region_array_entry)) * num_tiles); - } -} diff --git a/dreamcast2/holly/region_array.hpp b/dreamcast2/holly/region_array.hpp deleted file mode 100644 index c596b75..0000000 --- a/dreamcast2/holly/region_array.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include - -namespace holly { - namespace region_array { - struct region_array_entry { - uint32_t tile; - struct { - uint32_t opaque; - uint32_t opaque_modifier_volume; - uint32_t translucent; - uint32_t translucent_modifier_volume; - uint32_t punch_through; - } list_pointer; - }; - - struct list_block_size { - uint32_t opaque; - uint32_t opaque_modifier_volume; - uint32_t translucent; - uint32_t translucent_modifier_volume; - uint32_t punch_through; - - uint32_t total() const - { - return opaque - + opaque_modifier_volume - + translucent - + translucent_modifier_volume - + punch_through; - } - }; - - void transfer_region_array(const int tile_width, - const int tile_height, - const list_block_size& list_block_size, - const uint32_t region_array_start, - const uint32_t object_list_start); - } -} diff --git a/dreamcast2/holly/region_array_bits.hpp b/dreamcast2/holly/region_array_bits.hpp deleted file mode 100644 index 0769699..0000000 --- a/dreamcast2/holly/region_array_bits.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -namespace holly { - namespace region_array { - namespace tile { - constexpr uint32_t last_region = 1 << 31; - constexpr uint32_t z_clear = 1 << 30; - constexpr uint32_t pre_sort = 1 << 29; - constexpr uint32_t flush_accumulate = 1 << 28; - constexpr uint32_t y_position(uint32_t num) { return (num & 0x3f) << 8; } - constexpr uint32_t x_position(uint32_t num) { return (num & 0x3f) << 2; } - } - - namespace list_pointer { - constexpr uint32_t empty = 1 << 31; - constexpr uint32_t object_list(uint32_t num) { return (num & 0xfffffc) << 0; } - } - - } -} diff --git a/dreamcast2/memorymap.hpp b/dreamcast2/memorymap.hpp index ed0845f..a9d5f90 100644 --- a/dreamcast2/memorymap.hpp +++ b/dreamcast2/memorymap.hpp @@ -1,15 +1,15 @@ #include -extern volatile uint8_t system_boot_rom[0x200000] __asm("system_boot_rom"); -extern volatile uint8_t aica_wave_memory[0x200000] __asm("aica_wave_memory"); -extern volatile uint8_t texture_memory64[0x800000] __asm("texture_memory64"); -extern volatile uint8_t texture_memory32[0x800000] __asm("texture_memory32"); -extern volatile uint8_t system_memory[0x1000000] __asm("system_memory"); -extern volatile uint8_t ta_fifo_polygon_converter[0x800000] __asm("ta_fifo_polygon_converter"); -extern volatile uint8_t ta_fifo_yuv_converter[0x800000] __asm("ta_fifo_yuv_converter"); -extern volatile uint8_t ta_fifo_texture_memory[0x800000] __asm("ta_fifo_texture_memory"); -extern volatile uint8_t ta_fifo_polygon_converter_mirror[0x800000] __asm("ta_fifo_polygon_converter_mirror"); -extern volatile uint8_t ta_fifo_yuv_converter_mirror[0x800000] __asm("ta_fifo_yuv_converter_mirror"); -extern volatile uint8_t ta_fifo_texture_memory_mirror[0x800000] __asm("ta_fifo_texture_memory_mirror"); -extern volatile uint8_t store_queue[0x4000000] __asm("store_queue"); -extern volatile uint8_t sh7091_oc_d[0x1000] __asm("sh7091_oc_d"); +extern volatile uint8_t system_boot_rom[0x200000] __asm("system_boot_rom") __attribute__((aligned(32))); +extern volatile uint8_t aica_wave_memory[0x200000] __asm("aica_wave_memory") __attribute__((aligned(32))); +extern volatile uint8_t texture_memory64[0x800000] __asm("texture_memory64") __attribute__((aligned(32))); +extern volatile uint8_t texture_memory32[0x800000] __asm("texture_memory32") __attribute__((aligned(32))); +extern volatile uint8_t system_memory[0x1000000] __asm("system_memory") __attribute__((aligned(32))); +extern volatile uint8_t ta_fifo_polygon_converter[0x800000] __asm("ta_fifo_polygon_converter") __attribute__((aligned(32))); +extern volatile uint8_t ta_fifo_yuv_converter[0x800000] __asm("ta_fifo_yuv_converter") __attribute__((aligned(32))); +extern volatile uint8_t ta_fifo_texture_memory[0x800000] __asm("ta_fifo_texture_memory") __attribute__((aligned(32))); +extern volatile uint8_t ta_fifo_polygon_converter_mirror[0x800000] __asm("ta_fifo_polygon_converter_mirror") __attribute__((aligned(32))); +extern volatile uint8_t ta_fifo_yuv_converter_mirror[0x800000] __asm("ta_fifo_yuv_converter_mirror") __attribute__((aligned(32))); +extern volatile uint8_t ta_fifo_texture_memory_mirror[0x800000] __asm("ta_fifo_texture_memory_mirror") __attribute__((aligned(32))); +extern volatile uint8_t store_queue[0x4000000] __asm("store_queue") __attribute__((aligned(32))); +extern volatile uint8_t sh7091_oc_d[0x1000] __asm("sh7091_oc_d") __attribute__((aligned(32))); diff --git a/dreamcast2/regs.mk b/dreamcast2/regs.mk index ffa2a84..395539c 100644 --- a/dreamcast2/regs.mk +++ b/dreamcast2/regs.mk @@ -10,11 +10,14 @@ holly/holly.hpp: regs/holly/holly.csv regs/render_block_regs.py holly/holly_bits.hpp: regs/holly/holly_bits.csv regs/render_bits.py python regs/render_bits.py $< holly > $@ -holly/region_array_bits.hpp: regs/holly/region_array_bits.csv regs/render_bits.py - python regs/render_bits.py $< holly region_array > $@ +holly/core/region_array_bits.hpp: regs/holly/core/region_array_bits.csv regs/render_bits.py + python regs/render_bits.py $< holly::core::region_array > $@ -holly/object_list_bits.hpp:regs/holly/object_list_bits.csv regs/render_bits.py - python regs/render_bits.py $< holly object_list > $@ +holly/core/object_list_bits.hpp:regs/holly/core/object_list_bits.csv regs/render_bits.py + python regs/render_bits.py $< holly::core::object_list > $@ + +holly/core/parameter_bits.hpp:regs/holly/core/parameter_bits.csv regs/render_bits.py + python regs/render_bits.py $< holly::core::parameter > $@ # SH7091 diff --git a/dreamcast2/regs/holly/object_list_bits.ods b/dreamcast2/regs/holly/core/object_list_bits.ods similarity index 100% rename from dreamcast2/regs/holly/object_list_bits.ods rename to dreamcast2/regs/holly/core/object_list_bits.ods diff --git a/dreamcast2/regs/holly/core/parameter_bits.ods b/dreamcast2/regs/holly/core/parameter_bits.ods new file mode 100644 index 0000000..657c733 Binary files /dev/null and b/dreamcast2/regs/holly/core/parameter_bits.ods differ diff --git a/dreamcast2/regs/holly/region_array_bits.ods b/dreamcast2/regs/holly/core/region_array_bits.ods similarity index 100% rename from dreamcast2/regs/holly/region_array_bits.ods rename to dreamcast2/regs/holly/core/region_array_bits.ods diff --git a/dreamcast2/regs/render_bits.py b/dreamcast2/regs/render_bits.py index 883704b..1fe60c8 100644 --- a/dreamcast2/regs/render_bits.py +++ b/dreamcast2/regs/render_bits.py @@ -47,8 +47,11 @@ def aggregate_enums(aggregated_rows): def assert_unique_ordered(bits, row): nonlocal all_bits - assert all(bit not in all_bits for bit in bits), (bits, row) - assert max(all_bits, default=32) > max(bits), (all_bits, bits) + #assert all(bit not in all_bits for bit in bits), (bits, row) + if not all(bit not in all_bits for bit in bits): + print("bit overlap", row, file=sys.stderr) + else: + assert max(all_bits, default=32) > max(bits), (all_bits, bits) all_bits |= bits for row in aggregated_rows: diff --git a/dreamcast2/runtime.cpp b/dreamcast2/runtime.cpp index 327bf23..fcfbb83 100644 --- a/dreamcast2/runtime.cpp +++ b/dreamcast2/runtime.cpp @@ -51,9 +51,3 @@ void runtime_init() ((init_t *)(*ctors_start++))(); } } - -extern "C" -void foo() -{ - runtime_init(); -}