diff --git a/common.mk b/common.mk index 300b9c6..f108004 100644 --- a/common.mk +++ b/common.mk @@ -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: diff --git a/dumps/square.py b/dumps/square.py index 1e60b28..3c6b760 100644 --- a/dumps/square.py +++ b/dumps/square.py @@ -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 diff --git a/dumps/test.py b/dumps/test.py index 2823db4..2bcc077 100644 --- a/dumps/test.py +++ b/dumps/test.py @@ -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])}") diff --git a/dumps/triangle.py b/dumps/triangle.py index 755d3c2..68d3703 100644 --- a/dumps/triangle.py +++ b/dumps/triangle.py @@ -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 diff --git a/example/example.mk b/example/example.mk index d033e7a..9162562 100644 --- a/example/example.mk +++ b/example/example.mk @@ -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) diff --git a/example/software_ta.cpp b/example/software_ta.cpp new file mode 100644 index 0000000..9c9e18c --- /dev/null +++ b/example/software_ta.cpp @@ -0,0 +1,238 @@ +#include + +#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(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(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(para_control::para_type::end_of_list); + + return parameter.offset; +} + +void init_texture_memory(const struct opb_size& opb_size) +{ + auto mem = reinterpret_cast(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(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(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(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(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; + } +} diff --git a/example/software_ta.hpp b/example/software_ta.hpp new file mode 100644 index 0000000..be71bf0 --- /dev/null +++ b/example/software_ta.hpp @@ -0,0 +1,202 @@ +#include + +#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 +constexpr uint32_t clamp_int(const float x) +{ + const int32_t n = static_cast(x); + return (n < 0 ? 0 : (n >= max ? (max - 1) : x)); +} + +constexpr uint32_t tile_start_x(bounding_box bb) +{ + return clamp_int(__builtin_floorf(bb.min.x / tile_size)); +} + +constexpr uint32_t tile_start_y(bounding_box bb) +{ + return clamp_int(__builtin_floorf(bb.min.y / tile_size)); +} + +constexpr uint32_t tile_end_x(bounding_box bb) +{ + return clamp_int(__builtin_ceilf(bb.max.x / tile_size)); +} + +constexpr uint32_t tile_end_y(bounding_box bb) +{ + return clamp_int(__builtin_ceilf(bb.max.y / tile_size)); +} + +template +struct object_pointer_block { + uint32_t pointer[N]; +}; +static_assert((sizeof (object_pointer_block<8>)) == 32); + +template +void object_pointer_blocks(volatile uint32_t * mem, const quad& quad) +{ + auto block = reinterpret_cast *>(mem); + uint8_t tile_indices[tile_height][tile_width]; + for (uint32_t i = 0; i < tile_width * tile_height; i++) { + reinterpret_cast(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(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'; + } +} +*/ diff --git a/holly/isp_tsp.hpp b/holly/isp_tsp.hpp index 9886b30..4f6ae1a 100644 --- a/holly/isp_tsp.hpp +++ b/holly/isp_tsp.hpp @@ -1,3 +1,5 @@ +#pragma once + #include namespace isp_tsp_instruction_word { diff --git a/holly/object_list_data.hpp b/holly/object_list_data.hpp new file mode 100644 index 0000000..c6227ab --- /dev/null +++ b/holly/object_list_data.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include + +#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; } + } + +} diff --git a/libm.c b/libm.c new file mode 100644 index 0000000..9025c39 --- /dev/null +++ b/libm.c @@ -0,0 +1,92 @@ +#include + +#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; +} diff --git a/main.lds b/main.lds index 271d758..3a8d78a 100644 --- a/main.lds +++ b/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) diff --git a/regs/gen/core_bits.py b/regs/gen/core_bits.py index f48e345..2b66ddb 100644 --- a/regs/gen/core_bits.py +++ b/regs/gen/core_bits.py @@ -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()) diff --git a/regs/object_list.csv b/regs/object_list.csv new file mode 100644 index 0000000..27106b6 --- /dev/null +++ b/regs/object_list.csv @@ -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", diff --git a/regs/object_list.ods b/regs/object_list.ods new file mode 100644 index 0000000..b3408e6 Binary files /dev/null and b/regs/object_list.ods differ