diff --git a/example/bsp/20kdm2.cpp b/example/bsp/20kdm2.cpp index 010e94a..4e8752e 100644 --- a/example/bsp/20kdm2.cpp +++ b/example/bsp/20kdm2.cpp @@ -1470,7 +1470,7 @@ mat4x4 update_analog(const mat4x4& screen) 0, 0, 0, 1, }; - float yt = 0.05f * x_; + float yt = -0.05f * x_; float xt = 0.05f * y_; /* @@ -1547,8 +1547,108 @@ void transfer_font() printf("font_base %d actual %d\n", font_base, offset); } +void vbr100() +{ + serial::string("vbr100\n"); + interrupt_exception(); +} + +void vbr400() +{ + serial::string("vbr400\n"); + interrupt_exception(); +} + +const int framebuffer_width = 640; +const int framebuffer_height = 480; +const int tile_width = framebuffer_width / 32; +const int tile_height = framebuffer_height / 32; + +constexpr uint32_t ta_alloc = 0 + | ta_alloc_ctrl::pt_opb::_16x4byte + | ta_alloc_ctrl::tm_opb::no_list + | ta_alloc_ctrl::t_opb::no_list + | ta_alloc_ctrl::om_opb::_16x4byte + | ta_alloc_ctrl::o_opb::no_list; + +constexpr int ta_cont_count = 1; +constexpr struct opb_size opb_size[ta_cont_count] = { + { + .opaque = 0, + .opaque_modifier = 16 * 4, + .translucent = 0, + .translucent_modifier = 0, + .punch_through = 16 * 4 + } +}; + +static volatile int ta_in_use = 0; +static volatile int core_in_use = 0; +static volatile int next_frame; + +static inline void pump_events(uint32_t istnrm) +{ + if (istnrm & istnrm::v_blank_in) { + system.ISTNRM = istnrm::v_blank_in; + + holly.FB_R_SOF1 = texture_memory_alloc.framebuffer[next_frame].start; + } + + if (istnrm & istnrm::end_of_render_tsp) { + system.ISTNRM = istnrm::end_of_render_tsp + | istnrm::end_of_render_isp + | istnrm::end_of_render_video; + + core_in_use = 0; + } + + if (istnrm & istnrm::end_of_transferring_opaque_modifier_volume_list) { + system.ISTNRM = istnrm::end_of_transferring_opaque_modifier_volume_list; + + ta_in_use = 0; + } +} + +void vbr600() +{ + uint32_t sr; + asm volatile ("stc sr,%0" : "=r" (sr)); + sr |= sh::sr::imask(15); + asm volatile ("ldc %0,sr" : : "r" (sr)); + //serial::string("imask\n"); + + //check_pipeline(); + + if (sh7091.CCN.EXPEVT == 0 && sh7091.CCN.INTEVT == 0x320) { + uint32_t istnrm = system.ISTNRM; + uint32_t isterr = system.ISTERR; + + if (isterr) { + serial::string("isterr: "); + serial::integer(system.ISTERR); + } + + pump_events(istnrm); + + sr &= ~sh::sr::imask(15); + asm volatile ("ldc %0,sr" : : "r" (sr)); + + return; + } + + serial::string("vbr600\n"); + interrupt_exception(); +} + int main() { + sh7091.TMU.TSTR = 0; // stop all timers + sh7091.TMU.TOCR = tmu::tocr::tcoe::tclk_is_external_clock_or_input_capture; + sh7091.TMU.TCR0 = tmu::tcr0::tpsc::p_phi_256; // 256 / 50MHz = 5.12 μs ; underflows in ~1 hour + sh7091.TMU.TCOR0 = 0xffff'ffff; + sh7091.TMU.TCNT0 = 0xffff'ffff; + sh7091.TMU.TSTR = tmu::tstr::str0::counter_start; + serial::init(0); total_tri_count = count_face_triangles(); @@ -1558,36 +1658,15 @@ int main() transfer_font(); palette_data<3>(); - constexpr uint32_t ta_alloc = 0 - | ta_alloc_ctrl::pt_opb::_16x4byte - | ta_alloc_ctrl::tm_opb::no_list - | ta_alloc_ctrl::t_opb::no_list - | ta_alloc_ctrl::om_opb::_16x4byte - | ta_alloc_ctrl::o_opb::no_list; - - constexpr int ta_cont_count = 1; - constexpr struct opb_size opb_size[ta_cont_count] = { - { - .opaque = 0, - .opaque_modifier = 16 * 4, - .translucent = 0, - .translucent_modifier = 0, - .punch_through = 16 * 4 - } - }; - holly.SOFTRESET = softreset::pipeline_soft_reset | softreset::ta_soft_reset; holly.SOFTRESET = 0; core_init(); - system.IML6NRM = istnrm::end_of_render_tsp; - - const int framebuffer_width = 640; - const int framebuffer_height = 480; - const int tile_width = framebuffer_width / 32; - const int tile_height = framebuffer_height / 32; + system.IML6NRM = istnrm::end_of_render_tsp + | istnrm::v_blank_in + | istnrm::end_of_transferring_opaque_modifier_volume_list; for (int i = 0; i < 2; i++) { region_array_multipass(tile_width, @@ -1605,9 +1684,6 @@ int main() video_output::set_mode_vga(); - int ta = 0; - int core = 0; - /* mat4x4 trans1 = { 1.0, 0.0, 0.000, -1123.0, @@ -1627,46 +1703,61 @@ int main() holly.FPU_SHAD_SCALE = fpu_shad_scale::simple_shadow_enable::parameter_selection_volume_mode; + for (int i = 0; i < 2; i++) { + trans = update_analog(trans); + mat4x4 trans_inv = inverse(trans); + writer.offset = 0; + transfer_scene(writer, trans, trans_inv); + + ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters[i].start, + texture_memory_alloc.isp_tsp_parameters[i].end, + texture_memory_alloc.object_list[i].start, + texture_memory_alloc.object_list[i].end, + opb_size[0].total(), + ta_alloc, + tile_width, + tile_height); + ta_polygon_converter_writeback(writer.buf, writer.offset); + ta_polygon_converter_transfer(writer.buf, writer.offset); + while (ta_in_use); + } + + int ta = 0; + while (1) { + int core = !ta; + maple::dma_wait_complete(); do_get_condition(); trans = update_analog(trans); - mat4x4 trans_inv = inverse(trans); - - ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters[ta].start, - texture_memory_alloc.isp_tsp_parameters[ta].end, - texture_memory_alloc.object_list[ta].start, - texture_memory_alloc.object_list[ta].end, - opb_size[0].total(), - ta_alloc, - tile_width, - tile_height); - writer.offset = 0; transfer_scene(writer, trans, trans_inv); + + while (ta_in_use); + ta_in_use = 1; + ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters[ta].start, + texture_memory_alloc.isp_tsp_parameters[ta].end, + texture_memory_alloc.object_list[ta].start, + texture_memory_alloc.object_list[ta].end, + opb_size[0].total(), + ta_alloc, + tile_width, + tile_height); ta_polygon_converter_writeback(writer.buf, writer.offset); ta_polygon_converter_transfer(writer.buf, writer.offset); - //serial::integer(writer.offset); - //serial::integer(typen_tri_count); - //serial::string("wait_pt\n"); - ta_wait_opaque_modifier_volume_list(); - //ta_wait_opaque_list(); - render_done = 0; + while (current_frame != core); + core_in_use = 1; core_start_render2(texture_memory_alloc.region_array[core].start, texture_memory_alloc.isp_tsp_parameters[core].start, texture_memory_alloc.background[core].start, texture_memory_alloc.framebuffer[core].start, framebuffer_width); - //serial::string("wait_render\n"); - while (render_done == 0) { - asm volatile ("nop"); - }; - while (spg_status::vsync(holly.SPG_STATUS)); - while (!spg_status::vsync(holly.SPG_STATUS)); - holly.FB_R_SOF1 = texture_memory_alloc.framebuffer[ta].start; + ta = !ta; + + next_frame = ta; } } diff --git a/example/bsp/bsp.mk b/example/bsp/bsp.mk index 1a06349..caea799 100644 --- a/example/bsp/bsp.mk +++ b/example/bsp/bsp.mk @@ -10,7 +10,6 @@ BSP_20KDM2_OBJ = \ printf/printf.o \ printf/unparse.o \ printf/parse.o \ - interrupt.o \ maple/maple.o \ font/font_bitmap.o \ font/verite_8x16/verite_8x16.data.o \ diff --git a/interrupt.cpp b/interrupt.cpp index 7314fea..ae3708f 100644 --- a/interrupt.cpp +++ b/interrupt.cpp @@ -1,53 +1,15 @@ -#include "sh7091/sh7091.hpp" -#include "sh7091/sh7091_bits.hpp" -#include "sh7091/serial.hpp" -#include "sh7091/vbr.hpp" - -#include "systembus.hpp" -#include "systembus_bits.hpp" +#include "interrupt.hpp" void vbr100() { serial::string("vbr100\n"); - serial::string("expevt "); - serial::integer(sh7091.CCN.EXPEVT); - serial::string("intevt "); - serial::integer(sh7091.CCN.INTEVT); - serial::string("tra "); - serial::integer(sh7091.CCN.TRA); - - uint32_t spc; - uint32_t ssr; - asm volatile ("stc spc,%0" : "=r" (spc)); - asm volatile ("stc ssr,%0" : "=r" (ssr)); - serial::string("spc "); - serial::integer(spc); - serial::string("ssr "); - serial::integer(ssr); - - while (1); + interrupt_exception(); } void vbr400() { serial::string("vbr400\n"); - serial::string("expevt "); - serial::integer(sh7091.CCN.EXPEVT); - serial::string("intevt "); - serial::integer(sh7091.CCN.INTEVT); - serial::string("tra "); - serial::integer(sh7091.CCN.TRA); - - uint32_t spc; - uint32_t ssr; - asm volatile ("stc spc,%0" : "=r" (spc)); - asm volatile ("stc ssr,%0" : "=r" (ssr)); - serial::string("spc "); - serial::integer(spc); - serial::string("ssr "); - serial::integer(ssr); - - while (1); + interrupt_exception(); } int render_done = 0; @@ -68,78 +30,11 @@ void vbr600() | istnrm::end_of_render_isp | istnrm::end_of_render_video; render_done = 1; + serial::string("eor\n"); return; } } serial::string("vbr600\n"); - serial::string("expevt "); - serial::integer(sh7091.CCN.EXPEVT); - serial::string("intevt "); - serial::integer(sh7091.CCN.INTEVT); - serial::string("tra "); - serial::integer(sh7091.CCN.TRA); - - serial::string("istnrm: "); - serial::integer(system.ISTNRM); - serial::string("isterr: "); - serial::integer(system.ISTERR); - - uint32_t spc; - uint32_t ssr; - asm volatile ("stc spc,%0" : "=r" (spc)); - asm volatile ("stc ssr,%0" : "=r" (ssr)); - serial::string("spc "); - serial::integer(spc); - serial::string("ssr "); - serial::integer(ssr); - - while (1); -} - -void interrupt_init() -{ - system.IML2NRM = 0; - system.IML2ERR = 0; - system.IML2EXT = 0; - - system.IML4NRM = 0; - system.IML4ERR = 0; - system.IML4EXT = 0; - - system.IML6NRM = 0; - system.IML6ERR = 0; - system.IML6EXT = 0; - - system.ISTERR = 0xffffffff; - system.ISTNRM = 0xffffffff; - - sh7091.CCN.INTEVT = 0; - sh7091.CCN.EXPEVT = 0; - - uint32_t vbr = reinterpret_cast(&__vbr_link_start) - 0x100; - serial::string("vbr "); - serial::integer(vbr); - serial::string("vbr100 "); - serial::integer(reinterpret_cast(&vbr100)); - - asm volatile ("ldc %0,vbr" - : - : "r" (vbr)); - - uint32_t sr; - asm volatile ("stc sr,%0" - : "=r" (sr)); - serial::string("sr "); - serial::integer(sr); - - sr &= ~sh::sr::bl; // BL - sr &= ~sh::sr::imask(15); // imask - - serial::string("sr "); - serial::integer(sr); - - asm volatile ("ldc %0,sr" - : - : "r" (sr)); + interrupt_exception(); } diff --git a/interrupt.hpp b/interrupt.hpp index 171bbd5..2271297 100644 --- a/interrupt.hpp +++ b/interrupt.hpp @@ -1,5 +1,86 @@ #pragma once +#include "sh7091/sh7091.hpp" +#include "sh7091/sh7091_bits.hpp" +#include "sh7091/serial.hpp" +#include "sh7091/vbr.hpp" + +#include "systembus.hpp" +#include "systembus_bits.hpp" + extern int render_done; void interrupt_init(); + +static inline __attribute__((always_inline)) void interrupt_exception() +{ + serial::string("expevt "); + serial::integer(sh7091.CCN.EXPEVT); + serial::string("intevt "); + serial::integer(sh7091.CCN.INTEVT); + serial::string("tra "); + serial::integer(sh7091.CCN.TRA); + + serial::string("istnrm: "); + serial::integer(system.ISTNRM); + serial::string("isterr: "); + serial::integer(system.ISTERR); + + uint32_t spc; + uint32_t ssr; + asm volatile ("stc spc,%0" : "=r" (spc)); + asm volatile ("stc ssr,%0" : "=r" (ssr)); + serial::string("spc "); + serial::integer(spc); + serial::string("ssr "); + serial::integer(ssr); + + while (1); +} + +void interrupt_init() +{ + system.IML2NRM = 0; + system.IML2ERR = 0; + system.IML2EXT = 0; + + system.IML4NRM = 0; + system.IML4ERR = 0; + system.IML4EXT = 0; + + system.IML6NRM = 0; + system.IML6ERR = 0; + system.IML6EXT = 0; + + system.ISTERR = 0xffffffff; + system.ISTNRM = 0xffffffff; + + sh7091.CCN.INTEVT = 0; + sh7091.CCN.EXPEVT = 0; + + uint32_t vbr = reinterpret_cast(&__vbr_link_start) - 0x100; + serial::string("vbr "); + serial::integer(vbr); + serial::string("vbr100 "); + serial::integer(reinterpret_cast(&vbr100)); + + asm volatile ("ldc %0,vbr" + : + : "r" (vbr)); + + uint32_t sr; + asm volatile ("stc sr,%0" + : "=r" (sr)); + serial::string("sr "); + serial::integer(sr); + + sr &= ~sh::sr::bl; // BL + sr &= ~sh::sr::imask(15); // imask + + serial::string("sr "); + serial::integer(sr); + + asm volatile ("ldc %0,sr" + : + : "r" (sr)); +}