dreamcast2: add triangle_core

This commit is contained in:
Zack Buhman 2025-08-25 16:40:15 -05:00
parent b99d646365
commit dacdad6132
23 changed files with 749 additions and 217 deletions

View File

@ -7,3 +7,9 @@ CFLAGS += -I$(MAKEFILE_PATH)
LIB ?= $(MAKEFILE_PATH) LIB ?= $(MAKEFILE_PATH)
include example/example.mk include example/example.mk
clean:
find -P \
-regextype posix-egrep \
-regex '.*\.(iso|o|d|bin|elf|cue|gch)$$' \
-exec rm {} \;

View File

@ -1,6 +1,6 @@
system_boot_rom = 0xa0000000; system_boot_rom = 0xa0000000;
system = 0xa05f6800; systembus = 0xa05f6800;
maple_if = 0xa05f6c00; maple_if = 0xa05f6c00;
gdrom_if = 0xa05f7000; gdrom_if = 0xa05f7000;
g1_if = 0xa05f7400; g1_if = 0xa05f7400;

View File

@ -2,15 +2,15 @@ SECTIONS
{ {
. = ORIGIN(p2ram); . = ORIGIN(p2ram);
.text.start : .text.start ALIGN(4) :
{ {
KEEP(*(.text.start)) KEEP(*(.text.start))
*(.text.startup.*) *(.text.start.*)
} > p2ram AT>p1ram } > p2ram AT>p1ram
. = ORIGIN(p1ram) + (. - ORIGIN(p2ram)); . = ORIGIN(p1ram) + (. - ORIGIN(p2ram));
.text : .text ALIGN(4) : SUBALIGN(4)
{ {
*(.text.*) *(.text.*)
*(.text) *(.text)

View File

@ -7,3 +7,10 @@ FRAMEBUFFER_SHADED_OBJ = \
example/framebuffer_shaded.elf: LDSCRIPT = $(LIB)/main.lds example/framebuffer_shaded.elf: LDSCRIPT = $(LIB)/main.lds
example/framebuffer_shaded.elf: $(START_OBJ) $(FRAMEBUFFER_SHADED_OBJ) 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)

View File

@ -4,7 +4,7 @@
void main() 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 y = 0; y < 480; y++) {
for (int x = 0; x < 640; x++) { for (int x = 0; x < 640; x++) {

View File

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

View File

@ -0,0 +1,51 @@
#pragma once
#include <cstdint>
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; }
}
}

View File

@ -0,0 +1,144 @@
#include <cstdint>
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 <texture_sel T, volume_sel V, offset_sel O>
struct vertex;
template <>
struct vertex<non_texture, one_volume, non_offset> {
float x;
float y;
float z;
uint32_t base_color;
};
template <>
struct vertex<non_texture, two_volumes, non_offset> {
float x;
float y;
float z;
struct {
uint32_t base_color;
} volume[2];
};
template <>
struct vertex<non_texture, one_volume, offset> {
float x;
float y;
float z;
uint32_t base_color;
uint32_t offset_color;
};
template <>
struct vertex<non_texture, two_volumes, offset> {
float x;
float y;
float z;
struct {
uint32_t base_color;
uint32_t offset_color;
} volume[2];
};
template <>
struct vertex<texture, one_volume, non_offset> {
float x;
float y;
float z;
float u;
float v;
uint32_t base_color;
};
template <>
struct vertex<texture, two_volumes, non_offset> {
float x;
float y;
float z;
struct {
float u;
float v;
uint32_t base_color;
} volume[2];
};
template <>
struct vertex<texture, one_volume, offset> {
float x;
float y;
float z;
float u;
float v;
uint32_t base_color;
uint32_t offset_color;
};
template <>
struct vertex<texture, two_volumes, offset> {
float x;
float y;
float z;
struct {
float u;
float v;
uint32_t base_color;
uint32_t offset_color;
} volume[2];
};
template <int N, texture_sel T=non_texture, volume_sel V=one_volume, offset_sel O=non_offset>
struct isp_tsp_parameter;
template <int N, texture_sel T, offset_sel O>
struct isp_tsp_parameter<N, T, one_volume, O> {
uint32_t isp_tsp_instruction_word;
uint32_t tsp_instruction_word;
uint32_t texture_control_word;
struct vertex<T, one_volume, O> vertex[N];
};
template <int N, texture_sel T, offset_sel O>
struct isp_tsp_parameter<N, T, two_volumes, O> {
uint32_t isp_tsp_instruction_word;
struct {
uint32_t tsp_instruction_word;
uint32_t texture_control_word;
} volume[2];
struct vertex<T, two_volumes, O> 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);
}

View File

@ -0,0 +1,195 @@
#pragma once
#include <cstdint>
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; }
}
}

View File

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

View File

@ -0,0 +1,39 @@
#pragma once
#include <cstdint>
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);
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
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; }
}
}

View File

@ -1,53 +0,0 @@
#pragma once
#include <cstdint>
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; }
}
}
}

View File

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

View File

@ -1,41 +0,0 @@
#pragma once
#include <cstdint>
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);
}
}

View File

@ -1,22 +0,0 @@
#pragma once
#include <cstdint>
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; }
}
}
}

View File

@ -1,15 +1,15 @@
#include <cstdint> #include <cstdint>
extern volatile uint8_t system_boot_rom[0x200000] __asm("system_boot_rom"); 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"); 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"); extern volatile uint8_t texture_memory64[0x800000] __asm("texture_memory64") __attribute__((aligned(32)));
extern volatile uint8_t texture_memory32[0x800000] __asm("texture_memory32"); extern volatile uint8_t texture_memory32[0x800000] __asm("texture_memory32") __attribute__((aligned(32)));
extern volatile uint8_t system_memory[0x1000000] __asm("system_memory"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); extern volatile uint8_t sh7091_oc_d[0x1000] __asm("sh7091_oc_d") __attribute__((aligned(32)));

View File

@ -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 holly/holly_bits.hpp: regs/holly/holly_bits.csv regs/render_bits.py
python regs/render_bits.py $< holly > $@ python regs/render_bits.py $< holly > $@
holly/region_array_bits.hpp: regs/holly/region_array_bits.csv regs/render_bits.py holly/core/region_array_bits.hpp: regs/holly/core/region_array_bits.csv regs/render_bits.py
python regs/render_bits.py $< holly region_array > $@ python regs/render_bits.py $< holly::core::region_array > $@
holly/object_list_bits.hpp:regs/holly/object_list_bits.csv regs/render_bits.py holly/core/object_list_bits.hpp:regs/holly/core/object_list_bits.csv regs/render_bits.py
python regs/render_bits.py $< holly object_list > $@ 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 # SH7091

Binary file not shown.

View File

@ -47,7 +47,10 @@ def aggregate_enums(aggregated_rows):
def assert_unique_ordered(bits, row): def assert_unique_ordered(bits, row):
nonlocal all_bits nonlocal all_bits
assert all(bit not in all_bits for bit in bits), (bits, row) #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) assert max(all_bits, default=32) > max(bits), (all_bits, bits)
all_bits |= bits all_bits |= bits

View File

@ -51,9 +51,3 @@ void runtime_init()
((init_t *)(*ctors_start++))(); ((init_t *)(*ctors_start++))();
} }
} }
extern "C"
void foo()
{
runtime_init();
}