diff --git a/addresses.lds b/addresses.lds new file mode 100644 index 0000000..e4e20d5 --- /dev/null +++ b/addresses.lds @@ -0,0 +1,26 @@ +sh7091_ic_a = 0xf0000000; +sh7091_ic_d = 0xf1000000; +sh7091_oc_a = 0xf4000000; +sh7091_oc_d = 0xf5000000; +sh7091 = 0xff000000; + +system = 0xa05f6800; +maple_if = 0xa05f6c00; +gdrom_if = 0xa05f7000; +g1_if = 0xa05f7400; +g2_if = 0xa05f7800; +pvr_if = 0xa05f7c00; +holly = 0xa05f8000; +modem = 0xa0600000; + +system_boot_rom = 0xa0000000; +aica_wave_memory = 0xa0800000; +texture_memory = 0xa5000000; +system_memory = 0xac000000; +ta_fifo_polygon_converter = 0x10000000; +ta_fifo_yuv_converter = 0x10800000; +ta_fifo_texture_memory = 0x11000000; +ta_fifo_polygon_converter_mirror = 0x12000000; +ta_fifo_yuv_converter_mirror = 0x12800000; +ta_fifo_texture_memory_mirror = 0x13000000; +store_queue = 0xe0000000; diff --git a/alt.lds b/alt.lds index db089da..71bdccc 100644 --- a/alt.lds +++ b/alt.lds @@ -58,14 +58,4 @@ SECTIONS __p1ram_start = ORIGIN(p1ram); __p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); -SH7091_IC_A = 0xf0000000; -SH7091_IC_D = 0xf1000000; -SH7091_OC_A = 0xf4000000; -SH7091_OC_D = 0xf5000000; -SH7091 = 0xff000000; -HOLLY = 0xa05f8000; -SYSTEM = 0xa05F6800; -MAPLE_IF = 0xa05F6C00; -G1_IF = 0xa05F7400; -G2_IF = 0xa05F7800; -PVR_IF = 0xa05F7C00; +INCLUDE "addresses.lds" diff --git a/cache.c b/cache.c deleted file mode 100644 index 5677742..0000000 --- a/cache.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "type.h" -#include "sh7091.h" -#include "sh7091_bits.h" - -#include "cache.h" - -extern volatile reg32 SH7091_IC_A[256][(1 << 5) / 4] __asm("SH7091_IC_A"); -extern volatile reg32 SH7091_OC_A[512][(1 << 5) / 4] __asm("SH7091_OC_A"); - -void cache_init() -{ - for (int i = 0; i < 256; i++) { - SH7091_IC_A[i][0] = 0; - } - - for (int i = 0; i < 512; i++) { - SH7091_OC_A[i][0] = 0; - } - - SH7091.CCN.CCR = CCR__ICI | CCR__ICE | CCR__OCI | CCR__OCE; - - SH7091.CCN.MMUCR = 0; - - asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;"); -} diff --git a/cache.cpp b/cache.cpp new file mode 100644 index 0000000..a72b456 --- /dev/null +++ b/cache.cpp @@ -0,0 +1,25 @@ +#include "type.h" +#include "sh7091.h" +#include "sh7091_bits.h" + +#include "cache.h" + +extern volatile reg32 sh7091_ic_a[256][(1 << 5) / 4] __asm("sh7091_ic_a"); +extern volatile reg32 sh7091_oc_a[512][(1 << 5) / 4] __asm("sh7091_oc_a"); + +void cache_init() +{ + for (int i = 0; i < 256; i++) { + sh7091_ic_a[i][0] = 0; + } + + for (int i = 0; i < 512; i++) { + sh7091_oc_a[i][0] = 0; + } + + sh7091.CCN.CCR = CCR__ICI | CCR__ICE | CCR__OCI | CCR__OCE; + + sh7091.CCN.MMUCR = 0; + + asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;"); +} diff --git a/client.py b/client.py index c88a1aa..49baa91 100644 --- a/client.py +++ b/client.py @@ -32,6 +32,7 @@ def sync(ser, b): return bytes(l) def do(ser, b): + ser.read(ser.in_waiting) ser.flush() ser.flushInput() ser.flushOutput() @@ -55,14 +56,19 @@ def do(ser, b): args = struct.pack("/dev/null +%.data.o: %.data + $(BUILD_BINARY_O) + .SUFFIXES: .INTERMEDIATE: .SECONDARY: diff --git a/holly.h b/holly.h index e1f1b7c..7287787 100644 --- a/holly.h +++ b/holly.h @@ -164,5 +164,4 @@ static_assert((offsetof (struct holly_reg, FOG_TABLE)) == 0x200); static_assert((offsetof (struct holly_reg, TA_OL_POINTERS)) == 0x600); static_assert((offsetof (struct holly_reg, PALETTE_RAM)) == 0x1000); -extern struct holly_reg HOLLY __asm("HOLLY"); - +extern struct holly_reg holly __asm("holly"); diff --git a/holly/background.cpp b/holly/background.cpp new file mode 100644 index 0000000..68427b8 --- /dev/null +++ b/holly/background.cpp @@ -0,0 +1,49 @@ +#include + +#include "isp_tsp.h" + +struct vertex_parameter { + float x; + float y; + float z; + uint32_t base_color; +}; // ISP_BACKGND_T skip(1) + +struct isp_tsp_parameter { + uint32_t isp_tsp_instruction_word; + uint32_t tsp_instruction_word; + uint32_t texture_control_word; + vertex_parameter vertex[3]; +}; + +void background_parameter(volatile uint32_t * buf) +{ + volatile isp_tsp_parameter * parameter = reinterpret_cast(buf); + + parameter->isp_tsp_instruction_word + = isp_tsp_instruction_word::depth_compare_mode::always + | isp_tsp_instruction_word::culling_mode::no_culling; + + parameter->tsp_instruction_word + = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + + parameter->texture_control_word + = 0; + + parameter->vertex[0].x = 0.f; + parameter->vertex[0].y = 0.f; + parameter->vertex[0].z = 1.f/100000; + parameter->vertex[0].base_color = 0xff300000; + + parameter->vertex[1].x = 0.f; + parameter->vertex[1].y = 480.f; + parameter->vertex[1].z = 1.f/100000; + parameter->vertex[1].base_color = 0xff300000; + + parameter->vertex[2].x = 640.f; + parameter->vertex[2].y = 0.f; + parameter->vertex[2].z = 1.f/100000; + parameter->vertex[2].base_color = 0xff300000; +} diff --git a/holly/background.h b/holly/background.h new file mode 100644 index 0000000..266d44f --- /dev/null +++ b/holly/background.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +void background_parameter(volatile uint32_t * buf); diff --git a/holly/float_uint32.h b/holly/float_uint32.h new file mode 100644 index 0000000..56c7bbf --- /dev/null +++ b/holly/float_uint32.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +constexpr uint32_t _i(float f) { + return *(reinterpret_cast(&f)); +} +#pragma GCC diagnostic pop diff --git a/holly/isp_tsp.h b/holly/isp_tsp.h new file mode 100644 index 0000000..fb8579a --- /dev/null +++ b/holly/isp_tsp.h @@ -0,0 +1,113 @@ +#include + +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 not_equal = 5 << 29; + constexpr uint32_t greater_or_equal = 6 << 29; + constexpr uint32_t always = 7 << 29; + } + + namespace culling_mode { + constexpr uint32_t no_culling = 0 << 27; + constexpr uint32_t cull_if_small = 1 << 27; // compared to FPU_CULL_VAL + constexpr uint32_t cull_if_negative = 2 << 27; + constexpr uint32_t cull_if_positive = 3 << 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; + } + + 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 src_select = 1 << 25; + constexpr uint32_t dst_select = 1 << 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 color_clamp = 1 << 21; + constexpr uint32_t use_alpha = 1 << 20; + constexpr uint32_t ignore_tex_alpha = 1 << 19; + + // flip_uv + // clamp_uv + + 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 super_sample_texture = 1 << 12; + + constexpr uint32_t mip_map_d_adjust(uint32_t fp) + { + return (fp & 0b1111) << 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; + } + + 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; + } + + 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; + } +} diff --git a/holly/region_array.cpp b/holly/region_array.cpp new file mode 100644 index 0000000..3052b79 --- /dev/null +++ b/holly/region_array.cpp @@ -0,0 +1,61 @@ +#include "region_array.h" + +#define REGION_ARRAY__LAST_REGION (1 << 31) +#define REGION_ARRAY__Z_CLEAR (1 << 30) +#define REGION_ARRAY__PRE_SORT (1 << 29) +#define REGION_ARRAY__FLUSH_ACCUMULATE (1 << 28) +#define REGION_ARRAY__TILE_Y_POSITION(n) (((n) & 0x3f) << 8) +#define REGION_ARRAY__TILE_X_POSITION(n) (((n) & 0x3f) << 2) + +#define REGION_ARRAY__LIST_POINTER__EMPTY (1 << 31) +#define REGION_ARRAY__LIST_POINTER(n) ((n) & 0xfffffc) + +// this is for a "type 2" region array. +// region header type is specified in FPU_PARAM_CFG +struct region_array_entry { + uint32_t tile; /* 3.7.7 page 216 */ + uint32_t opaque_list_pointer; + uint32_t opaque_modifier_volume_list_pointer; + uint32_t translucent_list_pointer; + uint32_t translucent_modifier_volume_list_pointer; + uint32_t punch_through_list_pointer; +}; + +// opaque list pointer offset: OPB size * tile index * 4 + +void region_array(volatile uint32_t * buf, + uint32_t ol_base, + const uint32_t width, // in tile units (1 tile unit = 32 pixels) + const uint32_t height) // in tile units (1 tile unit = 32 pixels) +{ + volatile region_array_entry * region_array = reinterpret_cast(buf); + uint32_t ix = 0; + + // create a "dummy region array [item]" for CORE & TA-related bug #21: + // "Misshapen tiles or missing tiles occur" + region_array[ix].tile = REGION_ARRAY__FLUSH_ACCUMULATE; + region_array[ix].opaque_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].opaque_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].translucent_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].translucent_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].punch_through_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + + ix += 1; + + for (uint32_t y = 0; y < height; y++) { + for (uint32_t x = 0; x < width; x++) { + region_array[ix].tile = REGION_ARRAY__TILE_Y_POSITION(y) + | REGION_ARRAY__TILE_X_POSITION(x); + + uint32_t tile_index = y * width + x; + constexpr uint32_t opaque_list_opb_size = 16 * 4; // in bytes; this must match O_OPB in TA_ALLOC_CTRL + region_array[ix].opaque_list_pointer = ol_base + (opaque_list_opb_size * tile_index); + region_array[ix].opaque_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].translucent_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].translucent_modifier_volume_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + region_array[ix].punch_through_list_pointer = REGION_ARRAY__LIST_POINTER__EMPTY; + + ix += 1; + } + } +} diff --git a/holly/region_array.h b/holly/region_array.h new file mode 100644 index 0000000..fd6a93b --- /dev/null +++ b/holly/region_array.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +void region_array(volatile uint32_t * buf, + uint32_t ol_base, + const uint32_t width, // in tile units (1 tile unit = 32 pixels) + const uint32_t height); // in tile units (1 tile unit = 32 pixels) diff --git a/holly/ta_parameter.cpp b/holly/ta_parameter.cpp new file mode 100644 index 0000000..e6d1701 --- /dev/null +++ b/holly/ta_parameter.cpp @@ -0,0 +1,185 @@ +#include +#include + +#include "float_uint32.h" +#include "ta_parameter.h" +#include "isp_tsp.h" + +static_assert((sizeof (float)) == (sizeof (uint32_t))); + +struct vertex_polygon_type_0 { + uint32_t parameter_control_word; + float x; + float y; + float z; + uint32_t _res0; + uint32_t _res1; + uint32_t base_color; + uint32_t _res2; +}; + +static_assert((sizeof (vertex_polygon_type_0)) == 32); +static_assert((offsetof (struct vertex_polygon_type_0, parameter_control_word)) == 0x00); +static_assert((offsetof (struct vertex_polygon_type_0, x)) == 0x04); +static_assert((offsetof (struct vertex_polygon_type_0, y)) == 0x08); +static_assert((offsetof (struct vertex_polygon_type_0, z)) == 0x0c); +static_assert((offsetof (struct vertex_polygon_type_0, _res0)) == 0x10); +static_assert((offsetof (struct vertex_polygon_type_0, _res1)) == 0x14); +static_assert((offsetof (struct vertex_polygon_type_0, base_color)) == 0x18); +static_assert((offsetof (struct vertex_polygon_type_0, _res2)) == 0x1c); + +struct global_polygon_type_0 { + uint32_t parameter_control_word; + uint32_t isp_tsp_instruction_word; + uint32_t tsp_instruction_word; + uint32_t texture_control_word; + uint32_t _res0; + uint32_t _res1; + uint32_t data_size_for_sort_dma; + uint32_t next_address_for_sort_dma; +}; + +static_assert((sizeof (global_polygon_type_0)) == 32); +static_assert((offsetof (struct global_polygon_type_0, parameter_control_word)) == 0x00); +static_assert((offsetof (struct global_polygon_type_0, isp_tsp_instruction_word)) == 0x04); +static_assert((offsetof (struct global_polygon_type_0, tsp_instruction_word)) == 0x08); +static_assert((offsetof (struct global_polygon_type_0, texture_control_word)) == 0x0c); +static_assert((offsetof (struct global_polygon_type_0, _res0)) == 0x10); +static_assert((offsetof (struct global_polygon_type_0, _res1)) == 0x14); +static_assert((offsetof (struct global_polygon_type_0, data_size_for_sort_dma)) == 0x18); +static_assert((offsetof (struct global_polygon_type_0, next_address_for_sort_dma)) == 0x1c); + +struct global_end_of_list { + uint32_t parameter_control_word; + uint32_t _res0; + uint32_t _res1; + uint32_t _res2; + uint32_t _res3; + uint32_t _res4; + uint32_t _res5; + uint32_t _res6; +}; + +static_assert((sizeof (global_end_of_list)) == 32); +static_assert((offsetof (struct global_end_of_list, parameter_control_word)) == 0x00); +static_assert((offsetof (struct global_end_of_list, _res0)) == 0x04); +static_assert((offsetof (struct global_end_of_list, _res1)) == 0x08); +static_assert((offsetof (struct global_end_of_list, _res2)) == 0x0c); +static_assert((offsetof (struct global_end_of_list, _res3)) == 0x10); +static_assert((offsetof (struct global_end_of_list, _res4)) == 0x14); +static_assert((offsetof (struct global_end_of_list, _res5)) == 0x18); +static_assert((offsetof (struct global_end_of_list, _res6)) == 0x1c); + +namespace para_control { + namespace para_type { + constexpr uint32_t end_of_list = 0 << 29; + constexpr uint32_t user_tile_clip = 1 << 29; + constexpr uint32_t object_list_set = 2 << 29; + constexpr uint32_t polygon_or_modifier_volume = 4 << 29; + constexpr uint32_t sprite = 5 << 29; + constexpr uint32_t vertex_parameter = 7 << 29; + } + + constexpr uint32_t end_of_strip = 1 << 28; + + namespace list_type { + constexpr uint32_t opaque = 0 << 24; + constexpr uint32_t opaque_modifier_volume = 1 << 24; + constexpr uint32_t translucent = 2 << 24; + constexpr uint32_t translucent_modifier_volume = 3 << 24; + constexpr uint32_t punch_through = 4 << 24; + } +} + +namespace group_control { + constexpr uint32_t group_en = 1 << 23; + + namespace strip_len { + constexpr uint32_t _1_strip = 0 << 18; + constexpr uint32_t _2_strip = 1 << 18; + constexpr uint32_t _4_strip = 2 << 18; + constexpr uint32_t _6_strip = 3 << 18; + } + + namespace user_clip { + constexpr uint32_t disabled = 0 << 16; + constexpr uint32_t inside_enable = 2 << 16; + constexpr uint32_t outside_enable = 3 << 16; + } +} + +namespace obj_control { + constexpr uint32_t shadow = 1 << 7; + constexpr uint32_t volume = 1 << 6; + + namespace col_type { + constexpr uint32_t packed_color = 0 << 4; + constexpr uint32_t floating_color = 1 << 4; + constexpr uint32_t intensity_mode_1 = 2 << 4; + constexpr uint32_t intensity_mode_2 = 3 << 4; + } + + constexpr uint32_t texture = 1 << 3; + constexpr uint32_t offset = 1 << 2; + constexpr uint32_t gouraud = 1 << 1; + constexpr uint32_t _16bit_uv = 1 << 0; +} + +void vertex(volatile uint32_t * buf, + const float x, + const float y, + const float z, + const uint32_t base_color, + bool end_of_strip + ) +{ + volatile vertex_polygon_type_0 * parameter = reinterpret_cast(buf); + + parameter->parameter_control_word = para_control::para_type::vertex_parameter; + + if (end_of_strip) + parameter->parameter_control_word |= para_control::end_of_strip; + + parameter->x = x; + parameter->y = y; + parameter->z = z; + parameter->_res0 = 0; + parameter->_res1 = 0; + parameter->base_color = base_color; + parameter->_res2 = 0; +} + +void triangle(volatile uint32_t * buf) +{ + volatile global_polygon_type_0 * parameter = reinterpret_cast(buf); + + parameter->parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | para_control::list_type::opaque + | obj_control::col_type::packed_color; + + parameter->isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always + | isp_tsp_instruction_word::culling_mode::no_culling; + + parameter->tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + parameter->texture_control_word = 0; + parameter->_res0 = 0; + parameter->_res1 = 0; + parameter->data_size_for_sort_dma = 0; + parameter->next_address_for_sort_dma = 0; +} + +void end_of_list(volatile uint32_t * buf) +{ + volatile global_end_of_list * parameter = reinterpret_cast(buf); + + parameter->parameter_control_word = para_control::para_type::end_of_list; + parameter->_res0 = 0; + parameter->_res1 = 0; + parameter->_res2 = 0; + parameter->_res3 = 0; + parameter->_res4 = 0; + parameter->_res5 = 0; + parameter->_res6 = 0; +} diff --git a/holly/ta_parameter.h b/holly/ta_parameter.h new file mode 100644 index 0000000..213ade7 --- /dev/null +++ b/holly/ta_parameter.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +void vertex(volatile uint32_t * buf, + const float x, + const float y, + const float z, + const uint32_t base_color, + bool end_of_strip + ); + +void triangle(volatile uint32_t * buf); + +void end_of_list(volatile uint32_t * buf); diff --git a/load.c b/load.cpp similarity index 72% rename from load.c rename to load.cpp index d42846e..0184672 100644 --- a/load.c +++ b/load.cpp @@ -24,10 +24,10 @@ struct load_state { static struct load_state state; -void move(void *dest, const void *src, size_t n) +void move(void *dst, const void *src, size_t n) { - uint8_t *d = dest; - const uint8_t *s = src; + uint8_t * d = reinterpret_cast(dst); + const uint8_t * s = reinterpret_cast(src); if (d==s) return; if (d 0) { - SH7091.SCIF.SCFTDR2 = c; + uint8_t * dest = reinterpret_cast(state.addr2); + if (*size > 0) { + sh7091.SCIF.SCFTDR2 = c; // write c to dest *dest = c; @@ -109,19 +109,19 @@ void load_recv(uint8_t c) } return; break; - case CMD_JUMP: - // jump - state.len = 0; - state.command = CMD_NONE; - debug("prejump\n"); - HOLLY.VO_BORDER_COL = (31 << 11); - void (*fptr)(void) = (void (*)(void))state.addr1; - HOLLY.VO_BORDER_COL = (63 << 5) | (31 << 0); - fptr(); - debug("postjump\n"); - return; - break; } + case CMD_JUMP: + // jump + state.len = 0; + state.command = CMD_NONE; + debug("prejump\n"); + holly.VO_BORDER_COL = (31 << 11); + void (*fptr)(void) = (void (*)(void))state.addr1; + holly.VO_BORDER_COL = (63 << 5) | (31 << 0); + fptr(); + debug("postjump\n"); + return; + break; } } } diff --git a/main.c b/main.c deleted file mode 100644 index ec6aef2..0000000 --- a/main.c +++ /dev/null @@ -1,66 +0,0 @@ -#include - -#include "cache.h" -#include "load.h" - -#include "sh7091.h" -#include "sh7091_bits.h" - -extern uint32_t __bss_link_start __asm("__bss_link_start"); -extern uint32_t __bss_link_end __asm("__bss_link_end"); - -void serial() -{ - SH7091.SCIF.SCSCR2 = 0; - SH7091.SCIF.SCSMR2 = 0; - SH7091.SCIF.SCBRR2 = 12; - -#define SCFCR2__TFRST (1 << 2) -#define SCFCR2__RFRST (1 << 1) - SH7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST; - // tx/rx trigger on 1 byte - SH7091.SCIF.SCFCR2 = 0; - - SH7091.SCIF.SCSPTR2 = 0; - SH7091.SCIF.SCLSR2 = 0; - -#define SCSCR2__TE (1 << 5) -#define SCSCR2__RE (1 << 4) - SH7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; -} - -void main() -{ - cache_init(); - - // clear BSS - uint32_t * start = &__bss_link_start; - uint32_t * end = &__bss_link_end; - while (start < end) { - *start++ = 0; - } - - serial(); - - load_init(); - - while (1) { -#define SCFSR2__ER (1 << 7) /* read error */ -#define SCFSR2__TEND (1 << 6) /* transmit end */ -#define SCFSR2__TFDE (1 << 5) /* transmit fifo data empty */ -#define SCFSR2__BRK (1 << 4) /* break detect */ -#define SCFSR2__FER (1 << 3) /* framing error */ -#define SCFSR2__PER (1 << 2) /* parity error */ -#define SCFSR2__RDF (1 << 1) /* receive FIFO data full */ -#define SCFSR2__DR (1 << 0) /* receive data ready */ - - while ((SH7091.SCIF.SCFSR2 & SCFSR2__RDF) == 0) { - // wait - } - while ((SH7091.SCIF.SCFDR2 & 0b11111) > 0) { - uint8_t c = SH7091.SCIF.SCFRDR2; - load_recv(c); - } - SH7091.SCIF.SCFSR2 = SH7091.SCIF.SCFSR2 & (~SCFSR2__RDF); - } -} diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..c475e78 --- /dev/null +++ b/main.cpp @@ -0,0 +1,96 @@ +#include + +#include "cache.h" +#include "load.h" +#include "vga.h" + +#include "sh7091.h" +#include "sh7091_bits.h" +#include "memorymap.h" + +#include "rgb.h" +#include "scene.h" + +extern uint32_t __bss_link_start __asm("__bss_link_start"); +extern uint32_t __bss_link_end __asm("__bss_link_end"); + +void serial() +{ + sh7091.SCIF.SCSCR2 = 0; + sh7091.SCIF.SCSMR2 = 0; + sh7091.SCIF.SCBRR2 = 1; // 520833.3 + + sh7091.SCIF.SCFCR2 = SCFCR2__TFRST | SCFCR2__RFRST; + // tx/rx trigger on 1 byte + sh7091.SCIF.SCFCR2 = 0; + + sh7091.SCIF.SCSPTR2 = 0; + sh7091.SCIF.SCLSR2 = 0; + + sh7091.SCIF.SCSCR2 = SCSCR2__TE | SCSCR2__RE; +} + +extern "C" +void main() +{ + cache_init(); + + // clear BSS + uint32_t * start = &__bss_link_start; + uint32_t * end = &__bss_link_end; + while (start < end) { + *start++ = 0; + } + + serial(); + + vga(); + + v_sync_in(); + + volatile uint16_t * framebuffer = reinterpret_cast(&texture_memory[0]); + for (int y = 0; y < 480; y++) { + for (int x = 0; x < 640; x++) { + struct hsv hsv = {(y * 255) / 480, 255, 255}; + struct rgb rgb = hsv_to_rgb(hsv); + framebuffer[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0); + } + } + + + while (1) { + v_sync_in(); + scene_holly_init(); + scene_init_texture_memory(); + scene_ta_init(); + scene_geometry_transfer(); + scene_wait_opaque_list(); + scene_start_render(); + + // I do not understand why, but flycast does not show the first-rendered + // framebuffer. + v_sync_in(); + scene_ta_init(); + scene_geometry_transfer(); + scene_wait_opaque_list(); + scene_start_render(); + + // do nothing forever + while(1); + + /* + load_init(); + + while (1) { + while ((sh7091.SCIF.SCFSR2 & SCFSR2__RDF) == 0) { + // wait + } + while ((sh7091.SCIF.SCFDR2 & 0b11111) > 0) { + uint8_t c = sh7091.SCIF.SCFRDR2; + load_recv(c); + } + sh7091.SCIF.SCFSR2 = sh7091.SCIF.SCFSR2 & (~SCFSR2__RDF); + } +*/ + } +} diff --git a/main.lds b/main.lds index c7e294d..b64b5c5 100644 --- a/main.lds +++ b/main.lds @@ -64,11 +64,7 @@ SECTIONS __ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); } -SH7091_IC_A = 0xf0000000; -SH7091_IC_D = 0xf1000000; -SH7091_OC_A = 0xf4000000; -SH7091_OC_D = 0xf5000000; -SH7091 = 0xff000000; -HOLLY = 0xa05f8000; __p1ram_start = ORIGIN(p1ram); __p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); + +INCLUDE "addresses.lds" diff --git a/memorymap.h b/memorymap.h new file mode 100644 index 0000000..fed8642 --- /dev/null +++ b/memorymap.h @@ -0,0 +1,13 @@ +#include + +extern volatile uint32_t system_boot_rom[0x200000] __asm("system_boot_rom"); +extern volatile uint32_t aica_wave_memory[0x200000] __asm("aica_wave_memory"); +extern volatile uint32_t texture_memory[0x800000] __asm("texture_memory"); +extern volatile uint32_t system_memory[0x1000000] __asm("system_memory"); +extern volatile uint32_t ta_fifo_polygon_converter[0x800000] __asm("ta_fifo_polygon_converter"); +extern volatile uint32_t ta_fifo_yuv_converter[0x800000] __asm("ta_fifo_yuv_converter"); +extern volatile uint32_t ta_fifo_texture_memory[0x800000] __asm("ta_fifo_texture_memory"); +extern volatile uint32_t ta_fifo_polygon_converter_mirror[0x800000] __asm("ta_fifo_polygon_converter_mirror"); +extern volatile uint32_t ta_fifo_yuv_converter_mirror[0x800000] __asm("ta_fifo_yuv_converter_mirror"); +extern volatile uint32_t ta_fifo_texture_memory_mirror[0x800000] __asm("ta_fifo_texture_memory_mirror"); +extern volatile uint32_t store_queue[0x4000000] __asm("store_queue"); diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..5010466 --- /dev/null +++ b/notes.txt @@ -0,0 +1,176 @@ +======= KMYINIT.C ======== + +- ISP_FEED_CFG -- TRANSLUCENCY_CACHE_SIZE(0x200) + +- FPU_SHAD_SCALE -- SCALE_FACTOR(1) +- FPU_CULL_VAL -- 1.0f +- FPU_PERP_VAL -- 0.0f +- SPAN_SORT_CFG -- SPAN_SORT_ENABLE | OFFSET_SORT_ENABLE + +- FOG_COL_RAM -- RED(127) | GREEN(127) | BLUE(127) +- FOG_COL_VERT -- RED(127) | GREEN(127) | BLUE(127) +- FOG_CLAMP_MIN -- ALPHA(0) | RED(0) | GREEN(0) | BLUE(0) +- FOG_CLAMP_MAX -- ALPHA(255) | RED(255) | GREEN(255) | BLUE(255) + +- HALF_OFFSET -- TSP_TEXEL_SAMPLE_POSITION_CENTER + | TSP_PIXEL_SAMPLE_POSITION_CENTER + | FPU_PIXEL_SAMPLE_POSITION_CENTER + +- FPU_PARAM_CFG -- REGION_HEADER_TYPE__2 + | TSP_PARAMETER_BURST_TRIGGER(31) + | ISP_PARAMETER_BURST_TRIGGER(31) + | POINTER_BURST_SIZE(7) // must be less than OPB size + | POINTER_FIRST_BURST_SIZE(7) // half of pointer burst size(?) + +=========================== + +jargon: + +OPB - Object Pointer Block (a list of pointers to objects in the object list) +OL - Object list +ISP - Image Synthesis Processor +TSP - Texture Shading Processor + + +====== KMYSETUPTA.C ====== + +The OPB initial area size that is needed for one TA input list is the +product of the total OPB size for all lists specified by the +TA_ALLOC_CTRL register before the input of that list, multiplied by +the number of Tiles in the Global Tile Clip area that is specified by +the TA_GLOB_TILE_CLIP register. The amount of memory that should be +reserved in texture memory as the OPB initial area is the sum of the +OPB initial area size for the one list added together for each of the +polygon lists that are input to the TA. + +(OPB initial area size for one list) = {(Opaque list OPB size)} * (Number of Tiles in Global Tile Clip area) x 4 bytes + + 4byte + + +- TA_GLOB_TILE_CLIP -- TILE_Y_NUM(480 / 32) + | TILE_X_NUM(640 / 32) + (removes polygons that are entirely outside the clip area) + +- TA_ALLOC_CTRL -- TA_ALLOC_CTRL__OPB_MODE_INCREASING + | TA_ALLOC_CTRL__PT_OPB__NONE + | TA_ALLOC_CTRL__TM_OPB__NONE + | TA_ALLOC_CTRL__T_OPB__NONE + | TA_ALLOC_CTRL__OM_OPB__NONE + | TA_ALLOC_CTRL__O_OPB__16 + +- TA_ISP_BASE -- + (Base address for ISP/TSP parameters (relative address from the start of texture memory) (read by PARAM_BASE)) + +- TA_OL_LIMIT - The last address of the object list (relative address from the start of texture memory) +- TA_PARAM_LIMIT aka TA_ISP_LIMIT - The last address of the ISP/TSP parameter list (relative address from the start of texture memory) +- TA_NEXT_OPB_INIT - the address for storing additional OPBs during list initialization (relative address from the start of texture memory) + +The value in the TA_NEXT_OPB_INIT register, which should be set prior +to list initialization, is the sum starting address value of the +Object List that is stored in texture memory and the OPB initial area +size. + +(TA_NEXT_OPB_INIT register value) = (TA_OL_BASE register value at list initialization) + (OPB initial area size at list initialization) +-- &object_list[0] + (sizeof (mem->object_list)) +(end of object_list) + +- SOFTRESET = SOFTRESET__TA_SOFT_RESET +- SOFTRESET = 0 + +- TA_GLOB_TILE_CLIP = TILE_Y_NUM(15) + | TILE_X_NUM(20) // 640x480 + +- TA_ISP_BASE = 0x00000000 +- TA_ISP_LIMIT = 0x00100000 +- TA_OL_BASE = 0x00100000 +- TA_OL_LIMIT = 0x00200000 +- TA_NEXT_OPB_INIT = 0x00100000 + +- TA_LIST_INIT +- dummy read on TA_LIST_INIT + +==== BGPLANE ==== + +KMYSETPASSDEPTH.C +KMYINITIALIZEBGPLANE.C + +[ 0] = DEPTH_COMPARE_MODE(GREATER) +[ 1] = SRC_ALPHA(One) + | FOG_CONTROL(NO_FOG) +[ 2] = 0 + +[ 3] = 0.0 // x +[ 4] = 0.0 // y +[ 5] = 1.f/100000 // 1/z +[ 6] = 0x0FF000000 // color + +[ 7] = 0.0 // x +[ 8] = 0.0 // y +[ 9] = 1.f/100000 // 1/z +[10] = 0x0FF000000 // color + +[11] = 0.0 // x +[12] = 0.0 // y +[13] = 1.f/100000 // 1/z +[14] = 0x0FF000000 // color + +==== KMYSTARTRENDER.C ==== + +region array diagram on page 179 + +REGION_BASE the region array is not generated by the TA +PARAM_BASE -- equal to TA_ISP_BASE +FB_W_CTRL -- FB_PACKMODE__565_RGB + +ISP_BACKGND_T // address of ISP/TSP parameters, without using TA + -- TAG_ADDRESS(0x00200000/4) + -- TAG_OFFSET(0) + -- SKIP(1) + +ISP_BACKGND_D -- Z coordinate ; 0x03727c5ac (1.f/100000) + +FB_W_LINESTRIDE -- 640 / 8; +FB_W_SOF1 -- framebuffer address +STARTRENDER + +==== store queue ==== + +store queue write: 0xe000_0000 - 0xe3ff_fffc + +write vertex list to: 0x10000000 + +TA: +"List of Input Parameters" + +page 201 (TA) Parameter Format + +control: + - End of List 0x0000_0000 + - User Tile Clip 0x2000_0000 + - Object List Set 0x4000_0000 + +page 196 Parameter Control Word + +page 222 ISP/TSP Instruction Word + +page 226 TSP Instruction Word + +page 233 Texture Control Word + + +Volume 0 + +Col_Type + 0 Packed (32-bit ARGB) + 1 Floating (32-bit float * 4) + +Textured 0 +Offset 0 +Gouraud 0 +16bit_UV 0 + +Global: Polygon Type 0 +Vertex: Polygon Type 0 + +- x y are 32-bit floating point in screen space +- z specified as reciprocal 1/z diff --git a/regs/gen/generate.py b/regs/gen/generate.py index 8ac8aa4..cf56c82 100644 --- a/regs/gen/generate.py +++ b/regs/gen/generate.py @@ -1,5 +1,12 @@ import io +def should_autonewline(line): + return ( + "static_assert" not in line + and "extern" not in line + and line.split()[1] != '=' # hacky; meh + ) + def _render(out, lines): indent = " " level = 0 @@ -14,7 +21,7 @@ def _render(out, lines): level += 2 if level == 0 and l and l[-1] == ";": - if "static_assert" not in l: + if should_autonewline(l): out.write("\n") return out diff --git a/regs/gen/holly.py b/regs/gen/holly.py index 7aad1aa..91cb896 100644 --- a/regs/gen/holly.py +++ b/regs/gen/holly.py @@ -6,7 +6,7 @@ from sh7091 import headers from generate import renderer def block(): - yield 'extern struct holly_reg HOLLY __asm("HOLLY");' + yield 'extern struct holly_reg holly __asm("holly");' input_file = sys.argv[1] rows = read_input(input_file) diff --git a/regs/gen/memorymap.py b/regs/gen/memorymap.py new file mode 100644 index 0000000..8540835 --- /dev/null +++ b/regs/gen/memorymap.py @@ -0,0 +1,42 @@ +import sys + +from sh7091 import read_input + +from generate import renderer + +def includes(): + yield "#include " + yield "" + +def process_rows(rows): + for row in rows: + name = row["name"].strip() + if not name: + continue + start = int(row["start"].strip(), 16) + size = row["size"].strip() + assert size.endswith("MB"), size + size = int(size.rstrip("MB")) + yield name, start, size * 1024 * 1024 + +def header(processed): + for name, _, size in processed: + yield f"extern volatile uint32_t {name}[0x{size:x}] __asm(\"{name}\");" + +def lds(processed): + for name, address, size in processed: + if address < 0x1000_0000: + address = address | 0xa000_0000 + yield f"{name} = 0x{address:08x};" + +input_file = sys.argv[1] +rows = read_input(input_file) +processed = list(process_rows(rows)) +render, out = renderer() +render(includes()) +render(header(processed)) +sys.stdout.write(out.getvalue()) + +render, out = renderer() +render(lds(processed)) +sys.stderr.write(out.getvalue()) diff --git a/regs/gen/sh7091.py b/regs/gen/sh7091.py index 9ba8826..d6b0722 100644 --- a/regs/gen/sh7091.py +++ b/regs/gen/sh7091.py @@ -142,7 +142,7 @@ def blocks(rows): yield f"static_assert((offsetof (struct sh7091_reg, {block})) == {hex(offset << 16)});" yield "" - yield 'extern struct sh7091_reg SH7091 __asm("SH7091");' + yield 'extern struct sh7091_reg sh7091 __asm("sh7091");' def headers(): yield "#include " diff --git a/regs/memorymap.csv b/regs/memorymap.csv new file mode 100644 index 0000000..89fb7e7 --- /dev/null +++ b/regs/memorymap.csv @@ -0,0 +1,43 @@ +"area","start","end","function","size","access","name" +"0","0x00000000","0x001FFFFF","System/Boot ROM","2MB",,"system_boot_rom" +"0","0x00200000","0x0021FFFF","Flash Memory","128KB",, +"0","0x00400000","0x005F67FF","Unassigned","-",, +"0","0x005F6800","0x005F69FF","System Control Registers","512B",, +"0","0x005F6C00","0x005F6CFF","Maple interface Control Registers","256B",, +"0","0x005F7000","0x005F70FF","GD-ROM","256B",, +"0","0x005F7400","0x005F74FF","G1 interface Control Registers","256B",, +"0","0x005F7800","0x005F78FF","G2 interface Control Registers","256B",, +"0","0x005F7C00","0x005F7CFF","PVR interface Control Registers","256B",, +"0","0x005F8000","0x005F9FFF","TA / PVR Core Registers","8KB",, +"0","0x00600000","0x006007FF","MODEM","2KB",, +"0","0x00600800","0x006FFFFF","G2","-",, +"0","0x00700000","0x00707FFF","AICA- Sound Control Registers","32KB",, +"0","0x00710000","0x0071000B","AICA- RTC Control Registers","12B",, +"0","0x00800000","0x00FFFFFF","AICA- Wave Memory","2MB",,"aica_wave_memory" +"0","0x01000000","0x01FFFFFF","External Device","16MB",, +"0","0x02000000","0x03FFFFFF","Mirror of 0x00000000 - 0x1FFFFFFF","32MB",, +,,,,,, +"1","0x04000000","0x04FFFFFF","Texture memory 64bit access","8MB",, +"1","0x05000000","0x05FFFFFF","Texture memory 32bit access","8MB",,"texture_memory" +"1","0x06000000","0x06FFFFFF","Mirror of 0x04000000 - 0x06FFFFFF","32MB",, +,,,,,, +"2","0x08000000","0x0bffffff","Unassigned","-",, +,,,,,, +"3","0x0c000000","0x0cffffff","System memory","16MB",,"system_memory" +"3","0x0d000000","0x0dffffff","Mirror of 0x0c000000 - 0x0cffffff","16MB",, +"3","0x0e000000","0x0fffffff","Mirror of 0x0c000000 - 0x0dffffff","32MB",, +,,,,,, +"4","0x10000000","0x107FFFFF","TA FIFO Polygon Converter","8MB",,"ta_fifo_polygon_converter" +"4","0x10800000","0x10FFFFFF","TA FIFO YUV Converter","8MB",,"ta_fifo_yuv_converter" +"4","0x11000000","0x11FFFFFF","TA FIFO Texture memory","8MB",,"ta_fifo_texture_memory" +"4","0x12000000","0x127FFFFF","Mirror of TA FIFO Polygon Converter","8MB",,"ta_fifo_polygon_converter_mirror" +"4","0x12800000","0x137FFFFF","Mirror of TA FIFO YUV Converter","8MB",,"ta_fifo_yuv_converter_mirror" +"4","0x13000000","0x13FFFFFF","Mirror of TA FIFO Texture memory","8MB",,"ta_fifo_texture_memory_mirror" +,,,,,, +"5","0x14000000","0x17FFFFFF","External device","64MB",, +,,,,,, +"6","0x18000000","0x1BFFFFFF","Unassigned","-",, +,,,,,, +"7","0x1C000000","0x1FFFFFFF","SH4 Internal area","-",, +,,,,,, +,"0xE0000000","0xE3FFFFFF","Store Queue","64MB",,"store_queue" diff --git a/regs/memorymap.ods b/regs/memorymap.ods index 3696344..373544a 100644 Binary files a/regs/memorymap.ods and b/regs/memorymap.ods differ diff --git a/rgb.c b/rgb.cpp similarity index 100% rename from rgb.c rename to rgb.cpp diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000..f452764 --- /dev/null +++ b/scene.cpp @@ -0,0 +1,153 @@ +#include + +#include "holly/region_array.h" +#include "holly/background.h" +#include "holly/ta_parameter.h" +#include "holly.h" +#include "ta.h" + +#include "memorymap.h" +#include "storequeue.h" +#include "systembus.h" +#include "holly/float_uint32.h" + +struct texture_memory_alloc { + uint32_t isp_tsp_parameters[0x00100000 / 4]; // TA_ISP_BASE / PARAM_BASE (the actual objects) + uint32_t object_list[0x00100000 / 4]; // TA_OL_BASE (contains object pointer blocks) + uint32_t _res0[ 0x20 / 4]; // (the TA may clobber 4 bytes starting at TA_OL_LIMIT) + uint32_t region_array[0x00002000 / 4]; // REGION_BASE + uint32_t background[0x00000020 / 4]; // ISP_BACKGND_T + uint32_t framebuffer[0x00096000 / 4]; // FB_R_SOF1 / FB_W_SOF1 +}; + +float scene_triangle[3][3] = { + { 320.f, 120.f, 1/10.f}, + { 440.f, 360.f, 1/10.f}, + { 200.f, 360.f, 1/10.f}, +}; + +void scene_holly_init() +{ + holly.ISP_FEED_CFG = ISP_FEED_CFG__TRANSLUCENCY_CACHE_SIZE(0x200); + + holly.FPU_SHAD_SCALE = FPU_SHAD_SCALE__SCALE_FACTOR(1); + holly.FPU_CULL_VAL = _i(1.f); + holly.FPU_PERP_VAL = _i(0.f); + holly.SPAN_SORT_CFG = SPAN_SORT_CFG__SPAN_SORT_ENABLE + | SPAN_SORT_CFG__OFFSET_SORT_ENABLE; + + holly.FOG_COL_RAM = FOG_COL_RAM__RED(127) + | FOG_COL_RAM__GREEN(127) + | FOG_COL_RAM__BLUE(127); + + holly.FOG_COL_VERT = FOG_COL_VERT__RED(127) + | FOG_COL_VERT__GREEN(127) + | FOG_COL_VERT__BLUE(127); + + holly.FOG_CLAMP_MIN = FOG_CLAMP_MIN__ALPHA(0) + | FOG_CLAMP_MIN__RED(0) + | FOG_CLAMP_MIN__GREEN(0) + | FOG_CLAMP_MIN__BLUE(0); + + holly.FOG_CLAMP_MAX = FOG_CLAMP_MAX__ALPHA(255) + | FOG_CLAMP_MAX__RED(255) + | FOG_CLAMP_MAX__GREEN(255) + | FOG_CLAMP_MAX__BLUE(255); + + holly.HALF_OFFSET = HALF_OFFSET__TSP_TEXEL_SAMPLE_POSITION_CENTER + | HALF_OFFSET__TSP_PIXEL_SAMPLE_POSITION_CENTER + | HALF_OFFSET__FPU_PIXEL_SAMPLE_POSITION_CENTER; + + holly.FPU_PARAM_CFG = FPU_PARAM_CFG__REGION_HEADER_TYPE__2 + | FPU_PARAM_CFG__TSP_PARAMETER_BURST_TRIGGER(31) + | FPU_PARAM_CFG__ISP_PARAMETER_BURST_TRIGGER(31) + | FPU_PARAM_CFG__POINTER_BURST_SIZE(7) // must be less than OPB size + | FPU_PARAM_CFG__POINTER_FIRST_BURST_SIZE(7); // half of pointer burst size(?) +} + +void scene_ta_init() +{ + holly.SOFTRESET = SOFTRESET__TA_SOFT_RESET; + holly.SOFTRESET = 0; + + holly.TA_GLOB_TILE_CLIP = TA_GLOB_TILE_CLIP__TILE_Y_NUM((480 / 32) - 1) + | TA_GLOB_TILE_CLIP__TILE_X_NUM((640 / 32) - 1); + + holly.TA_ALLOC_CTRL = TA_ALLOC_CTRL__OPB_MODE_INCREASING + | TA_ALLOC_CTRL__PT_OPB__NONE + | TA_ALLOC_CTRL__TM_OPB__NONE + | TA_ALLOC_CTRL__T_OPB__NONE + | TA_ALLOC_CTRL__OM_OPB__NONE + | TA_ALLOC_CTRL__O_OPB__16; + + holly.TA_ISP_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); + holly.TA_ISP_LIMIT = (offsetof (struct texture_memory_alloc, object_list)); // the end of isp_tsp_parameters + holly.TA_OL_BASE = (offsetof (struct texture_memory_alloc, object_list)); + holly.TA_OL_LIMIT = (offsetof (struct texture_memory_alloc, region_array)); // the end of the object_list + holly.TA_NEXT_OPB_INIT = (offsetof (struct texture_memory_alloc, object_list)) + + (640 / 32) * (320 / 32) * 16 * 4; + + holly.TA_LIST_INIT = TA_LIST_INIT__LIST_INIT; + + volatile uint32_t _dummy_read = holly.TA_LIST_INIT; + (void)_dummy_read; +} + +void scene_wait_opaque_list() +{ + while ((system.ISTNRM & SB_ISTNRM__TAEOINT) == 0); + + system.ISTNRM = SB_ISTNRM__TAEOINT; +} + +void scene_geometry_transfer() +{ + triangle(store_queue); + sq_transfer_32byte(ta_fifo_polygon_converter); + + for (int i = 0; i < 3; i++) { + bool end_of_strip = i == 2; + + vertex(store_queue, + scene_triangle[i][0], // x + scene_triangle[i][1], // y + scene_triangle[i][2], // z + 0xffff00ff, // base_color + end_of_strip); + + sq_transfer_32byte(ta_fifo_polygon_converter); + } + + end_of_list(store_queue); + sq_transfer_32byte(ta_fifo_polygon_converter); +} + +void scene_init_texture_memory() +{ + volatile texture_memory_alloc * mem = reinterpret_cast(texture_memory); + + background_parameter(mem->background); + region_array(mem->region_array, + (offsetof (struct texture_memory_alloc, object_list)), + 640 / 32, // width + 480 / 32 // height + ); +} + +void scene_start_render() +{ + holly.REGION_BASE = (offsetof (struct texture_memory_alloc, region_array)); + holly.PARAM_BASE = (offsetof (struct texture_memory_alloc, isp_tsp_parameters)); + + holly.ISP_BACKGND_T = ISP_BACKGND_T__TAG_ADDRESS((offsetof (struct texture_memory_alloc, background)) / 4) + | ISP_BACKGND_T__TAG_OFFSET(0) + | ISP_BACKGND_T__SKIP(1); + holly.ISP_BACKGND_D = _i(1.f/100000); + + holly.FB_W_CTRL = FB_W_CTRL__FB_PACKMODE__565_RGB; + holly.FB_W_LINESTRIDE = 640 / 8; + holly.FB_W_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)); + holly.FB_R_SOF1 = (offsetof (struct texture_memory_alloc, framebuffer)); + + holly.STARTRENDER = 1; +} diff --git a/scene.h b/scene.h new file mode 100644 index 0000000..ad77bce --- /dev/null +++ b/scene.h @@ -0,0 +1,8 @@ +#pragma once + +void scene_holly_init(); +void scene_ta_init(); +void scene_init_texture_memory(); +void scene_geometry_transfer(); +void scene_wait_opaque_list(); +void scene_start_render(); diff --git a/sh7091.h b/sh7091.h index c25da18..039e71a 100644 --- a/sh7091.h +++ b/sh7091.h @@ -374,5 +374,4 @@ static_assert((offsetof (struct sh7091_reg, SCI)) == 0xe00000); static_assert((offsetof (struct sh7091_reg, SCIF)) == 0xe80000); static_assert((offsetof (struct sh7091_reg, UDI)) == 0xf00000); -extern struct sh7091_reg SH7091 __asm("SH7091"); - +extern struct sh7091_reg sh7091 __asm("sh7091"); diff --git a/sh7091_bits.h b/sh7091_bits.h index f5b6d28..c0807d5 100644 --- a/sh7091_bits.h +++ b/sh7091_bits.h @@ -13,3 +13,18 @@ #define PDTRA__RESERVED (0b01 << 8) #define PDTRA__RGB (0b10 << 8) #define PDTRA__AV (0b11 << 8) + +#define SCFCR2__TFRST (1 << 2) +#define SCFCR2__RFRST (1 << 1) + +#define SCSCR2__TE (1 << 5) +#define SCSCR2__RE (1 << 4) + +#define SCFSR2__ER (1 << 7) /* read error */ +#define SCFSR2__TEND (1 << 6) /* transmit end */ +#define SCFSR2__TFDE (1 << 5) /* transmit fifo data empty */ +#define SCFSR2__BRK (1 << 4) /* break detect */ +#define SCFSR2__FER (1 << 3) /* framing error */ +#define SCFSR2__PER (1 << 2) /* parity error */ +#define SCFSR2__RDF (1 << 1) /* receive FIFO data full */ +#define SCFSR2__DR (1 << 0) /* receive data ready */ diff --git a/storequeue.cpp b/storequeue.cpp new file mode 100644 index 0000000..e3d05ed --- /dev/null +++ b/storequeue.cpp @@ -0,0 +1,34 @@ +#include "sh7091.h" +#include "memorymap.h" + +void sq_transfer_32byte(volatile void * dst) +{ + // dst typically 0x10000000 (ta polygon converter) + sh7091.CCN.QACR0 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; + + // start 32-byte transfer from store queue 0 (SQ0) to QACR0 + asm volatile ("pref @%0" + : // output + : "r" (&store_queue[0]) // input + ); +} + + +void sq_transfer_64byte(volatile void * dst) +{ + // dst typically 0x10000000 (ta polygon converter) + sh7091.CCN.QACR0 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; + sh7091.CCN.QACR1 = ((reinterpret_cast(dst) >> 26) & 0b111) << 2; + + // start 32-byte transfer from store queue 0 (SQ0) to QACR0 + asm volatile ("pref @%0" + : // output + : "r" (&store_queue[0]) // input + ); + + // start 32-byte transfer from store queue 1 (SQ1) to QACR1 + asm volatile ("pref @%0" + : // output + : "r" (&store_queue[8]) // input + ); +} diff --git a/storequeue.h b/storequeue.h new file mode 100644 index 0000000..aae33bb --- /dev/null +++ b/storequeue.h @@ -0,0 +1,4 @@ +#pragma once + +void sq_transfer_32byte(volatile void * dst); +void sq_transfer_64byte(volatile void * dst); diff --git a/systembus.h b/systembus.h index d1a5fac..4aad7ae 100644 --- a/systembus.h +++ b/systembus.h @@ -301,13 +301,12 @@ static_assert((offsetof (struct pvr_if_reg, PDSTAPD)) == 0xf0); static_assert((offsetof (struct pvr_if_reg, PDSTARD)) == 0xf4); static_assert((offsetof (struct pvr_if_reg, PDLEND)) == 0xf8); -extern struct system_reg SYSTEM __asm("SYSTEM"); +extern struct system_reg system __asm("system"); -extern struct maple_if_reg MAPLE_IF __asm("MAPLE_IF"); +extern struct maple_if_reg maple_if __asm("maple_if"); -extern struct g1_if_reg G1_IF __asm("G1_IF"); +extern struct g1_if_reg g1_if __asm("g1_if"); -extern struct g2_if_reg G2_IF __asm("G2_IF"); - -extern struct pvr_if_reg PVR_IF __asm("PVR_IF"); +extern struct g2_if_reg g2_if __asm("g2_if"); +extern struct pvr_if_reg pvr_if __asm("pvr_if"); diff --git a/ta.h b/ta.h new file mode 100644 index 0000000..43a6662 --- /dev/null +++ b/ta.h @@ -0,0 +1,88 @@ +#define ISP_FEED_CFG__TRANSLUCENCY_CACHE_SIZE(n) (((n) & 0x3ff) << 14) + +#define FPU_SHAD_SCALE__INTENSITY_SHADOW_ENABLE (1 << 8) +#define FPU_SHAD_SCALE__SCALE_FACTOR(n) (((n) & 0xff) << 0) + +#define FPU_CULL_VAL__COMPARISON_VALUE(n) (_u32(__builtin_fabsf(n))) + +#define FPU_PERP_VAL__COMPARISON_VALUE(n) (_u32(__builtin_fabsf(n))) + +#define SPAN_SORT_CFG__CACHE_BYPASS (1 << 16) +#define SPAN_SORT_CFG__OFFSET_SORT_ENABLE (1 << 8) +#define SPAN_SORT_CFG__SPAN_SORT_ENABLE (1 << 0) + +#define FOG_COL_RAM__RED(n) (((n) & 0xff) << 16) +#define FOG_COL_RAM__GREEN(n) (((n) & 0xff) << 8) +#define FOG_COL_RAM__BLUE(n) (((n) & 0xff) << 0) + +#define FOG_COL_VERT__RED(n) (((n) & 0xff) << 16) +#define FOG_COL_VERT__GREEN(n) (((n) & 0xff) << 8) +#define FOG_COL_VERT__BLUE(n) (((n) & 0xff) << 0) + +#define FOG_CLAMP_MIN__ALPHA(n) (((n) & 0xff) << 24) +#define FOG_CLAMP_MIN__RED(n) (((n) & 0xff) << 16) +#define FOG_CLAMP_MIN__GREEN(n) (((n) & 0xff) << 8) +#define FOG_CLAMP_MIN__BLUE(n) (((n) & 0xff) << 0) + +#define FOG_CLAMP_MAX__ALPHA(n) (((n) & 0xff) << 24) +#define FOG_CLAMP_MAX__RED(n) (((n) & 0xff) << 16) +#define FOG_CLAMP_MAX__GREEN(n) (((n) & 0xff) << 8) +#define FOG_CLAMP_MAX__BLUE(n) (((n) & 0xff) << 0) + +#define HALF_OFFSET__TSP_TEXEL_SAMPLE_POSITION_CENTER (1 << 2) +#define HALF_OFFSET__TSP_PIXEL_SAMPLE_POSITION_CENTER (1 << 1) +#define HALF_OFFSET__FPU_PIXEL_SAMPLE_POSITION_CENTER (1 << 0) + +#define FPU_PARAM_CFG__REGION_HEADER_TYPE__1 (0 << 21) +#define FPU_PARAM_CFG__REGION_HEADER_TYPE__2 (1 << 21) +#define FPU_PARAM_CFG__TSP_PARAMETER_BURST_TRIGGER(n) (((n) & 0x3f) << 14) +#define FPU_PARAM_CFG__ISP_PARAMETER_BURST_TRIGGER(n) (((n) & 0x3f) << 8) +#define FPU_PARAM_CFG__POINTER_BURST_SIZE(n) (((n) & 0xf) << 4) +#define FPU_PARAM_CFG__POINTER_FIRST_BURST_SIZE(n) (((n) & 0xf) << 0) + +// -------------------- + +#define TA_GLOB_TILE_CLIP__TILE_Y_NUM(n) (((n) & 0b1111) << 16) +#define TA_GLOB_TILE_CLIP__TILE_X_NUM(n) (((n) & 0b11111) << 0) + +#define TA_ALLOC_CTRL__OPB_MODE_INCREASING (0 << 20) +#define TA_ALLOC_CTRL__OPB_MODE_DECREASING (1 << 20) +#define TA_ALLOC_CTRL__PT_OPB__NONE (0b00 << 16) +#define TA_ALLOC_CTRL__PT_OPB__8 (0b01 << 16) +#define TA_ALLOC_CTRL__PT_OPB__16 (0b10 << 16) +#define TA_ALLOC_CTRL__PT_OPB__32 (0b11 << 16) +#define TA_ALLOC_CTRL__TM_OPB__NONE (0b00 << 12) +#define TA_ALLOC_CTRL__TM_OPB__8 (0b01 << 12) +#define TA_ALLOC_CTRL__TM_OPB__16 (0b10 << 12) +#define TA_ALLOC_CTRL__TM_OPB__32 (0b11 << 12) +#define TA_ALLOC_CTRL__T_OPB__NONE (0b00 << 8) +#define TA_ALLOC_CTRL__T_OPB__8 (0b01 << 8) +#define TA_ALLOC_CTRL__T_OPB__16 (0b10 << 8) +#define TA_ALLOC_CTRL__T_OPB__32 (0b11 << 8) +#define TA_ALLOC_CTRL__OM_OPB__NONE (0b00 << 4) +#define TA_ALLOC_CTRL__OM_OPB__8 (0b01 << 4) +#define TA_ALLOC_CTRL__OM_OPB__16 (0b10 << 4) +#define TA_ALLOC_CTRL__OM_OPB__32 (0b11 << 4) +#define TA_ALLOC_CTRL__O_OPB__NONE (0b00 << 0) +#define TA_ALLOC_CTRL__O_OPB__8 (0b01 << 0) +#define TA_ALLOC_CTRL__O_OPB__16 (0b10 << 0) +#define TA_ALLOC_CTRL__O_OPB__32 (0b11 << 0) + +#define SOFTRESET__SDRAM_IF_SOFT_RESET (1 << 2) +#define SOFTRESET__CORE_SOFT_RESET (1 << 1) +#define SOFTRESET__TA_SOFT_RESET (1 << 0) + +#define TA_LIST_INIT__LIST_INIT (1 << 31) + +#define SB_ISTNRM__TAEOINT (1 << 7) // End of Transferring interrupt : Opaque List + +#define FB_W_CTRL__FB_PACKMODE__565_RGB (1 << 0); + +#define ISP_BACKGND_T__CACHE_BYPASS (1 << 28) +#define ISP_BACKGND_T__SHADOW (1 << 27) +#define ISP_BACKGND_T__SKIP(n) (((n) & 0b111) << 24) +//#define ISP_BACKGND_T__TAG_ADDRESS(n) ((n) & 0xfffff8) +#define ISP_BACKGND_T__TAG_ADDRESS(n) (((n) & 0x3fffff) << 3) +#define ISP_BACKGND_T__TAG_OFFSET(n) (((n) & 0b111) << 0) + +// ---------- diff --git a/test.c b/test.c index 05f2a08..96b70a2 100644 --- a/test.c +++ b/test.c @@ -13,6 +13,8 @@ void *memcpy(void *restrict dest, const void *restrict src, size_t n) return dest; } +extern uint32_t _binary_DSC08384_data_start __asm("_binary_DSC08384_data_start"); + void start(void) { /* @@ -25,35 +27,35 @@ void start(void) G2_IF.G2APRO = 0x4659404f; */ - HOLLY.SOFTRESET = 0b111; - HOLLY.TEXT_CONTROL = 3; + holly.SOFTRESET = 0b111; + holly.TEXT_CONTROL = 3; uint16_t xsize = 640; uint16_t ysize = 480; uint16_t fb_xclip_min = 0; uint16_t fb_xclip_max = xsize-1; - HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); + holly.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); uint16_t fb_yclip_min = 0; uint16_t fb_yclip_max = ysize-1; - HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); + holly.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); uint32_t fb_xsize = (xsize * 16)/(32) - 1; uint32_t fb_ysize = ysize - 3; uint32_t fb_mod = 1; - HOLLY.FB_R_SIZE = 0 + holly.FB_R_SIZE = 0 | (fb_xsize << 0) | (fb_ysize << 10) | (fb_mod << 20); uint32_t fb_linestride = (xsize * 16) / 64; - HOLLY.FB_W_LINESTRIDE = fb_linestride; + holly.FB_W_LINESTRIDE = fb_linestride; - HOLLY.FB_W_CTRL = 0 + holly.FB_W_CTRL = 0 | 0b001 << 0 // fb_packmode: RGB 565 ; - HOLLY.FB_R_CTRL = 0 + holly.FB_R_CTRL = 0 | 1 << 23 // vclk_div | 0 << 22 // fb_strip_buf_en | 0 << 16 // fb_strip_size @@ -64,43 +66,43 @@ void start(void) | 1 << 0 // fb_enable ; - HOLLY.FB_W_SOF1 = 0; - HOLLY.FB_W_SOF2 = 0; - HOLLY.FB_R_SOF1 = 0; - HOLLY.FB_R_SOF2 = 0; + holly.FB_W_SOF1 = 0; + holly.FB_W_SOF2 = 0; + holly.FB_R_SOF1 = 0; + holly.FB_R_SOF2 = 0; - HOLLY.VO_BORDER_COL = (31 << 11) | (31 << 0); + holly.VO_BORDER_COL = (31 << 11) | (31 << 0); uint16_t startx = 0x0a8; uint16_t starty = 0x028; - HOLLY.VO_STARTX = startx; - HOLLY.VO_STARTY = (starty << 16) | (starty << 0); + holly.VO_STARTX = startx; + holly.VO_STARTY = (starty << 16) | (starty << 0); - HOLLY.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default + holly.SPG_CONTROL = (1 << 8); // sync_direction__output ; non-default uint16_t hbstart = 0x0345; // default uint16_t hbend = 0x007e; // default - HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0); + holly.SPG_HBLANK = (hbend << 16) | (hbstart << 0); uint16_t hcount = 0x0359; // default uint16_t vcount = 0x020c; // non-default - HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0); + holly.SPG_LOAD = (vcount << 16) | (hcount << 0); uint16_t vbstart = 0x0208; // non-default uint16_t vbend = 0x0028; // non-default - HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0); + holly.SPG_VBLANK = (vbend << 16) | (vbstart << 0); uint16_t hswidth = 0x003f; uint16_t vswidth = 0x0003; uint16_t bpwidth = 0x0319; uint16_t eqwidth = 0x000f; - HOLLY.SPG_WIDTH = + holly.SPG_WIDTH = (hswidth << 0) | (vswidth << 8) | (bpwidth << 12) | (eqwidth << 22); - HOLLY.SPG_HBLANK_INT = hbstart << 16; + holly.SPG_HBLANK_INT = hbstart << 16; uint32_t hsync_pol = 0; uint32_t vsync_pol = 0; @@ -109,7 +111,7 @@ void start(void) uint32_t field_mode = 0; uint32_t pixel_double = 0; uint32_t pclk_delay = 0x16; - HOLLY.VO_CONTROL = 0 + holly.VO_CONTROL = 0 | (( pclk_delay & 0x3f) << 16 ) | (( pixel_double & 0x01) << 8 ) | (( field_mode & 0x0f) << 4 ) @@ -119,7 +121,9 @@ void start(void) | (( hsync_pol & 0x01) << 0 ); - HOLLY.SOFTRESET = 0b000; + holly.SOFTRESET = 0b000; + + const uint8_t * buf = (const uint8_t *)&_binary_DSC08384_data_start; reg16 * vram = (reg16 *)0xa5000000; v_sync_in(); @@ -130,15 +134,22 @@ void start(void) struct rgb rgb = hsv_to_rgb(hsv); vram[y * 640 + x] = ((rgb.r >> 3) << 11) | ((rgb.g >> 2) << 5) | ((rgb.b >> 3) << 0); */ - vram[y * 640 + x] = 30 << 5 | 31 << 11; + //vram[y * 640 + x] = 30 << 5 | 31 << 11; + uint32_t ix = y * 640 + x; + uint8_t r = buf[ix * 3 + 0]; + uint8_t g = buf[ix * 3 + 1]; + uint8_t b = buf[ix * 3 + 2]; + vram[ix] = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0); } } + /* vram[0] = 0xffff; vram[10] = 0xffff; vram[639] = 0xffff; vram[307199 - (640 * 3) - 1] = 0xffff; vram[307199 - (640 * 2) - 10] = 31 << 11; vram[307199 - (640 * 1) - 1] = 0xffff; + */ //vram[307199 - (640 * 2) - 10] = 0xf0ff; //vram[307199 - 640 - 10] = 0xf0ff; //vram[307199 - 10] = 0xf0ff; diff --git a/vga.c b/vga.cpp similarity index 63% rename from vga.c rename to vga.cpp index a0d0308..b9646af 100644 --- a/vga.c +++ b/vga.cpp @@ -10,45 +10,45 @@ uint32_t get_cable_type() { /* set all pins to input */ - SH7091.BSC.PCTRA = 0; + sh7091.BSC.PCTRA = 0; /* get cable type from pins 9 + 8 */ - return SH7091.BSC.PDTRA & PDTRA__MASK; + return sh7091.BSC.PDTRA & PDTRA__MASK; } void vga1() { - uint32_t fb_r_ctrl = HOLLY.FB_R_CTRL; - HOLLY.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0 + uint32_t fb_r_ctrl = holly.FB_R_CTRL; + holly.FB_R_CTRL = fb_r_ctrl & ~(1 << 0); // fb_enable = 0 uint32_t blank_video = 1; - HOLLY.VO_CONTROL |= (blank_video << 3); // blank_video + holly.VO_CONTROL |= (blank_video << 3); // blank_video - HOLLY.FB_R_SIZE = 0; + holly.FB_R_SIZE = 0; uint32_t vblank_in = 0x0208; uint32_t vblank_out = 0x0015; - HOLLY.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0); + holly.SPG_VBLANK_INT = (vblank_out << 16) | (vblank_in << 0); uint32_t sync_direction = 1; - HOLLY.SPG_CONTROL = (sync_direction << 8); + holly.SPG_CONTROL = (sync_direction << 8); uint32_t hbstart = 0x0345; // default uint32_t hbend = 0x007e; // default - HOLLY.SPG_HBLANK = (hbend << 16) | (hbstart << 0); + holly.SPG_HBLANK = (hbend << 16) | (hbstart << 0); uint32_t hcount = 0x0359; // default uint32_t vcount = 0x020c; // non-default - HOLLY.SPG_LOAD = (vcount << 16) | (hcount << 0); + holly.SPG_LOAD = (vcount << 16) | (hcount << 0); uint32_t vbstart = 0x0208; // non-default uint32_t vbend = 0x0028; // non-default - HOLLY.SPG_VBLANK = (vbend << 16) | (vbstart << 0); + holly.SPG_VBLANK = (vbend << 16) | (vbstart << 0); uint32_t hswidth = 0x003f; uint32_t vswidth = 0x0003; uint32_t bpwidth = 0x0319; uint32_t eqwidth = 0x000f; - HOLLY.SPG_WIDTH = + holly.SPG_WIDTH = (hswidth << 0) | (vswidth << 8) | (bpwidth << 12) @@ -56,54 +56,47 @@ void vga1() uint32_t startx = 0x0a8; uint32_t starty = 0x028; - HOLLY.VO_STARTX = startx; - HOLLY.VO_STARTY = (starty << 16) | (starty << 0); + holly.VO_STARTX = startx; + holly.VO_STARTY = (starty << 16) | (starty << 0); - HOLLY.SPG_HBLANK_INT = hbstart << 16; + holly.SPG_HBLANK_INT = hbstart << 16; } void vga2() { - HOLLY.FB_BURSTCTRL = 0x00093f39; + holly.FB_BURSTCTRL = 0x00093f39; uint32_t xsize = 640; uint32_t ysize = 480; uint32_t fb_xclip_min = 0; uint32_t fb_xclip_max = xsize-1; - HOLLY.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); + holly.FB_X_CLIP = (fb_xclip_max << 16) | (fb_xclip_min << 0); uint32_t fb_yclip_min = 0; uint32_t fb_yclip_max = ysize-1; - HOLLY.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); + holly.FB_Y_CLIP = (fb_yclip_max << 16) | (fb_yclip_min << 0); uint32_t fb_xsize = (xsize * 16)/(32) - 1; uint32_t fb_ysize = ysize - 3; uint32_t fb_mod = 1; - HOLLY.FB_R_SIZE = 0 + holly.FB_R_SIZE = 0 | (fb_xsize << 0) | (fb_ysize << 10) | (fb_mod << 20); uint32_t coeff0 = 0x40; uint32_t coeff1 = 0x80; - HOLLY.Y_COEFF = (coeff1 << 8) | (coeff0 << 0); + holly.Y_COEFF = (coeff1 << 8) | (coeff0 << 0); uint32_t vscale_factor = 0x0400; - HOLLY.SCALER_CTL = (vscale_factor << 0); + holly.SCALER_CTL = (vscale_factor << 0); - uint32_t fb_linestride = (xsize * 16) / 64; - HOLLY.FB_W_LINESTRIDE = fb_linestride; + holly.FB_W_SOF1 = 0; + holly.FB_W_SOF2 = 0; + holly.FB_R_SOF1 = 0; + holly.FB_R_SOF2 = 0; - HOLLY.FB_W_CTRL = 0 - | 0b001 << 0 // fb_packmode: RGB 565 - ; - - HOLLY.FB_W_SOF1 = 0; - HOLLY.FB_W_SOF2 = 0; - HOLLY.FB_R_SOF1 = 0; - HOLLY.FB_R_SOF2 = 0; - - HOLLY.FB_R_CTRL = 0 + holly.FB_R_CTRL = 0 | 1 << 23 // vclk_div | 0 << 22 // fb_strip_buf_en | 0 << 16 // fb_strip_size @@ -121,7 +114,7 @@ void vga2() uint32_t field_mode = 0; uint32_t pixel_double = 0; uint32_t pclk_delay = 0x16; - HOLLY.VO_CONTROL = 0 + holly.VO_CONTROL = 0 | (( pclk_delay & 0x3f) << 16 ) | (( pixel_double & 0x01) << 8 ) | (( field_mode & 0x0f) << 4 ) @@ -136,10 +129,10 @@ void vga2() void v_sync_in() { #define V_SYNC (1<<13) - while (!(V_SYNC & HOLLY.SPG_STATUS)) { + while (!(V_SYNC & holly.SPG_STATUS)) { asm volatile ("nop"); } - while ((V_SYNC & HOLLY.SPG_STATUS)) { + while ((V_SYNC & holly.SPG_STATUS)) { asm volatile ("nop"); } #undef V_SYNC @@ -148,10 +141,10 @@ void v_sync_in() void v_sync_out() { #define V_SYNC (1<<13) - while ((V_SYNC & HOLLY.SPG_STATUS)) { + while ((V_SYNC & holly.SPG_STATUS)) { asm volatile ("nop"); } - while (!(V_SYNC & HOLLY.SPG_STATUS)) { + while (!(V_SYNC & holly.SPG_STATUS)) { asm volatile ("nop"); } #undef V_SYNC @@ -161,9 +154,9 @@ void vga() { get_cable_type(); - HOLLY.SOFTRESET = 0b111; - HOLLY.TEXT_CONTROL = 3; - HOLLY.FB_W_CTRL = 9; + holly.SOFTRESET = 0b111; + holly.TEXT_CONTROL = 3; + holly.FB_W_CTRL = 9; /* */ @@ -172,10 +165,10 @@ void vga() v_sync_in(); - HOLLY.VO_BORDER_COL = (63 << 5) | (31 << 0); - HOLLY.VO_CONTROL = 0x0016; + holly.VO_BORDER_COL = (63 << 5) | (31 << 0); + holly.VO_CONTROL = 0x0016; - HOLLY.SOFTRESET = 0b000; + holly.SOFTRESET = 0b000; } void fill_framebuffer()