examples: add software_ta
This commit is contained in:
parent
4e71e002bf
commit
59708cc3cf
@ -13,7 +13,7 @@ CARCH = -m4-single-only -ml
|
||||
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib
|
||||
CFLAGS += -Wall -Werror -Wfatal-errors
|
||||
CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= -Wno-array-bounds
|
||||
CFLAGS += -mfsca -funsafe-math-optimizations
|
||||
CFLAGS += -mfsca -funsafe-math-optimizations -ffast-math
|
||||
CFLAGS += -I$(dir $(MAKEFILE_PATH))
|
||||
DEPFLAGS = -MMD -E
|
||||
# --print-gc-sections
|
||||
@ -102,7 +102,7 @@ audio.pcm:
|
||||
synth 1 sin 440 vol -10dB
|
||||
mv $@.raw $@
|
||||
|
||||
1ST_READ.BIN: example/macaw_multipass.bin
|
||||
1ST_READ.BIN: example/dump_object_list.bin
|
||||
./scramble $< $@
|
||||
|
||||
%.iso: 1ST_READ.BIN ip.bin
|
||||
@ -152,6 +152,9 @@ holly/ta_global_parameter.hpp: regs/global_parameter_format.csv regs/gen/ta_para
|
||||
holly/ta_vertex_parameter.hpp: regs/vertex_parameter_format.csv regs/gen/ta_parameter_format.py
|
||||
python regs/gen/ta_parameter_format.py $< ta_vertex_parameter > $@
|
||||
|
||||
holly/object_list_data.hpp: regs/object_list.csv regs/gen/core_bits.py
|
||||
python regs/gen/core_bits.py $< object_list_data > $@
|
||||
|
||||
sh7091/sh7091.hpp: regs/sh7091.csv regs/gen/sh7091.py
|
||||
python regs/gen/sh7091.py $< > $@
|
||||
|
||||
@ -163,6 +166,7 @@ clean:
|
||||
-regextype posix-egrep \
|
||||
-regex '.*\.(iso|o|d|bin|elf|cue|gch)$$' \
|
||||
-exec rm {} \;
|
||||
rm 1ST_READ.BIN
|
||||
|
||||
.SUFFIXES:
|
||||
.INTERMEDIATE:
|
||||
|
@ -1217,7 +1217,7 @@ _object_list = """
|
||||
0xeeeeeeee 0xeeeeeeee 0xeeeeeeee 0xeeeeeeee
|
||||
"""
|
||||
|
||||
object_list = [int(i, 16) for i in s.strip().split()]
|
||||
object_list = [int(i, 16) for i in _object_list.strip().split()]
|
||||
|
||||
_isp_tsp = """
|
||||
0x80400000 0x20800000 0x00000000 0x43480000
|
||||
@ -1238,7 +1238,7 @@ _isp_tsp = """
|
||||
0xeeeeeeee 0xeeeeeeee 0xeeeeeeee 0xeeeeeeee
|
||||
"""
|
||||
|
||||
isp_tsp = [int(i, 16) for i in s.strip().split()]
|
||||
isp_tsp = [int(i, 16) for i in _isp_tsp.strip().split()]
|
||||
|
||||
isp_tsp_instruction_word = 0x80400000
|
||||
# Depth Compare Greater | 16Bit UV
|
||||
|
@ -1,4 +1,19 @@
|
||||
import square
|
||||
import triangle
|
||||
|
||||
triangle.isp
|
||||
object_list_size = 16
|
||||
|
||||
for i in range((640 // 32) * (480 // 32)):
|
||||
block_start = (i + 0) * object_list_size
|
||||
block_end = (i + 1) * object_list_size
|
||||
objects = square.object_list[block_start:block_end]
|
||||
|
||||
stride = (640 // 32)
|
||||
|
||||
tile_x = (i % stride)
|
||||
tile_y = (i // stride)
|
||||
|
||||
for j in range(16):
|
||||
if objects[j] & (1 << 28) != 0:
|
||||
break
|
||||
print(f"tile {tile_x: 4} {tile_y: 4}: {hex(objects[j])}")
|
||||
|
@ -1236,7 +1236,7 @@ _isp_tsp = """
|
||||
0xeeeeeeee 0xeeeeeeee 0xeeeeeeee 0xeeeeeeee
|
||||
"""
|
||||
|
||||
isp_tsp = [int(i, 16) for i in s.strip().split()]
|
||||
isp_tsp = [int(i, 16) for i in _isp_tsp.strip().split()]
|
||||
|
||||
isp_tsp_instruction_word = 0x80000000
|
||||
tsp_instruction_word = 0x20800000
|
||||
|
@ -326,7 +326,21 @@ DUMP_OBJECT_LIST_OBJ = \
|
||||
holly/region_array.o \
|
||||
holly/background.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
sh7091/serial.o
|
||||
sh7091/serial.o \
|
||||
libm.o
|
||||
|
||||
example/dump_object_list.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/dump_object_list.elf: LDSCRIPT = $(LIB)/main.lds
|
||||
example/dump_object_list.elf: $(START_OBJ) $(DUMP_OBJECT_LIST_OBJ)
|
||||
|
||||
SOFTWARE_TA_OBJ = \
|
||||
example/software_ta.o \
|
||||
vga.o \
|
||||
holly/core.o \
|
||||
holly/region_array.o \
|
||||
holly/background.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
sh7091/serial.o \
|
||||
libm.o
|
||||
|
||||
example/software_ta.elf: LDSCRIPT = $(LIB)/main.lds
|
||||
example/software_ta.elf: $(START_OBJ) $(SOFTWARE_TA_OBJ)
|
||||
|
238
example/software_ta.cpp
Normal file
238
example/software_ta.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "align.hpp"
|
||||
#include "vga.hpp"
|
||||
|
||||
#include "holly/texture_memory_alloc.hpp"
|
||||
#include "holly/holly.hpp"
|
||||
#include "holly/core.hpp"
|
||||
#include "holly/core_bits.hpp"
|
||||
#include "holly/ta_fifo_polygon_converter.hpp"
|
||||
#include "holly/ta_parameter.hpp"
|
||||
#include "holly/ta_global_parameter.hpp"
|
||||
#include "holly/ta_vertex_parameter.hpp"
|
||||
#include "holly/ta_bits.hpp"
|
||||
#include "holly/isp_tsp.hpp"
|
||||
#include "holly/region_array.hpp"
|
||||
#include "holly/background.hpp"
|
||||
#include "memorymap.hpp"
|
||||
|
||||
#include "sh7091/serial.hpp"
|
||||
|
||||
#include "macaw.hpp"
|
||||
#include "software_ta.hpp"
|
||||
|
||||
uint32_t transform(uint32_t * ta_parameter_buf,
|
||||
const software_ta::quad& quad)
|
||||
{
|
||||
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||
|
||||
const uint32_t parameter_control_word = para_control::para_type::sprite
|
||||
//const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||
| para_control::list_type::opaque
|
||||
| obj_control::col_type::packed_color;
|
||||
|
||||
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
|
||||
| isp_tsp_instruction_word::culling_mode::no_culling;
|
||||
|
||||
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||
| tsp_instruction_word::dst_alpha_instr::zero
|
||||
| tsp_instruction_word::fog_control::no_fog;
|
||||
|
||||
const uint32_t texture_control_word = 0;
|
||||
|
||||
constexpr uint32_t base_color = 0xffff0000;
|
||||
|
||||
parameter.append<ta_global_parameter::sprite>() =
|
||||
ta_global_parameter::sprite(parameter_control_word,
|
||||
isp_tsp_instruction_word,
|
||||
tsp_instruction_word,
|
||||
texture_control_word,
|
||||
base_color,
|
||||
0, // offset_color
|
||||
0, // data_size_for_sort_dma
|
||||
0); // next_address_for_sort_dma
|
||||
|
||||
parameter.append<ta_vertex_parameter::sprite_type_0>() =
|
||||
ta_vertex_parameter::sprite_type_0(para_control::para_type::vertex_parameter,
|
||||
quad.a.x,
|
||||
quad.a.y,
|
||||
0.1f,
|
||||
quad.b.x,
|
||||
quad.b.y,
|
||||
0.1f,
|
||||
quad.c.x,
|
||||
quad.c.y,
|
||||
0.1f,
|
||||
quad.d.x,
|
||||
quad.d.y);
|
||||
|
||||
parameter.append<ta_global_parameter::end_of_list>() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
|
||||
return parameter.offset;
|
||||
}
|
||||
|
||||
void init_texture_memory(const struct opb_size& opb_size)
|
||||
{
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
// zeroize
|
||||
for (uint32_t i = 0; i < 0x00100000 / 4; i++) {
|
||||
mem->object_list[i] = 0xeeeeeeee;
|
||||
mem->isp_tsp_parameters[i] = 0xeeeeeeee;
|
||||
}
|
||||
|
||||
background_parameter(mem->background, 0xff222200);
|
||||
|
||||
region_array2(mem->region_array,
|
||||
(offsetof (struct texture_memory_alloc, object_list)),
|
||||
640 / 32, // width
|
||||
480 / 32, // height
|
||||
opb_size
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t _ta_parameter_buf[((32 * (32 + 2)) + 32) / 4];
|
||||
|
||||
union u32_u8 {
|
||||
uint32_t u32;
|
||||
uint8_t u8[4];
|
||||
};
|
||||
static_assert((sizeof (union u32_u8)) == 4);
|
||||
|
||||
void dump()
|
||||
{
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
constexpr uint32_t screen_ol_size = 8 * 4 * (640 / 32) * (480 / 32);
|
||||
for (uint32_t i = 0; i < (screen_ol_size + 0x100) / 4; i++) {
|
||||
union u32_u8 n;
|
||||
n.u32 = mem->object_list[i];
|
||||
|
||||
if (((i * 4) & 0x1f) == 0)
|
||||
serial::character('\n');
|
||||
//if (((i * 4) & 0x3f) == 0)
|
||||
// serial::character('\n');
|
||||
|
||||
serial::integer<uint32_t>(n.u32, ' ');
|
||||
}
|
||||
|
||||
serial::character('\n');
|
||||
serial::character('\n');
|
||||
serial::character('\n');
|
||||
|
||||
for (uint32_t i = 0; i < (0x100) / 4; i++) {
|
||||
union u32_u8 n;
|
||||
n.u32 = mem->isp_tsp_parameters[i];
|
||||
|
||||
if (((i * 4) & 0x1f) == 0)
|
||||
serial::character('\n');
|
||||
|
||||
serial::integer<uint32_t>(n.u32, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
constexpr float half_degree = 0.01745329f / 2.f;
|
||||
|
||||
constexpr software_ta::point rotate(const software_ta::point& p, const float theta)
|
||||
{
|
||||
float x = p.x;
|
||||
float y = p.y;
|
||||
float x1;
|
||||
|
||||
x1 = x * __builtin_cosf(theta) - y * __builtin_sinf(theta);
|
||||
y = x * __builtin_sinf(theta) + y * __builtin_cosf(theta);
|
||||
x = x1;
|
||||
|
||||
x *= 240.f;
|
||||
y *= 240.f;
|
||||
x += 320.f;
|
||||
y += 240.f;
|
||||
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vga();
|
||||
|
||||
// The address of `ta_parameter_buf` must be a multiple of 32 bytes.
|
||||
// This is mandatory for ch2-dma to the ta fifo polygon converter.
|
||||
uint32_t * ta_parameter_buf = align_32byte(_ta_parameter_buf);
|
||||
|
||||
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
|
||||
| ta_alloc_ctrl::tm_opb::no_list
|
||||
| ta_alloc_ctrl::t_opb::no_list
|
||||
| ta_alloc_ctrl::om_opb::no_list
|
||||
| ta_alloc_ctrl::o_opb::_8x4byte;
|
||||
|
||||
constexpr struct opb_size opb_size = { .opaque = 8 * 4
|
||||
, .opaque_modifier = 0
|
||||
, .translucent = 0
|
||||
, .translucent_modifier = 0
|
||||
, .punch_through = 0
|
||||
};
|
||||
|
||||
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||
| softreset::ta_soft_reset;
|
||||
holly.SOFTRESET = 0;
|
||||
|
||||
core_init();
|
||||
init_texture_memory(opb_size);
|
||||
|
||||
float theta = 0;
|
||||
uint32_t frame_ix = 0;
|
||||
constexpr uint32_t num_frames = 1;
|
||||
|
||||
bool hardware_ta = false;
|
||||
|
||||
constexpr software_ta::quad q = {
|
||||
{-0.5f, 0.5f},
|
||||
{-0.5f, -0.5f},
|
||||
{ 0.5f, -0.5f},
|
||||
{ 0.5f, 0.5f},
|
||||
};
|
||||
|
||||
while (true) {
|
||||
if ((frame_ix & 255) == 0) {
|
||||
holly.SOFTRESET = softreset::pipeline_soft_reset;
|
||||
holly.SOFTRESET = 0;
|
||||
hardware_ta = !hardware_ta;
|
||||
if (hardware_ta)
|
||||
serial::string("now using hardware TA\n");
|
||||
else
|
||||
serial::string("now using software TA\n");
|
||||
}
|
||||
|
||||
software_ta::quad qq;
|
||||
qq.a = rotate(q.a, theta);
|
||||
qq.b = rotate(q.b, theta);
|
||||
qq.c = rotate(q.c, theta);
|
||||
qq.d = rotate(q.d, theta);
|
||||
|
||||
if (hardware_ta) {
|
||||
ta_polygon_converter_init(opb_size.total(),
|
||||
ta_alloc,
|
||||
640 / 32,
|
||||
480 / 32);
|
||||
uint32_t ta_parameter_size = transform(ta_parameter_buf, qq);
|
||||
ta_polygon_converter_transfer(ta_parameter_buf, ta_parameter_size);
|
||||
ta_wait_opaque_list();
|
||||
} else {
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
software_ta::object_pointer_blocks<8>(&mem->object_list[0], qq);
|
||||
software_ta::isp_tsp_parameters(&mem->isp_tsp_parameters[0], qq);
|
||||
}
|
||||
|
||||
core_start_render(frame_ix, num_frames);
|
||||
core_wait_end_of_render_video();
|
||||
|
||||
while (!spg_status::vsync(holly.SPG_STATUS));
|
||||
core_flip(frame_ix, num_frames);
|
||||
while (spg_status::vsync(holly.SPG_STATUS));
|
||||
|
||||
frame_ix += 1;
|
||||
theta += half_degree;
|
||||
}
|
||||
}
|
202
example/software_ta.hpp
Normal file
202
example/software_ta.hpp
Normal file
@ -0,0 +1,202 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "holly/object_list_data.hpp"
|
||||
#include "holly/isp_tsp.hpp"
|
||||
|
||||
namespace software_ta {
|
||||
|
||||
constexpr uint32_t tile_size = 32;
|
||||
|
||||
constexpr uint32_t framebuffer_width = 640;
|
||||
constexpr uint32_t framebuffer_height = 480;
|
||||
|
||||
constexpr uint32_t tile_width = framebuffer_width / tile_size;
|
||||
constexpr uint32_t tile_height = framebuffer_height / tile_size;
|
||||
|
||||
struct point {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct quad {
|
||||
point a;
|
||||
point b;
|
||||
point c;
|
||||
point d;
|
||||
};
|
||||
|
||||
struct bounding_box {
|
||||
point min;
|
||||
point max;
|
||||
|
||||
bounding_box(const quad q)
|
||||
{
|
||||
min.x = (q.a.x < q.b.x) ? q.a.x : q.b.x;
|
||||
min.x = (min.x < q.c.x) ? min.x : q.c.x;
|
||||
min.x = (min.x < q.d.x) ? min.x : q.d.x;
|
||||
|
||||
min.y = (q.a.y < q.b.y) ? q.a.y : q.b.y;
|
||||
min.y = (min.y < q.c.y) ? min.y : q.c.y;
|
||||
min.y = (min.y < q.d.y) ? min.y : q.d.y;
|
||||
|
||||
max.x = (q.a.x > q.b.x) ? q.a.x : q.b.x;
|
||||
max.x = (max.x > q.c.x) ? max.x : q.c.x;
|
||||
max.x = (max.x > q.d.x) ? max.x : q.d.x;
|
||||
|
||||
max.y = (q.a.y > q.b.y) ? q.a.y : q.b.y;
|
||||
max.y = (max.y > q.c.y) ? max.y : q.c.y;
|
||||
max.y = (max.y > q.d.y) ? max.y : q.d.y;
|
||||
}
|
||||
};
|
||||
|
||||
template <int32_t max>
|
||||
constexpr uint32_t clamp_int(const float x)
|
||||
{
|
||||
const int32_t n = static_cast<int32_t>(x);
|
||||
return (n < 0 ? 0 : (n >= max ? (max - 1) : x));
|
||||
}
|
||||
|
||||
constexpr uint32_t tile_start_x(bounding_box bb)
|
||||
{
|
||||
return clamp_int<framebuffer_width>(__builtin_floorf(bb.min.x / tile_size));
|
||||
}
|
||||
|
||||
constexpr uint32_t tile_start_y(bounding_box bb)
|
||||
{
|
||||
return clamp_int<framebuffer_height>(__builtin_floorf(bb.min.y / tile_size));
|
||||
}
|
||||
|
||||
constexpr uint32_t tile_end_x(bounding_box bb)
|
||||
{
|
||||
return clamp_int<framebuffer_height>(__builtin_ceilf(bb.max.x / tile_size));
|
||||
}
|
||||
|
||||
constexpr uint32_t tile_end_y(bounding_box bb)
|
||||
{
|
||||
return clamp_int<framebuffer_height>(__builtin_ceilf(bb.max.y / tile_size));
|
||||
}
|
||||
|
||||
template <int N>
|
||||
struct object_pointer_block {
|
||||
uint32_t pointer[N];
|
||||
};
|
||||
static_assert((sizeof (object_pointer_block<8>)) == 32);
|
||||
|
||||
template <int N>
|
||||
void object_pointer_blocks(volatile uint32_t * mem, const quad& quad)
|
||||
{
|
||||
auto block = reinterpret_cast<volatile object_pointer_block<N> *>(mem);
|
||||
uint8_t tile_indices[tile_height][tile_width];
|
||||
for (uint32_t i = 0; i < tile_width * tile_height; i++) {
|
||||
reinterpret_cast<uint8_t *>(tile_indices)[i] = 0;
|
||||
}
|
||||
|
||||
bounding_box bb(quad);
|
||||
|
||||
for (uint32_t y = tile_start_y(bb); y < tile_end_y(bb); y++) {
|
||||
for (uint32_t x = tile_start_x(bb); x < tile_end_x(bb); x++) {
|
||||
uint8_t& ix = tile_indices[y][x];
|
||||
auto& opb = block[y * tile_width + x];
|
||||
opb.pointer[ix] = object_list_data::pointer_type::quad_array
|
||||
| object_list_data::quad_array::number_of_quads(0)
|
||||
| object_list_data::quad_array::skip(1)
|
||||
| object_list_data::quad_array::start(0);
|
||||
ix++;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < tile_height; y++) {
|
||||
for (uint32_t x = 0; x < tile_width; x++) {
|
||||
uint8_t& ix = tile_indices[y][x];
|
||||
auto& opb = block[y * tile_width + x];
|
||||
opb.pointer[ix] = object_list_data::pointer_type::object_pointer_block_link
|
||||
| object_list_data::object_pointer_block_link::end_of_list;
|
||||
ix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct __untextured_quad_vertex {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
struct __untextured_quad {
|
||||
uint32_t isp_tsp_instruction_word;
|
||||
uint32_t tsp_instruction_word;
|
||||
uint32_t texture_control_word;
|
||||
__untextured_quad_vertex a;
|
||||
__untextured_quad_vertex b;
|
||||
__untextured_quad_vertex c;
|
||||
__untextured_quad_vertex d;
|
||||
};
|
||||
|
||||
void isp_tsp_parameters(volatile uint32_t * mem, const quad& quad)
|
||||
{
|
||||
auto params = reinterpret_cast<volatile __untextured_quad *>(mem);
|
||||
params->isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater
|
||||
| isp_tsp_instruction_word::culling_mode::no_culling;
|
||||
|
||||
params->tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||
| tsp_instruction_word::dst_alpha_instr::zero
|
||||
| tsp_instruction_word::fog_control::no_fog;
|
||||
|
||||
params->texture_control_word = 0;
|
||||
|
||||
params->a.x = quad.a.x;
|
||||
params->a.y = quad.a.y;
|
||||
params->a.z = 0.1f;
|
||||
params->b.color = 0; // invalid
|
||||
|
||||
params->b.x = quad.b.x;
|
||||
params->b.y = quad.b.y;
|
||||
params->b.z = 0.1f;
|
||||
params->b.color = 0; // invalid
|
||||
|
||||
params->c.x = quad.c.x;
|
||||
params->c.y = quad.c.y;
|
||||
params->c.z = 0.1f;
|
||||
params->c.color = 0xffff0000;
|
||||
|
||||
params->d.x = quad.d.x;
|
||||
params->d.y = quad.d.y;
|
||||
params->d.z = 0.f; // invalid
|
||||
params->b.color = 0; // invalid
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
int main()
|
||||
{
|
||||
using namespace software_ta;
|
||||
|
||||
quad q = {
|
||||
{200.f, 360.f},
|
||||
{200.f, 120.f},
|
||||
{440.f, 120.f},
|
||||
{440.f, 360.f},
|
||||
};
|
||||
|
||||
uint32_t opb_mem[300 * 8];
|
||||
|
||||
object_pointer_blocks<8>(opb_mem, q);
|
||||
for (int i = 0; i < 300 * 8; i++) {
|
||||
if ((i & 7) == 0)
|
||||
std::cout << '\n' << std::dec << i / 8 << ' ';
|
||||
std::cout << std::hex << opb_mem[i] << ' ';
|
||||
}
|
||||
std::cout << '\n';
|
||||
|
||||
uint32_t param_mem[32];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
param_mem[i] = 0xeeeeeeee;
|
||||
}
|
||||
isp_tsp_parameters(param_mem, q);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
std::cout << std::hex << param_mem[i] << '\n';
|
||||
}
|
||||
}
|
||||
*/
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace isp_tsp_instruction_word {
|
||||
|
53
holly/object_list_data.hpp
Normal file
53
holly/object_list_data.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../float_uint32.hpp"
|
||||
|
||||
namespace object_list_data {
|
||||
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; }
|
||||
}
|
||||
|
||||
}
|
92
libm.c
Normal file
92
libm.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
|
||||
/*
|
||||
musl as a whole is licensed under the following standard MIT license:
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Copyright © 2005-2020 Rich Felker, et al.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline void fp_force_evalf(float x)
|
||||
{
|
||||
volatile float y;
|
||||
y = x;
|
||||
}
|
||||
|
||||
#define FORCE_EVAL(x) do { \
|
||||
fp_force_evalf(x); \
|
||||
} while(0)
|
||||
|
||||
float floorf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
int e = (int)(u.i >> 23 & 0xff) - 0x7f;
|
||||
uint32_t m;
|
||||
|
||||
if (e >= 23)
|
||||
return x;
|
||||
if (e >= 0) {
|
||||
m = 0x007fffff >> e;
|
||||
if ((u.i & m) == 0)
|
||||
return x;
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
if (u.i >> 31)
|
||||
u.i += m;
|
||||
u.i &= ~m;
|
||||
} else {
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
if (u.i >> 31 == 0)
|
||||
u.i = 0;
|
||||
else if (u.i << 1)
|
||||
u.f = -1.0;
|
||||
}
|
||||
return u.f;
|
||||
}
|
||||
|
||||
float ceilf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
int e = (int)(u.i >> 23 & 0xff) - 0x7f;
|
||||
uint32_t m;
|
||||
|
||||
if (e >= 23)
|
||||
return x;
|
||||
if (e >= 0) {
|
||||
m = 0x007fffff >> e;
|
||||
if ((u.i & m) == 0)
|
||||
return x;
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
if (u.i >> 31 == 0)
|
||||
u.i += m;
|
||||
u.i &= ~m;
|
||||
} else {
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
if (u.i >> 31)
|
||||
u.f = -0.0;
|
||||
else if (u.i << 1)
|
||||
u.f = 1.0;
|
||||
}
|
||||
return u.f;
|
||||
}
|
20
main.lds
20
main.lds
@ -6,7 +6,15 @@ MEMORY
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
. = ORIGIN(p1ram);
|
||||
. = ORIGIN(p2ram);
|
||||
|
||||
.text ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.text.start))
|
||||
*(.text.startup.*)
|
||||
} > p2ram AT>p1ram
|
||||
|
||||
. = ORIGIN(p1ram) + (. - ORIGIN(p2ram));
|
||||
|
||||
.text ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
@ -34,16 +42,6 @@ SECTIONS
|
||||
KEEP(*(.ctors.*))
|
||||
} > p1ram
|
||||
|
||||
. = ORIGIN(p2ram) + (. - ORIGIN(p1ram));
|
||||
|
||||
.text.p2ram ALIGN(4) : SUBALIGN(4)
|
||||
{
|
||||
*(.p2ram)
|
||||
*(.p2ram.*)
|
||||
} > p2ram AT>p1ram
|
||||
|
||||
. = ORIGIN(p1ram) + (. - ORIGIN(p2ram));
|
||||
|
||||
.bss ALIGN(4) (NOLOAD) : SUBALIGN(4)
|
||||
{
|
||||
*(.bss)
|
||||
|
@ -10,7 +10,7 @@ from generate import renderer
|
||||
def aggregate_registers(d):
|
||||
aggregated = defaultdict(list)
|
||||
for row in d:
|
||||
assert row["register_name"] != ""
|
||||
#assert row["register_name"] != ""
|
||||
aggregated[row["register_name"]].append(row)
|
||||
return dict(aggregated)
|
||||
|
||||
@ -218,7 +218,8 @@ def render_enum(enum_def):
|
||||
yield "}"
|
||||
|
||||
def render_register(register):
|
||||
yield f"namespace {register.name.lower()} {{"
|
||||
if register.name != "":
|
||||
yield f"namespace {register.name.lower()} {{"
|
||||
|
||||
last = None
|
||||
for ix, bit_def in enumerate(register.defs):
|
||||
@ -232,10 +233,14 @@ def render_register(register):
|
||||
yield from render_defs(bit_def)
|
||||
last = bit_def
|
||||
|
||||
yield "}"
|
||||
if register.name != "":
|
||||
yield "}"
|
||||
yield ""
|
||||
|
||||
def render_registers(registers):
|
||||
def render_registers(registers, file_namespace):
|
||||
if file_namespace is not None:
|
||||
yield f"namespace {file_namespace} {{"
|
||||
|
||||
last_block = None
|
||||
for register in registers:
|
||||
if register.block != last_block:
|
||||
@ -253,6 +258,9 @@ def render_registers(registers):
|
||||
if last_block is not None:
|
||||
yield '}' # end of block namespace
|
||||
|
||||
if file_namespace is not None:
|
||||
yield '}' # end of file namespace
|
||||
|
||||
def header():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
@ -263,9 +271,10 @@ def header():
|
||||
|
||||
if __name__ == "__main__":
|
||||
d = read_input(sys.argv[1])
|
||||
file_namespace = sys.argv[2] if len(sys.argv) > 2 else None
|
||||
aggregated = aggregate_registers(d)
|
||||
registers = aggregate_all_enums(aggregated)
|
||||
render, out = renderer()
|
||||
render(header())
|
||||
render(render_registers(registers))
|
||||
render(render_registers(registers, file_namespace))
|
||||
sys.stdout.write(out.getvalue())
|
||||
|
28
regs/object_list.csv
Normal file
28
regs/object_list.csv
Normal file
@ -0,0 +1,28 @@
|
||||
"register_name","enum_name","bits","bit_name","value","mask","description"
|
||||
,"pointer_type","31-29","triangle_strip","0b000",,
|
||||
,"pointer_type","31-29","triangle_array","0b100",,
|
||||
,"pointer_type","31-29","quad_array","0b101",,
|
||||
,"pointer_type","31-29","object_pointer_block_link","0b111",,
|
||||
,,,,,,
|
||||
"triangle_strip","mask","30-25","t0","0b100000",,
|
||||
"triangle_strip","mask","30-25","t1","0b010000",,
|
||||
"triangle_strip","mask","30-25","t2","0b001000",,
|
||||
"triangle_strip","mask","30-25","t3","0b000100",,
|
||||
"triangle_strip","mask","30-25","t4","0b000010",,
|
||||
"triangle_strip","mask","30-25","t5","0b000001",,
|
||||
"triangle_strip",,"24","shadow","1",,
|
||||
"triangle_strip",,"23-21","skip",,"0b111",
|
||||
"triangle_strip",,"20-0","start",,"0x1fffff",
|
||||
,,,,,,
|
||||
"triangle_array",,"28-25","number_of_triangles",,"0b1111",
|
||||
"triangle_array",,"24","shadow","1",,
|
||||
"triangle_array",,"23-21","skip",,"0b111",
|
||||
"triangle_array",,"20-0","start",,"0x1fffff",
|
||||
,,,,,,
|
||||
"quad_array",,"28-25","number_of_quads",,"0b1111",
|
||||
"quad_array",,"24","shadow","1",,
|
||||
"quad_array",,"23-21","skip",,"0b111",
|
||||
"quad_array",,"20-0","start",,"0x1fffff",
|
||||
,,,,,,
|
||||
"object_pointer_block_link",,"28","end_of_list","1",,
|
||||
"object_pointer_block_link",,"23-0","next_pointer_block",,"0xfffffc",
|
|
BIN
regs/object_list.ods
Normal file
BIN
regs/object_list.ods
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user