serial_transfer: re-enable maple_handle

This commit is contained in:
Zack Buhman 2025-12-13 17:35:50 -06:00
parent d222a2dc9f
commit 6dd9391f21
3 changed files with 92 additions and 27 deletions

View File

@ -4,6 +4,7 @@
#include "sh7091/sh7091.hpp" #include "sh7091/sh7091.hpp"
#include "sh7091/sh7091_bits.hpp" #include "sh7091/sh7091_bits.hpp"
#include "sh7091/serial.hpp" #include "sh7091/serial.hpp"
#include "sh7091/vbr.hpp"
#include "maple/maple.hpp" #include "maple/maple.hpp"
#include "maple/maple_bus_commands.hpp" #include "maple/maple_bus_commands.hpp"
@ -82,8 +83,6 @@ void recv_extension_device_status(struct serial_load::maple_poll_state &state)
using response_type = maple::host_response<maple::device_status::data_fields>; using response_type = maple::host_response<maple::device_status::data_fields>;
auto host_response = reinterpret_cast<response_type *>(recv_buf); auto host_response = reinterpret_cast<response_type *>(recv_buf);
uint32_t last_send_offset = 0;
int response_index = 0; int response_index = 0;
for (int port = 0; port < 4; port++) { for (int port = 0; port < 4; port++) {
uint32_t bit = ap::lm_bus::_0; uint32_t bit = ap::lm_bus::_0;
@ -108,7 +107,6 @@ void recv_extension_device_status(struct serial_load::maple_poll_state &state)
state.port[port].lm[i].device_id.fd[2] = std::byteswap(data_fields.device_id.fd[2]); state.port[port].lm[i].device_id.fd[2] = std::byteswap(data_fields.device_id.fd[2]);
if (state.port[port].lm[i].device_id.ft & function_type::bw_lcd) { if (state.port[port].lm[i].device_id.ft & function_type::bw_lcd) {
last_send_offset = writer.send_offset;
send_vmu_framebuffer(writer, port, bit); send_vmu_framebuffer(writer, port, bit);
} }
} }
@ -116,11 +114,7 @@ void recv_extension_device_status(struct serial_load::maple_poll_state &state)
} }
} }
// rewrite the end flag of the last request writer.set_end_flag();
using command_type = maple::host_command<uint8_t[0]>;
auto host_command = reinterpret_cast<command_type *>(&send_buf[last_send_offset / 4]);
host_command->host_instruction |= host_instruction::end_flag;
maple::dma_start(send_buf, writer.send_offset, maple::dma_start(send_buf, writer.send_offset,
recv_buf, writer.recv_offset); recv_buf, writer.recv_offset);
} }
@ -139,12 +133,11 @@ void send_extension_device_request(maple::host_command_writer<>& writer, uint8_t
} }
typedef void (* func_t)(maple::host_command_writer<>& writer, uint8_t port, uint8_t lm); typedef void (* func_t)(maple::host_command_writer<>& writer, uint8_t port, uint8_t lm);
void do_lm_requests(maple::host_command_writer<>& writer, uint8_t port, uint8_t lm, uint32_t& last_send_offset, func_t func) void do_lm_requests(maple::host_command_writer<>& writer, uint8_t port, uint8_t lm, func_t func)
{ {
uint32_t bit = ap::lm_bus::_0; uint32_t bit = ap::lm_bus::_0;
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
if (lm & bit) { if (lm & bit) {
last_send_offset = writer.send_offset;
func(writer, port, bit); func(writer, port, bit);
} }
bit <<= 1; bit <<= 1;
@ -157,7 +150,6 @@ void recv_device_status(struct serial_load::maple_poll_state &state)
using response_type = maple::host_response<maple::device_status::data_fields>; using response_type = maple::host_response<maple::device_status::data_fields>;
auto host_response = reinterpret_cast<response_type *>(recv_buf); auto host_response = reinterpret_cast<response_type *>(recv_buf);
uint32_t last_send_offset = 0;
for (int port = 0; port < 4; port++) { for (int port = 0; port < 4; port++) {
auto& bus_data = host_response[port].bus_data; auto& bus_data = host_response[port].bus_data;
@ -172,15 +164,11 @@ void recv_device_status(struct serial_load::maple_poll_state &state)
state.port[port].device_id.fd[0] = std::byteswap(data_fields.device_id.fd[0]); state.port[port].device_id.fd[0] = std::byteswap(data_fields.device_id.fd[0]);
state.port[port].device_id.fd[1] = std::byteswap(data_fields.device_id.fd[1]); state.port[port].device_id.fd[1] = std::byteswap(data_fields.device_id.fd[1]);
state.port[port].device_id.fd[2] = std::byteswap(data_fields.device_id.fd[2]); state.port[port].device_id.fd[2] = std::byteswap(data_fields.device_id.fd[2]);
do_lm_requests(writer, port, lm, last_send_offset, &send_extension_device_request); do_lm_requests(writer, port, lm, &send_extension_device_request);
} }
} }
// rewrite the end flag of the last request writer.set_end_flag();
using command_type = maple::host_command<uint8_t[0]>;
auto host_command = reinterpret_cast<command_type *>(&send_buf[last_send_offset / 4]);
host_command->host_instruction |= host_instruction::end_flag;
maple::dma_start(send_buf, writer.send_offset, maple::dma_start(send_buf, writer.send_offset,
recv_buf, writer.recv_offset); recv_buf, writer.recv_offset);
} }
@ -200,8 +188,8 @@ void send_device_request()
void send_raw(struct serial_load::maple_poll_state& state) void send_raw(struct serial_load::maple_poll_state& state)
{ {
maple::dma_start(reinterpret_cast<uint8_t *>(&__send_buf), state.send_length, maple::dma_start(maple_send_buf, state.send_length,
reinterpret_cast<uint8_t *>(&__recv_buf), state.recv_length); maple_recv_buf, state.recv_length);
} }
void handle_maple(struct serial_load::maple_poll_state& state) void handle_maple(struct serial_load::maple_poll_state& state)
@ -394,6 +382,81 @@ void render(maple::display::font_renderer& renderer0,
render_glyphs(renderer1, textbuffer[1]); render_glyphs(renderer1, textbuffer[1]);
} }
void vbr100()
{
serial::string("vbr100\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);
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 vbr400()
{
serial::string("vbr400");
while (1);
}
void vbr600()
{
serial::string("vbr600");
while (1);
}
void interrupt_setup()
{
uint32_t vbr = reinterpret_cast<uint32_t>(&__vbr_link_start) - 0x100;
uint32_t zero = 0;
asm volatile ("ldc %0,spc"
:
: "r" (zero));
asm volatile ("ldc %0,ssr"
:
: "r" (zero));
asm volatile ("ldc %0,vbr"
:
: "r" (vbr));
// sr
uint32_t sr;
asm volatile ("stc sr,%0"
: "=r" (sr));
serial::string("sr ");
serial::integer<uint32_t>(sr);
sr &= ~sh::sr::bl; // BL
sr |= sh::sr::imask(15); // imask
serial::string("sr ");
serial::integer<uint32_t>(sr);
asm volatile ("ldc %0,sr"
:
: "r" (sr));
serial::string("interrupt_setup\n");
}
void main() __attribute__((section(".text.main"))); void main() __attribute__((section(".text.main")));
void main() void main()
@ -405,13 +468,11 @@ void main()
constexpr uint32_t serial_speed = 0; constexpr uint32_t serial_speed = 0;
serial_load::init(serial_speed); serial_load::init(serial_speed);
/*
const uint8_t * font = reinterpret_cast<const uint8_t *>(&_binary_font_portfolio_6x8); const uint8_t * font = reinterpret_cast<const uint8_t *>(&_binary_font_portfolio_6x8);
auto renderer0 = maple::display::font_renderer(font); auto renderer0 = maple::display::font_renderer(font);
framebuffer[0] = renderer0.fb; framebuffer[0] = renderer0.fb;
auto renderer1 = maple::display::font_renderer(font); auto renderer1 = maple::display::font_renderer(font);
framebuffer[1] = renderer1.fb; framebuffer[1] = renderer1.fb;
*/
// reset serial status // reset serial status
sh7091.SCIF.SCFSR2 = 0; sh7091.SCIF.SCFSR2 = 0;
@ -431,6 +492,7 @@ void main()
serial_load::recv(state, m[i]); serial_load::recv(state, m[i]);
} }
*/ */
interrupt_setup();
while (1) { while (1) {
using namespace scif; using namespace scif;
@ -470,6 +532,6 @@ void main()
//render(renderer0, renderer1); //render(renderer0, renderer1);
//poll_state.want_start = 1; //poll_state.want_start = 1;
//handle_maple(poll_state); handle_maple(poll_state);
} }
} }

