example: add video_output example
The intent of this example is to change video output modes in response to swapping the cable type.
This commit is contained in:
parent
2a121625c8
commit
f8dc9f1250
@ -1,3 +1,15 @@
|
||||
VIDEO_OUTPUT_OBJ = \
|
||||
example/video_output.o \
|
||||
holly/video_output.o \
|
||||
holly/core.o \
|
||||
holly/region_array.o \
|
||||
holly/background.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
sh7091/serial.o
|
||||
|
||||
example/video_output.elf: LDSCRIPT = $(LIB)/alt.lds
|
||||
example/video_output.elf: $(START_OBJ) $(VIDEO_OUTPUT_OBJ)
|
||||
|
||||
SPRITE_OBJ = \
|
||||
example/sprite.o \
|
||||
holly/video_output.o \
|
||||
|
@ -155,7 +155,7 @@ void main()
|
||||
}
|
||||
};
|
||||
|
||||
constexpr uint32_t tiles = (640 / 32) * (320 / 32);
|
||||
constexpr uint32_t tiles = (640 / 32) * (480 / 32);
|
||||
|
||||
uint32_t frame_ix = 0;
|
||||
constexpr uint32_t num_frames = 1;
|
||||
|
@ -21,7 +21,7 @@ struct vertex {
|
||||
};
|
||||
|
||||
// screen space coordinates
|
||||
const struct vertex quad_verticies[4] = {
|
||||
const struct vertex quad_vertices[4] = {
|
||||
{ 200.f, 360.f, 0.1f },
|
||||
{ 200.f, 120.f, 0.1f },
|
||||
{ 440.f, 120.f, 0.1f },
|
||||
@ -35,17 +35,17 @@ uint32_t transform(uint32_t * ta_parameter_buf)
|
||||
constexpr uint32_t base_color = 0xffff0000;
|
||||
parameter.append<global_sprite>() = global_sprite(base_color);
|
||||
parameter.append<vertex_sprite_type_0>() =
|
||||
vertex_sprite_type_0(quad_verticies[0].x,
|
||||
quad_verticies[0].y,
|
||||
quad_verticies[0].z,
|
||||
quad_verticies[1].x,
|
||||
quad_verticies[1].y,
|
||||
quad_verticies[1].z,
|
||||
quad_verticies[2].x,
|
||||
quad_verticies[2].y,
|
||||
quad_verticies[2].z,
|
||||
quad_verticies[3].x,
|
||||
quad_verticies[3].y);
|
||||
vertex_sprite_type_0(quad_vertices[0].x,
|
||||
quad_vertices[0].y,
|
||||
quad_vertices[0].z,
|
||||
quad_vertices[1].x,
|
||||
quad_vertices[1].y,
|
||||
quad_vertices[1].z,
|
||||
quad_vertices[2].x,
|
||||
quad_vertices[2].y,
|
||||
quad_vertices[2].z,
|
||||
quad_vertices[3].x,
|
||||
quad_vertices[3].y);
|
||||
// curiously, there is no quad_veritices[3].z in vertex_sprite_type_0
|
||||
|
||||
parameter.append<global_end_of_list>() = global_end_of_list();
|
||||
@ -90,7 +90,7 @@ void main()
|
||||
, .punch_through = 0
|
||||
};
|
||||
|
||||
constexpr uint32_t tiles = (640 / 32) * (320 / 32);
|
||||
constexpr uint32_t tiles = (640 / 32) * (480 / 32);
|
||||
|
||||
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||
| softreset::ta_soft_reset;
|
||||
|
187
example/video_output.cpp
Normal file
187
example/video_output.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "align.hpp"
|
||||
#include "dve.hpp"
|
||||
#include "memorymap.hpp"
|
||||
#include "holly/holly.hpp"
|
||||
#include "holly/core.hpp"
|
||||
#include "holly/core_bits.hpp"
|
||||
#include "holly/video_output.hpp"
|
||||
#include "holly/ta_bits.hpp"
|
||||
#include "holly/ta_parameter.hpp"
|
||||
#include "holly/ta_global_parameter.hpp"
|
||||
#include "holly/ta_vertex_parameter.hpp"
|
||||
#include "holly/ta_fifo_polygon_converter.hpp"
|
||||
#include "holly/isp_tsp.hpp"
|
||||
#include "holly/texture_memory_alloc.hpp"
|
||||
#include "holly/background.hpp"
|
||||
#include "holly/region_array.hpp"
|
||||
|
||||
#include "sh7091/serial.hpp"
|
||||
|
||||
void print_cable_type_resolution(const uint32_t cable_type, const struct video_output::framebuffer_resolution& framebuffer_resolution)
|
||||
{
|
||||
serial::string("cable type: ");
|
||||
switch (cable_type) {
|
||||
case pdtra::cable_type::vga: serial::string("vga\n"); break;
|
||||
case pdtra::cable_type::rgb: serial::string("rgb\n"); break;
|
||||
case pdtra::cable_type::cvbs_yc: serial::string("cvbs_yc\n"); break;
|
||||
default: serial::string("undefined/reserved\n"); break;
|
||||
}
|
||||
serial::string("framebuffer resolution: ");
|
||||
serial::integer<uint16_t, serial::dec>(framebuffer_resolution.width, ' ', 3);
|
||||
serial::integer<uint16_t, serial::dec>(framebuffer_resolution.height, '\n', 3);
|
||||
}
|
||||
|
||||
struct vertex {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
// screen space coordinates
|
||||
const struct vertex quad_vertices[4] = {
|
||||
{ -0.5f, 0.5f, 0.1f },
|
||||
{ -0.5f, -0.5f, 0.1f },
|
||||
{ 0.5f, -0.5f, 0.1f },
|
||||
{ 0.5f, 0.5f, 0.1f },
|
||||
};
|
||||
|
||||
struct vertex transform_vertex(const struct vertex& v,
|
||||
const struct video_output::framebuffer_resolution& framebuffer_resolution,
|
||||
const float theta)
|
||||
{
|
||||
float x = v.x * __builtin_cosf(theta) - v.y * __builtin_sinf(theta);
|
||||
float y = v.x * __builtin_sinf(theta) + v.y * __builtin_cosf(theta);
|
||||
|
||||
return {
|
||||
x * (framebuffer_resolution.height / 2) + (framebuffer_resolution.width / 2),
|
||||
y * (framebuffer_resolution.height / 2) + (framebuffer_resolution.height / 2),
|
||||
v.z,
|
||||
};
|
||||
}
|
||||
|
||||
uint32_t transform(uint32_t * ta_parameter_buf,
|
||||
const struct video_output::framebuffer_resolution& framebuffer_resolution,
|
||||
const float theta)
|
||||
{
|
||||
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||
|
||||
auto a = transform_vertex(quad_vertices[0], framebuffer_resolution, theta);
|
||||
auto b = transform_vertex(quad_vertices[1], framebuffer_resolution, theta);
|
||||
auto c = transform_vertex(quad_vertices[2], framebuffer_resolution, theta);
|
||||
auto d = transform_vertex(quad_vertices[3], framebuffer_resolution, theta);
|
||||
|
||||
const uint32_t parameter_control_word = para_control::para_type::sprite
|
||||
| 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,
|
||||
a.x, a.y, a.z,
|
||||
b.x, b.y, b.z,
|
||||
c.x, c.y, c.z,
|
||||
d.x, d.y);
|
||||
// curiously, there is no quad_veritices[3].z in vertex_sprite_type_0
|
||||
|
||||
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, const struct video_output::framebuffer_resolution& framebuffer_resolution)
|
||||
{
|
||||
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory32);
|
||||
|
||||
background_parameter(mem->background, 0xff220000);
|
||||
|
||||
region_array2(mem->region_array,
|
||||
(offsetof (struct texture_memory_alloc, object_list)),
|
||||
framebuffer_resolution.width / 32, // width
|
||||
framebuffer_resolution.height / 32, // height
|
||||
opb_size
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t _ta_parameter_buf[((32 + 64 + 32) + 32) / 4];
|
||||
|
||||
void main()
|
||||
{
|
||||
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::_16x4byte;
|
||||
|
||||
constexpr struct opb_size opb_size = { .opaque = 16 * 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;
|
||||
|
||||
uint32_t cable_type = video_output::get_cable_type();
|
||||
auto framebuffer_resolution = video_output::set_mode_by_cable_type(cable_type);
|
||||
print_cable_type_resolution(cable_type, framebuffer_resolution);
|
||||
init_texture_memory(opb_size, framebuffer_resolution);
|
||||
core_init();
|
||||
|
||||
float theta = 0;
|
||||
uint32_t frame_ix = 0;
|
||||
constexpr uint32_t num_frames = 1;
|
||||
|
||||
while (true) {
|
||||
ta_polygon_converter_init(opb_size.total(),
|
||||
ta_alloc,
|
||||
framebuffer_resolution.width / 32,
|
||||
framebuffer_resolution.height / 32);
|
||||
uint32_t ta_parameter_size = transform(ta_parameter_buf, framebuffer_resolution, theta);
|
||||
ta_polygon_converter_transfer(ta_parameter_buf, ta_parameter_size);
|
||||
ta_wait_opaque_list();
|
||||
|
||||
core_start_render((offsetof (struct texture_memory_alloc, framebuffer)),
|
||||
framebuffer_resolution.width, // frame_width
|
||||
0x00096000, // frame_size
|
||||
frame_ix, num_frames);;
|
||||
core_wait_end_of_render_video();
|
||||
|
||||
while (!spg_status::vsync(holly.SPG_STATUS));
|
||||
core_flip(frame_ix, num_frames);
|
||||
if (cable_type != video_output::get_cable_type()) {
|
||||
cable_type = video_output::get_cable_type();
|
||||
framebuffer_resolution = video_output::set_mode_by_cable_type(cable_type);
|
||||
print_cable_type_resolution(cable_type, framebuffer_resolution);
|
||||
init_texture_memory(opb_size, framebuffer_resolution);
|
||||
}
|
||||
while (spg_status::vsync(holly.SPG_STATUS));
|
||||
|
||||
constexpr float half_degree = 0.01745329f / 2.f;
|
||||
theta += half_degree;
|
||||
frame_ix += 1;
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
|
@ -25,6 +25,11 @@ namespace ta_global_parameter {
|
||||
, _res5(0)
|
||||
, _res6(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (end_of_list)) == 32);
|
||||
static_assert((offsetof (struct end_of_list, parameter_control_word)) == 0x00);
|
||||
@ -61,6 +66,11 @@ namespace ta_global_parameter {
|
||||
, user_clip_x_max(user_clip_x_max)
|
||||
, user_clip_y_max(user_clip_y_max)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (user_tile_clip)) == 32);
|
||||
static_assert((offsetof (struct user_tile_clip, parameter_control_word)) == 0x00);
|
||||
@ -98,6 +108,11 @@ namespace ta_global_parameter {
|
||||
, bounding_box_x_max(bounding_box_x_max)
|
||||
, bounding_box_y_max(bounding_box_y_max)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (object_list_set)) == 32);
|
||||
static_assert((offsetof (struct object_list_set, parameter_control_word)) == 0x00);
|
||||
@ -135,6 +150,11 @@ namespace ta_global_parameter {
|
||||
, data_size_for_sort_dma(data_size_for_sort_dma)
|
||||
, next_address_for_sort_dma(next_address_for_sort_dma)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_0)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_0, parameter_control_word)) == 0x00);
|
||||
@ -174,6 +194,11 @@ namespace ta_global_parameter {
|
||||
, face_color_g(face_color_g)
|
||||
, face_color_b(face_color_b)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_1)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_1, parameter_control_word)) == 0x00);
|
||||
@ -235,6 +260,11 @@ namespace ta_global_parameter {
|
||||
, face_offset_color_g(face_offset_color_g)
|
||||
, face_offset_color_b(face_offset_color_b)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_2)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_2, parameter_control_word)) == 0x00);
|
||||
@ -282,6 +312,11 @@ namespace ta_global_parameter {
|
||||
, data_size_for_sort_dma(data_size_for_sort_dma)
|
||||
, next_address_for_sort_dma(next_address_for_sort_dma)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_3)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_3, parameter_control_word)) == 0x00);
|
||||
@ -345,6 +380,11 @@ namespace ta_global_parameter {
|
||||
, face_color_g_1(face_color_g_1)
|
||||
, face_color_b_1(face_color_b_1)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_4)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_4, parameter_control_word)) == 0x00);
|
||||
@ -392,6 +432,11 @@ namespace ta_global_parameter {
|
||||
, data_size_for_sort_dma(data_size_for_sort_dma)
|
||||
, next_address_for_sort_dma(next_address_for_sort_dma)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (sprite)) == 32);
|
||||
static_assert((offsetof (struct sprite, parameter_control_word)) == 0x00);
|
||||
@ -425,6 +470,11 @@ namespace ta_global_parameter {
|
||||
, _res4(0)
|
||||
, _res5(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (modifier_volume)) == 32);
|
||||
static_assert((offsetof (struct modifier_volume, parameter_control_word)) == 0x00);
|
||||
|
@ -29,6 +29,11 @@ namespace ta_vertex_parameter {
|
||||
, base_color(base_color)
|
||||
, _res2(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_0)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_0, parameter_control_word)) == 0x00);
|
||||
@ -68,6 +73,11 @@ namespace ta_vertex_parameter {
|
||||
, base_color_g(base_color_g)
|
||||
, base_color_b(base_color_b)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_1)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_1, parameter_control_word)) == 0x00);
|
||||
@ -104,6 +114,11 @@ namespace ta_vertex_parameter {
|
||||
, base_intensity(base_intensity)
|
||||
, _res2(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_2)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_2, parameter_control_word)) == 0x00);
|
||||
@ -143,6 +158,11 @@ namespace ta_vertex_parameter {
|
||||
, base_color(base_color)
|
||||
, offset_color(offset_color)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_3)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_3, parameter_control_word)) == 0x00);
|
||||
@ -181,6 +201,11 @@ namespace ta_vertex_parameter {
|
||||
, base_color(base_color)
|
||||
, offset_color(offset_color)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_4)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_4, parameter_control_word)) == 0x00);
|
||||
@ -242,6 +267,11 @@ namespace ta_vertex_parameter {
|
||||
, offset_color_g(offset_color_g)
|
||||
, offset_color_b(offset_color_b)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_5)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_5, parameter_control_word)) == 0x00);
|
||||
@ -310,6 +340,11 @@ namespace ta_vertex_parameter {
|
||||
, offset_color_g(offset_color_g)
|
||||
, offset_color_b(offset_color_b)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_6)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_6, parameter_control_word)) == 0x00);
|
||||
@ -357,6 +392,11 @@ namespace ta_vertex_parameter {
|
||||
, base_intensity(base_intensity)
|
||||
, offset_intensity(offset_intensity)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_7)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_7, parameter_control_word)) == 0x00);
|
||||
@ -395,6 +435,11 @@ namespace ta_vertex_parameter {
|
||||
, base_intensity(base_intensity)
|
||||
, offset_intensity(offset_intensity)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_8)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_8, parameter_control_word)) == 0x00);
|
||||
@ -432,6 +477,11 @@ namespace ta_vertex_parameter {
|
||||
, _res0(0)
|
||||
, _res1(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_9)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_9, parameter_control_word)) == 0x00);
|
||||
@ -469,6 +519,11 @@ namespace ta_vertex_parameter {
|
||||
, _res0(0)
|
||||
, _res1(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_10)) == 32);
|
||||
static_assert((offsetof (struct polygon_type_10, parameter_control_word)) == 0x00);
|
||||
@ -528,6 +583,11 @@ namespace ta_vertex_parameter {
|
||||
, _res2(0)
|
||||
, _res3(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_11)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_11, parameter_control_word)) == 0x00);
|
||||
@ -593,6 +653,11 @@ namespace ta_vertex_parameter {
|
||||
, _res4(0)
|
||||
, _res5(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_12)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_12, parameter_control_word)) == 0x00);
|
||||
@ -660,6 +725,11 @@ namespace ta_vertex_parameter {
|
||||
, _res2(0)
|
||||
, _res3(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_13)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_13, parameter_control_word)) == 0x00);
|
||||
@ -725,6 +795,11 @@ namespace ta_vertex_parameter {
|
||||
, _res4(0)
|
||||
, _res5(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (polygon_type_14)) == 64);
|
||||
static_assert((offsetof (struct polygon_type_14, parameter_control_word)) == 0x00);
|
||||
@ -792,6 +867,11 @@ namespace ta_vertex_parameter {
|
||||
, _res2(0)
|
||||
, _res3(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (sprite_type_0)) == 64);
|
||||
static_assert((offsetof (struct sprite_type_0, parameter_control_word)) == 0x00);
|
||||
@ -862,6 +942,11 @@ namespace ta_vertex_parameter {
|
||||
, b_u_b_v(b_u_b_v)
|
||||
, c_u_c_v(c_u_c_v)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (sprite_type_1)) == 64);
|
||||
static_assert((offsetof (struct sprite_type_1, parameter_control_word)) == 0x00);
|
||||
@ -927,6 +1012,11 @@ namespace ta_vertex_parameter {
|
||||
, _res4(0)
|
||||
, _res5(0)
|
||||
{ }
|
||||
|
||||
const uint8_t * _data()
|
||||
{
|
||||
return reinterpret_cast<const uint8_t *>(this);
|
||||
}
|
||||
};
|
||||
static_assert((sizeof (modifier_volume)) == 64);
|
||||
static_assert((offsetof (struct modifier_volume, parameter_control_word)) == 0x00);
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "video_output.hpp"
|
||||
#include "video_output_mode.inc"
|
||||
#include "video_output.hpp"
|
||||
|
||||
namespace video_output {
|
||||
|
||||
@ -64,24 +65,27 @@ uint32_t get_cable_type()
|
||||
return sh7091.BSC.PDTRA & pdtra::cable_type::bit_mask;
|
||||
}
|
||||
|
||||
void set_mode_automatic()
|
||||
framebuffer_resolution set_mode_by_cable_type(uint32_t cable_type)
|
||||
{
|
||||
switch (get_cable_type()) {
|
||||
switch (cable_type) {
|
||||
default: [[fallthrough]];
|
||||
case pdtra::cable_type::vga:
|
||||
set_mode(vga);
|
||||
set_framebuffer_resolution(640, 480);
|
||||
aica_sound.common.VREG(vreg::output_mode::vga);
|
||||
return {640, 480};
|
||||
break;
|
||||
case pdtra::cable_type::rgb:
|
||||
set_mode(ntsc_ni);
|
||||
set_framebuffer_resolution(320, 240);
|
||||
aica_sound.common.VREG(vreg::output_mode::rgb);
|
||||
return {320, 240};
|
||||
break;
|
||||
case pdtra::cable_type::cvbs_yc:
|
||||
set_mode(ntsc_ni);
|
||||
set_framebuffer_resolution(320, 240);
|
||||
aica_sound.common.VREG(vreg::output_mode::cvbs_yc);
|
||||
return {320, 240};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,15 @@ extern const struct mode ntsc_i;
|
||||
extern const struct mode pal_ni;
|
||||
extern const struct mode pal_i;
|
||||
|
||||
struct framebuffer_resolution {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
void set_framebuffer_resolution(const uint32_t x_size, const uint32_t y_size);
|
||||
void set_mode(const struct mode& mode);
|
||||
uint32_t get_cable_type();
|
||||
void set_mode_automatic();
|
||||
framebuffer_resolution set_mode_by_cable_type(uint32_t cable_type);
|
||||
void set_mode_vga();
|
||||
void reset_sdram();
|
||||
|
||||
|
@ -126,6 +126,8 @@ def blocks(rows):
|
||||
yield 'extern struct sh7091_reg sh7091 __asm("sh7091");'
|
||||
|
||||
def headers():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
yield "#include <cstdint>"
|
||||
yield "#include <cstddef>"
|
||||
yield ""
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#include "sh7091.hpp"
|
||||
#include "sh7091_bits.hpp"
|
||||
|
||||
#include "string.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
namespace serial {
|
||||
|
||||
@ -64,30 +66,23 @@ void hexlify(const uint8_t n)
|
||||
character(num_buf[1]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void integer(const T n, const char end)
|
||||
template <typename T, typename conv_type>
|
||||
void integer(const T n, const char end, const uint32_t length)
|
||||
{
|
||||
constexpr uint32_t length = (sizeof (T)) * 2;
|
||||
char num_buf[length + 1];
|
||||
string::hex<char>(num_buf, length, n);
|
||||
num_buf[length] = 0;
|
||||
string("0x");
|
||||
string(num_buf);
|
||||
uint8_t num_buf[length];
|
||||
conv_type::template render<uint8_t>(num_buf, length, n);
|
||||
if constexpr (std::is_same<conv_type, string::hex_type>::value)
|
||||
string("0x");
|
||||
string(num_buf, length);
|
||||
character(end);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void integer(const T n)
|
||||
{
|
||||
return integer(n, '\n');
|
||||
}
|
||||
template void integer<uint32_t, hex>(uint32_t param, char end, uint32_t length);
|
||||
template void integer<uint16_t, hex>(uint16_t param, char end, uint32_t length);
|
||||
template void integer<uint8_t, hex>(uint8_t param, char end, uint32_t length);
|
||||
|
||||
template void integer<uint32_t>(uint32_t param);
|
||||
template void integer<uint16_t>(uint16_t param);
|
||||
template void integer<uint8_t>(uint8_t param);
|
||||
|
||||
template void integer<uint32_t>(uint32_t param, char end);
|
||||
template void integer<uint16_t>(uint16_t param, char end);
|
||||
template void integer<uint8_t>(uint8_t param, char end);
|
||||
template void integer<uint32_t, dec>(uint32_t param, char end, uint32_t length);
|
||||
template void integer<uint16_t, dec>(uint16_t param, char end, uint32_t length);
|
||||
template void integer<uint8_t, dec>(uint8_t param, char end, uint32_t length);
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "string.hpp"
|
||||
|
||||
namespace serial {
|
||||
|
||||
void init(uint8_t bit_rate);
|
||||
@ -10,10 +12,23 @@ void string(const uint8_t * s, uint32_t len);
|
||||
|
||||
void hexlify(const uint8_t n);
|
||||
|
||||
template <typename T>
|
||||
void integer(const T n, const char end);
|
||||
using hex = string::hex_type;
|
||||
using dec = string::dec_type;
|
||||
|
||||
template <typename T>
|
||||
void integer(const T n);
|
||||
template <typename T, typename conv_type>
|
||||
void integer(const T n, const char end, const uint32_t length);
|
||||
|
||||
template <typename T, typename conv_type = hex>
|
||||
inline void integer(const T n, const char end)
|
||||
{
|
||||
constexpr uint32_t length = (sizeof (T)) * 2;
|
||||
return integer<T, conv_type>(n, end, length);
|
||||
}
|
||||
|
||||
template <typename T, typename conv_type = hex>
|
||||
inline void integer(const T n)
|
||||
{
|
||||
return integer<T, conv_type>(n, '\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
|
27
string.hpp
27
string.hpp
@ -3,6 +3,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
namespace string {
|
||||
|
||||
template <typename T>
|
||||
inline void hex(T * c, uint32_t len, uint32_t n)
|
||||
{
|
||||
@ -18,4 +19,30 @@ namespace string {
|
||||
c[--len] = nib;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void dec(T * c, uint32_t len, uint32_t n)
|
||||
{
|
||||
while (len > 0) {
|
||||
const uint32_t digit = n % 10;
|
||||
n = n / 10;
|
||||
c[--len] = digit + 48;
|
||||
}
|
||||
}
|
||||
|
||||
struct hex_type {
|
||||
template <typename T>
|
||||
static void render(T * c, uint32_t len, uint32_t n)
|
||||
{
|
||||
hex<T>(c, len, n);
|
||||
}
|
||||
};
|
||||
|
||||
struct dec_type {
|
||||
template <typename T>
|
||||
static void render(T * c, uint32_t len, uint32_t n)
|
||||
{
|
||||
dec<T>(c, len, n);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user