runner_dreamcast: render in v_blank_in_interrupt

This allows solutions to use printf without returning.
This commit is contained in:
Zack Buhman 2024-12-04 22:38:16 -06:00
parent acff0d9dd3
commit 735a088add

View File

@ -16,6 +16,12 @@
#include "sh7091/store_queue.hpp"
#include "sh7091/serial.hpp"
#include "sh7091/vbr.hpp"
#include "sh7091/sh7091.hpp"
#include "sh7091/sh7091_bits.hpp"
#include "systembus.hpp"
#include "systembus_bits.hpp"
#include "font/font.hpp"
#include "font/dejavusansmono/dejavusansmono.data.h"
@ -161,12 +167,6 @@ void copy_font(const uint8_t * src,
}
}
int main()
{
serial::init(0);
serial::string("framebuffer: ");
serial::integer<uint32_t>((uint32_t)&texture_memory32[texture_memory_alloc::framebuffer[0].start / 4]);
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::_32x4byte
@ -184,65 +184,27 @@ int main()
}
};
holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset;
holly.SOFTRESET = 0;
static int ta;
static int core;
core_init();
const struct font * font;
const struct glyph * glyphs;
constexpr int framebuffer_width = 640;
constexpr int framebuffer_height = 480;
constexpr int tile_width = framebuffer_width / 32;
constexpr int tile_height = framebuffer_height / 32;
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[0].start,
texture_memory_alloc::object_list[0].start);
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[1].start,
texture_memory_alloc::object_list[1].start);
static uint32_t frame = 0;
background_parameter2(texture_memory_alloc::background[0].start,
0xff220033);
background_parameter2(texture_memory_alloc::background[1].start,
0xff220033);
auto font = reinterpret_cast<const struct font *>(&_binary_font_dejavusansmono_dejavusansmono_data_start);
auto glyphs = reinterpret_cast<const struct glyph *>(&font[1]);
auto texture = reinterpret_cast<const uint8_t *>(&glyphs[font->glyph_count]);
copy_font(texture, font->max_z_curve_ix);
palette_data<256>();
int ta = -1;
int core = -2;
struct runner_state runner_state = {0};
video_output::set_mode_vga();
bool done = false;
while (true) {
void render()
{
if (core >= 0) {
// core = 0 ; core = 1
// ta = 1 ; ta = 0
core_wait_end_of_render_video();
while (!spg_status::vsync(holly.SPG_STATUS));
frame += 1;
holly.FB_R_SOF1 = texture_memory_alloc::framebuffer[core].start;
while (spg_status::vsync(holly.SPG_STATUS));
}
if (core == 0) {
if (done == true)
break;
done = runner_tick(&runner_state);
}
// core = -2 ; core = 1 ; core = 0
@ -264,7 +226,6 @@ int main()
framebuffer_width);
}
// core = -1 ; core = 1 ; core = 0
// ta = 0 ; ta = 0 ; ta = 1
ta_polygon_converter_init2(texture_memory_alloc::isp_tsp_parameters[ta].start,
@ -278,6 +239,139 @@ int main()
transfer_scene(font, glyphs);
}
//while (1);
void vbr600()
{
/*
serial::string("vbr600\n");
serial::string("expevt ");
serial::integer<uint16_t>(sh7091.CCN.EXPEVT);
serial::string("intevt ");
serial::integer<uint16_t>(sh7091.CCN.INTEVT);
serial::string("tra ");
serial::integer<uint16_t>(sh7091.CCN.TRA);
serial::string("istnrm ");
serial::integer<uint32_t>(system.ISTNRM & system.IML6NRM);
*/
// reset v_blank_in interrupt
system.ISTNRM = istnrm::v_blank_in_interrupt;
render();
return;
}
void vbr400()
{
serial::string("vbr400\n");
while (1);
}
void vbr100()
{
serial::string("vbr100\n");
while (1);
}
void interrupt_init()
{
sh7091.CCN.INTEVT = 0;
sh7091.CCN.EXPEVT = 0;
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;
// enable v-blank-in interrupt at IRL level 6
system.IML6NRM = istnrm::v_blank_in_interrupt;
const uint32_t vbr = reinterpret_cast<uint32_t>(&__vbr_link_start) - 0x100;
// set VBR
asm volatile ("ldc %0,vbr"
:
: "r" (vbr));
uint32_t sr;
// read current SR
asm volatile ("stc sr,%0"
: "=r" (sr));
// unset interrupt block bit
sr &= ~sh::sr::bl;
// enable interrupt level 6
sr &= ~sh::sr::imask(15);
sr |= sh::sr::imask(0b0100);
// set new SR
asm volatile ("ldc %0,sr"
:
: "r" (sr));
}
int main()
{
serial::init(0);
serial::string("framebuffer: ");
serial::integer<uint32_t>((uint32_t)&texture_memory32[texture_memory_alloc::framebuffer[0].start / 4]);
holly.SOFTRESET = softreset::pipeline_soft_reset
| softreset::ta_soft_reset;
holly.SOFTRESET = 0;
core_init();
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[0].start,
texture_memory_alloc::object_list[0].start);
region_array_multipass(tile_width,
tile_height,
opb_size,
render_passes,
texture_memory_alloc::region_array[1].start,
texture_memory_alloc::object_list[1].start);
background_parameter2(texture_memory_alloc::background[0].start,
0xff220033);
background_parameter2(texture_memory_alloc::background[1].start,
0xff220033);
font = reinterpret_cast<const struct font *>(&_binary_font_dejavusansmono_dejavusansmono_data_start);
glyphs = reinterpret_cast<const struct glyph *>(&font[1]);
auto texture = reinterpret_cast<const uint8_t *>(&glyphs[font->glyph_count]);
copy_font(texture, font->max_z_curve_ix);
palette_data<256>();
struct runner_state runner_state = {0};
video_output::set_mode_vga();
ta = -1;
core = -2;
interrupt_init();
uint32_t done_frame = 0;
bool done = false;
while (true) {
if (!done && runner_tick(&runner_state)) {
done = true;
done_frame = frame;
}
if (done && (frame == done_frame + 2))
break;
}
serial::string("return\n");
}