View File

@ -11,6 +11,9 @@
#include "align.hpp" #include "align.hpp"
#include "memory.hpp" #include "memory.hpp"
uint8_t maple_send_buf[1024];
uint8_t maple_recv_buf[1024];
namespace serial_load { namespace serial_load {
struct state state; struct state state;
@ -38,7 +41,7 @@ void jump_to_func(const uint32_t addr)
: :
: "r"(addr) /* input */ : "r"(addr) /* input */
/* clobbered register */ /* clobbered register */
: "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","r13","macl","mach","gbr","pr" : "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","macl","mach","gbr","pr"
); );
// restore our stack // restore our stack
} }
@ -63,7 +66,7 @@ static void poststart_read()
static void prestart_maple_raw__command() static void prestart_maple_raw__command()
{ {
uint32_t dest = reinterpret_cast<uint32_t>(&__send_buf); uint32_t dest = reinterpret_cast<uint32_t>(&maple_send_buf[0]);
uint32_t size = state.buf.arg[0]; uint32_t size = state.buf.arg[0];
serial::recv_dma(dest - 1, size + 1); serial::recv_dma(dest - 1, size + 1);
state.reply_crc.value = 0xffffffff; state.reply_crc.value = 0xffffffff;
@ -72,7 +75,7 @@ static void prestart_maple_raw__command()
static void prestart_maple_raw__response() static void prestart_maple_raw__response()
{ {
uint32_t src = reinterpret_cast<uint32_t>(&__recv_buf); uint32_t src = reinterpret_cast<uint32_t>(&maple_recv_buf[0]);
uint32_t size = state.buf.arg[1]; uint32_t size = state.buf.arg[1];
serial::send_dma(src, size); serial::send_dma(src, size);
state.reply_crc.value = 0xffffffff; state.reply_crc.value = 0xffffffff;

View File

@ -79,5 +79,5 @@ struct maple_poll_state {
} }
extern "C" uint32_t __send_buf __asm("__send_buf"); extern uint8_t maple_send_buf[1024] __attribute__((aligned(32)));
extern "C" uint32_t __recv_buf __asm("__recv_buf"); extern uint8_t maple_recv_buf[1024] __attribute__((aligned(32)));