maple: slightly refactor maple command initialization
This adopts a "writer" concept, vaguely inspired by the ta parameter writer. This might turn out to be not a great idea if the response/offsets for heterogenous commands are too inconvenient to keep track of. This breaks every example that uses maple--only example/maple_controller is updated to use the new interface.
This commit is contained in:
parent
b5ac43c109
commit
9801557535
3
base.mk
3
base.mk
@ -2,10 +2,11 @@ DEBUG = -g -gdwarf-4
|
||||
|
||||
AFLAGS += --fatal-warnings
|
||||
|
||||
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib
|
||||
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib -fno-builtin -finline-stringops
|
||||
CFLAGS += -Wall -Werror -Wfatal-errors
|
||||
CFLAGS += -Wno-array-bounds
|
||||
#CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds=
|
||||
CFLAGS += -Wno-error=maybe-uninitialized
|
||||
|
||||
CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics
|
||||
|
||||
|
@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
DIR := $(dir $(MAKEFILE_PATH))
|
||||
|
||||
LIB ?= .
|
||||
OPT ?= -O2
|
||||
OPT ?= -Os
|
||||
GENERATED ?=
|
||||
|
||||
AARCH = --isa=sh4 --little
|
||||
|
@ -46,7 +46,7 @@ void do_get_condition(uint32_t * command_buf,
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
|
@ -47,9 +47,8 @@ void do_get_condition(uint32_t * command_buf,
|
||||
.function_type = std::byteswap(function_type::controller)
|
||||
};
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf, data_fields);
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
|
@ -51,14 +51,14 @@ void do_get_condition(uint32_t * command_buf,
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
|
||||
using command_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
for (uint8_t port = 0; port < 4; port++) {
|
||||
auto response = reinterpret_cast<command_response_type *>(receive_buf);
|
||||
auto response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
auto& bus_data = response[port].bus_data;
|
||||
if (bus_data.command_code != response_type::command_code) {
|
||||
return;
|
||||
|
@ -46,7 +46,7 @@ void do_get_condition(uint32_t * command_buf,
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
|
@ -5,65 +5,39 @@
|
||||
#include "holly/core_bits.hpp"
|
||||
#include "holly/holly.hpp"
|
||||
#include "maple/maple.hpp"
|
||||
#include "maple/maple_impl.hpp"
|
||||
#include "maple/maple_port.hpp"
|
||||
#include "maple/maple_bus_bits.hpp"
|
||||
#include "maple/maple_bus_commands.hpp"
|
||||
#include "maple/maple_bus_ft0.hpp"
|
||||
#include "maple/maple_host_command_writer.hpp"
|
||||
#include "sh7091/serial.hpp"
|
||||
|
||||
uint32_t _command_buf[(1024 + 32) / 4];
|
||||
uint32_t _receive_buf[(1024 + 32) / 4];
|
||||
#include "systembus.hpp"
|
||||
|
||||
static uint32_t * command_buf;
|
||||
static uint32_t * receive_buf;
|
||||
|
||||
void do_get_condition(uint32_t port)
|
||||
void do_get_condition()
|
||||
{
|
||||
uint32_t destination_port;
|
||||
uint32_t destination_ap;
|
||||
uint32_t send_buf[1024] __attribute__((aligned(32)));
|
||||
uint32_t recv_buf[1024] __attribute__((aligned(32)));
|
||||
|
||||
switch (port) {
|
||||
case 0:
|
||||
destination_port = host_instruction::port_select::a;
|
||||
destination_ap = ap::de::device | ap::port_select::a;
|
||||
break;
|
||||
case 1:
|
||||
destination_port = host_instruction::port_select::b;
|
||||
destination_ap = ap::de::device | ap::port_select::b;
|
||||
break;
|
||||
case 2:
|
||||
destination_port = host_instruction::port_select::c;
|
||||
destination_ap = ap::de::device | ap::port_select::c;
|
||||
break;
|
||||
case 3:
|
||||
destination_port = host_instruction::port_select::d;
|
||||
destination_ap = ap::de::device | ap::port_select::d;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t command_size = maple::init_get_condition(command_buf, receive_buf,
|
||||
destination_port,
|
||||
destination_ap,
|
||||
std::byteswap(function_type::controller));
|
||||
auto writer = maple::host_command_writer(send_buf, recv_buf);
|
||||
|
||||
using command_type = get_condition;
|
||||
using response_type = data_transfer<ft0::data_transfer::data_format>;
|
||||
using command_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<command_response_type *>(receive_buf);
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
auto [host_command, host_response]
|
||||
= writer.append_command_all_ports<command_type, response_type>();
|
||||
|
||||
auto& bus_data = host_response->bus_data;
|
||||
if (bus_data.command_code != response_type::command_code) {
|
||||
return;
|
||||
}
|
||||
maple::dma_start(send_buf, writer.send_offset,
|
||||
recv_buf, writer.recv_offset);
|
||||
|
||||
for (uint8_t port = 0; port < 4; port++) {
|
||||
auto& bus_data = host_response[port].bus_data;
|
||||
auto& data_fields = bus_data.data_fields;
|
||||
if ((data_fields.function_type & std::byteswap(function_type::controller)) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bus_data.command_code != response_type::command_code) {
|
||||
//serial::string("device did not reply to get_condition: ");
|
||||
//serial::integer<uint8_t>(port);
|
||||
} else if ((data_fields.function_type & std::byteswap(function_type::controller)) != 0) {
|
||||
bool a = ft0::data_transfer::digital_button::a(data_fields.data.digital_button);
|
||||
if (a == 0) {
|
||||
serial::string("port ");
|
||||
@ -72,47 +46,121 @@ void do_get_condition(uint32_t port)
|
||||
serial::integer<uint8_t>(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void do_device_request()
|
||||
void do_lm_request(uint8_t port, uint8_t lm)
|
||||
{
|
||||
uint32_t send_buf[1024] __attribute__((aligned(32)));
|
||||
uint32_t recv_buf[1024] __attribute__((aligned(32)));
|
||||
|
||||
auto writer = maple::host_command_writer(send_buf, recv_buf);
|
||||
|
||||
uint32_t host_port_select = host_instruction_port_select(port);
|
||||
uint32_t destination_ap = ap_port_select(port) | ap::de::expansion_device | lm;
|
||||
|
||||
using command_type = device_request;
|
||||
using response_type = device_status;
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
auto [host_command, host_response]
|
||||
= writer.append_command<command_type, response_type>(host_port_select,
|
||||
destination_ap,
|
||||
true); // end_flag
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
maple::dma_start(send_buf, writer.send_offset,
|
||||
recv_buf, writer.recv_offset);
|
||||
|
||||
auto& bus_data = host_response->bus_data;
|
||||
auto& data_fields = bus_data.data_fields;
|
||||
if (bus_data.command_code != device_status::command_code) {
|
||||
serial::string("lm did not reply: ");
|
||||
serial::integer<uint8_t>(port, ' ');
|
||||
serial::integer<uint8_t>(lm);
|
||||
} else {
|
||||
serial::string(" lm: ");
|
||||
serial::integer<uint8_t>(lm);
|
||||
serial::string(" ft: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.ft));
|
||||
serial::string(" fd[0]: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.fd[0]));
|
||||
serial::string(" fd[1]: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.fd[1]));
|
||||
serial::string(" fd[2]: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.fd[2]));
|
||||
serial::string(" source_ap.lm_bus: ");
|
||||
serial::integer<uint8_t>(bus_data.source_ap & ap::lm_bus::bit_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void do_lm_requests(uint8_t port, uint8_t lm)
|
||||
{
|
||||
if (lm & ap::lm_bus::_0)
|
||||
do_lm_request(port, lm & ap::lm_bus::_0);
|
||||
if (lm & ap::lm_bus::_1)
|
||||
do_lm_request(port, lm & ap::lm_bus::_1);
|
||||
if (lm & ap::lm_bus::_2)
|
||||
do_lm_request(port, lm & ap::lm_bus::_2);
|
||||
if (lm & ap::lm_bus::_3)
|
||||
do_lm_request(port, lm & ap::lm_bus::_3);
|
||||
if (lm & ap::lm_bus::_4)
|
||||
do_lm_request(port, lm & ap::lm_bus::_4);
|
||||
}
|
||||
|
||||
void do_device_request()
|
||||
{
|
||||
uint32_t send_buf[1024] __attribute__((aligned(32)));
|
||||
uint32_t recv_buf[1024] __attribute__((aligned(32)));
|
||||
|
||||
auto writer = maple::host_command_writer(send_buf, recv_buf);
|
||||
|
||||
using command_type = device_request;
|
||||
using response_type = device_status;
|
||||
|
||||
auto [host_command, host_response]
|
||||
= writer.append_command_all_ports<command_type, response_type>();
|
||||
|
||||
maple::dma_start(send_buf, writer.send_offset,
|
||||
recv_buf, writer.recv_offset);
|
||||
|
||||
for (uint8_t port = 0; port < 4; port++) {
|
||||
auto& bus_data = host_response[port].bus_data;
|
||||
auto& data_fields = host_response[port].bus_data.data_fields;
|
||||
auto& data_fields = bus_data.data_fields;
|
||||
if (bus_data.command_code != device_status::command_code) {
|
||||
// the controller is disconnected
|
||||
serial::string("port: ");
|
||||
serial::integer<uint8_t>(port);
|
||||
serial::string(" disconnected\n");
|
||||
} else {
|
||||
if ((data_fields.device_id.ft & std::byteswap(function_type::controller)) != 0) {
|
||||
//serial::string("is controller: ");
|
||||
//serial::integer<uint8_t>(port);
|
||||
do_get_condition(port);
|
||||
}
|
||||
serial::string("port: ");
|
||||
serial::integer<uint8_t>(port);
|
||||
serial::string(" ft: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.ft));
|
||||
serial::string(" fd[0]: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.fd[0]));
|
||||
serial::string(" fd[1]: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.fd[1]));
|
||||
serial::string(" fd[2]: ");
|
||||
serial::integer<uint32_t>(std::byteswap(data_fields.device_id.fd[2]));
|
||||
serial::string(" source_ap.lm_bus: ");
|
||||
serial::integer<uint8_t>(bus_data.source_ap & ap::lm_bus::bit_mask);
|
||||
|
||||
do_lm_requests(port,
|
||||
bus_data.source_ap & ap::lm_bus::bit_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
command_buf = align_32byte(_command_buf);
|
||||
command_buf = reinterpret_cast<uint32_t *>(reinterpret_cast<uint32_t>(command_buf) | 0xa000'0000);
|
||||
receive_buf = align_32byte(_receive_buf);
|
||||
|
||||
// flycast needs this in HLE mode, or else it won't start the vcount
|
||||
// counter.
|
||||
video_output::set_mode_vga();
|
||||
|
||||
do_device_request();
|
||||
|
||||
while (1) {
|
||||
while (!spg_status::vsync(holly.SPG_STATUS));
|
||||
while (spg_status::vsync(holly.SPG_STATUS));
|
||||
do_device_request();
|
||||
|
||||
do_get_condition();
|
||||
};
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ void main()
|
||||
|
||||
uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf);
|
||||
|
||||
constexpr uint32_t host_response_size = (sizeof (maple::command_response<response_type::data_fields>));
|
||||
constexpr uint32_t host_response_size = (sizeof (maple::host_response<response_type::data_fields>));
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, host_response_size);
|
||||
|
@ -47,16 +47,17 @@ void do_lm_request(uint8_t port, uint8_t lm)
|
||||
maple::init_host_command(command_buf, receive_buf,
|
||||
destination_port,
|
||||
destination_ap, get_media_info::command_code, (sizeof (struct get_media_info::data_fields)),
|
||||
true);
|
||||
true); // end_flag
|
||||
|
||||
using host_command_type = struct maple::host_command<get_media_info::data_fields>;
|
||||
using command_type = get_media_info;
|
||||
using host_command_type = struct maple::host_command<command_type::data_fields>;
|
||||
auto host_command = reinterpret_cast<host_command_type *>(command_buf);
|
||||
auto& fields = host_command->bus_data.data_fields;
|
||||
fields.function_type = std::byteswap(function_type::vibration);
|
||||
fields.pt = std::byteswap(1 << 24);
|
||||
|
||||
using response_type = data_transfer<ft8::data_transfer::data_format>;
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
|
||||
serial::string("dma start\n");
|
||||
@ -118,7 +119,7 @@ void do_lm_request(uint8_t port, uint8_t lm)
|
||||
fields.write_in_data.freq = 0x27;
|
||||
fields.write_in_data.inc = 0x00;
|
||||
|
||||
using host_response_type = struct maple::command_response<device_reply::data_fields>;
|
||||
using host_response_type = struct maple::host_response<device_reply::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
maple::dma_start(command_buf, maple::sizeof_command(host_command),
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
@ -154,11 +155,11 @@ void do_device_request()
|
||||
{
|
||||
using command_type = device_request;
|
||||
using response_type = device_status;
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf);
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
receive_buf, maple::sizeof_command(host_response) * 4);
|
||||
|
||||
for (uint8_t port = 0; port < 4; port++) {
|
||||
auto& bus_data = host_response[port].bus_data;
|
||||
@ -193,5 +194,6 @@ void main()
|
||||
while (spg_status::vsync(holly.SPG_STATUS));
|
||||
}
|
||||
do_device_request();
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ void main()
|
||||
uint32_t * receive_buf = align_32byte(_receive_buf);
|
||||
|
||||
const uint32_t command_size = maple::init_block_write(command_buf, receive_buf,
|
||||
host_instruction::port_select::a,
|
||||
ap::de::expansion_device | ap::port_select::a | ap::lm_bus::_0,
|
||||
host_instruction::port_select::b,
|
||||
ap::de::expansion_device | ap::port_select::b | ap::lm_bus::_0,
|
||||
wink_buf,
|
||||
wink_size);
|
||||
using response_type = device_reply;
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
maple::dma_start(command_buf, command_size,
|
||||
receive_buf, maple::sizeof_command(host_response));
|
||||
@ -56,6 +56,4 @@ void main()
|
||||
serial::integer<uint8_t>(host_response->bus_data.destination_ap);
|
||||
serial::integer<uint8_t>(host_response->bus_data.source_ap);
|
||||
serial::integer<uint8_t>(host_response->bus_data.data_size);
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ void do_get_condition(uint32_t * command_buf,
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
|
@ -244,7 +244,7 @@ void do_get_condition(uint32_t * command_buf,
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf,
|
||||
data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
namespace maple {
|
||||
|
||||
/*
|
||||
void init_host_command(uint32_t * command_buf, uint32_t * receive_buf,
|
||||
uint32_t destination_port,
|
||||
uint8_t destination_ap, uint8_t command_code, uint8_t data_size,
|
||||
@ -104,6 +105,7 @@ uint32_t init_block_write(uint32_t * command_buf, uint32_t * receive_buf,
|
||||
return (reinterpret_cast<uint32_t>(&host_command[1]) - reinterpret_cast<uint32_t>(&host_command[0]))
|
||||
+ data_size;
|
||||
}
|
||||
*/
|
||||
|
||||
static inline void _dma_start(const uint32_t * command_buf)
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ static_assert((sizeof (host_command<uint8_t[0]>)) == 12);
|
||||
static_assert((sizeof (host_command<uint8_t[0]>[4])) == 48);
|
||||
|
||||
template <typename T>
|
||||
struct command_response {
|
||||
struct host_response {
|
||||
struct bus_data {
|
||||
uint8_t command_code;
|
||||
uint8_t destination_ap;
|
||||
@ -32,7 +32,7 @@ struct command_response {
|
||||
} bus_data;
|
||||
uint8_t _pad[align_32byte((sizeof (bus_data))) - (sizeof (bus_data))];
|
||||
};
|
||||
static_assert((sizeof (command_response<uint8_t[0]>)) == align_32byte((sizeof (command_response<uint8_t[0]>))));
|
||||
static_assert((sizeof (host_response<uint8_t[0]>)) == align_32byte((sizeof (host_response<uint8_t[0]>))));
|
||||
|
||||
void init_host_command(uint32_t * buf, uint32_t * receive_buf,
|
||||
uint32_t destination_port,
|
||||
|
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ft6 {
|
||||
namespace scan_codes {
|
||||
namespace scan_code {
|
||||
constexpr uint32_t no_operation = 0x0;
|
||||
constexpr uint32_t rollover_error = 0x1;
|
||||
constexpr uint32_t post_fail = 0x2;
|
||||
@ -52,7 +54,7 @@ namespace ft6 {
|
||||
constexpr uint32_t bracketleft_braceleft = 0x2f;
|
||||
constexpr uint32_t bracketright_braceright = 0x30;
|
||||
constexpr uint32_t backslash_bar = 0x31;
|
||||
constexpr uint32_t _unknown_ = 0x32;
|
||||
constexpr uint32_t iso_numbersign_tilde = 0x32;
|
||||
constexpr uint32_t semicolon_colon = 0x33;
|
||||
constexpr uint32_t apostrophe_quotedbl = 0x34;
|
||||
constexpr uint32_t grave_asciitilde = 0x35;
|
||||
@ -87,4 +89,69 @@ namespace ft6 {
|
||||
constexpr uint32_t up_arrow = 0x52;
|
||||
}
|
||||
}
|
||||
namespace ft6 {
|
||||
namespace scan_code {
|
||||
constexpr uint32_t last_printable = 0x38;
|
||||
|
||||
const uint8_t code_point[last_printable + 1][2] = {
|
||||
[scan_code::no_operation] = { 0, 0 },
|
||||
[scan_code::rollover_error] = { 0, 0 },
|
||||
[scan_code::post_fail] = { 0, 0 },
|
||||
[scan_code::undefined_error] = { 0, 0 },
|
||||
[scan_code::a_A] = { 'a', 'A' },
|
||||
[scan_code::b_B] = { 'b', 'B' },
|
||||
[scan_code::c_C] = { 'c', 'C' },
|
||||
[scan_code::d_D] = { 'd', 'D' },
|
||||
[scan_code::e_E] = { 'e', 'E' },
|
||||
[scan_code::f_F] = { 'f', 'F' },
|
||||
[scan_code::g_G] = { 'g', 'G' },
|
||||
[scan_code::h_H] = { 'h', 'H' },
|
||||
[scan_code::i_I] = { 'i', 'I' },
|
||||
[scan_code::j_J] = { 'j', 'J' },
|
||||
[scan_code::k_K] = { 'k', 'K' },
|
||||
[scan_code::l_L] = { 'l', 'L' },
|
||||
[scan_code::m_M] = { 'm', 'M' },
|
||||
[scan_code::n_N] = { 'n', 'N' },
|
||||
[scan_code::o_O] = { 'o', 'O' },
|
||||
[scan_code::p_P] = { 'p', 'P' },
|
||||
[scan_code::q_Q] = { 'q', 'Q' },
|
||||
[scan_code::r_R] = { 'r', 'R' },
|
||||
[scan_code::s_S] = { 's', 'S' },
|
||||
[scan_code::t_T] = { 't', 'T' },
|
||||
[scan_code::u_U] = { 'u', 'U' },
|
||||
[scan_code::v_V] = { 'v', 'V' },
|
||||
[scan_code::w_W] = { 'w', 'W' },
|
||||
[scan_code::x_X] = { 'x', 'X' },
|
||||
[scan_code::y_Y] = { 'y', 'Y' },
|
||||
[scan_code::z_Z] = { 'z', 'Z' },
|
||||
[scan_code::_1_exclam] = { '1', '!' },
|
||||
[scan_code::_2_at] = { '2', '@' },
|
||||
[scan_code::_3_numbersign] = { '3', '#' },
|
||||
[scan_code::_4_dollar] = { '4', '$' },
|
||||
[scan_code::_5_percent] = { '5', '%' },
|
||||
[scan_code::_6_asciicircum] = { '6', '^' },
|
||||
[scan_code::_7_ampersand] = { '7', '&' },
|
||||
[scan_code::_8_asterisk] = { '8', '*' },
|
||||
[scan_code::_9_parenleft] = { '9', '(' },
|
||||
[scan_code::_0_parenright] = { '0', ')' },
|
||||
[scan_code::_return] = { 0, 0 },
|
||||
[scan_code::esc] = { 0, 0 },
|
||||
[scan_code::backspace] = { 0, 0 },
|
||||
[scan_code::tab] = { 0, 0 },
|
||||
[scan_code::spacebar] = { 0, 0 },
|
||||
[scan_code::minus_underscore] = { '-', '_' },
|
||||
[scan_code::equal_plus] = { '=', '+' },
|
||||
[scan_code::bracketleft_braceleft] = { '[', '{' },
|
||||
[scan_code::bracketright_braceright] = { ']', '}' },
|
||||
[scan_code::backslash_bar] = { '\\', '|' },
|
||||
[scan_code::iso_numbersign_tilde] = { '#', '~' },
|
||||
[scan_code::semicolon_colon] = { ';', ':' },
|
||||
[scan_code::apostrophe_quotedbl] = { '\'', '"' },
|
||||
[scan_code::grave_asciitilde] = { '\'', '~' },
|
||||
[scan_code::comma_less] = { ',', '<' },
|
||||
[scan_code::period_greater] = { '.', '>' },
|
||||
[scan_code::slash_question] = { '/', '?' },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
72
maple/maple_host_command_writer.hpp
Normal file
72
maple/maple_host_command_writer.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
|
||||
#include "maple/maple.hpp"
|
||||
#include "maple/maple_bus_commands.hpp"
|
||||
#include "maple/maple_bus_bits.hpp"
|
||||
|
||||
namespace maple {
|
||||
|
||||
struct host_command_writer {
|
||||
uint32_t * const send_buf;
|
||||
uint32_t * const recv_buf;
|
||||
uint32_t send_offset;
|
||||
uint32_t recv_offset;
|
||||
|
||||
constexpr host_command_writer(uint32_t * const send_buf,
|
||||
uint32_t * const recv_buf)
|
||||
: send_buf(send_buf), recv_buf(recv_buf), send_offset(0), recv_offset(0)
|
||||
{ }
|
||||
|
||||
template <typename C, typename R, int data_fields_trailing = 0>
|
||||
constexpr inline std::tuple<maple::host_command<typename C::data_fields> *,
|
||||
maple::host_response<typename R::data_fields> *>
|
||||
append_command(uint32_t host_port_select,
|
||||
uint32_t destination_ap,
|
||||
bool end_flag)
|
||||
{
|
||||
using command_type = maple::host_command<typename C::data_fields>;
|
||||
using response_type = maple::host_response<typename R::data_fields>;
|
||||
constexpr uint32_t data_size = (sizeof (typename C::data_fields)) + data_fields_trailing;
|
||||
|
||||
static_assert((sizeof (command_type)) % 4 == 0);
|
||||
static_assert((sizeof (response_type)) % 4 == 0);
|
||||
static_assert(data_size % 4 == 0);
|
||||
|
||||
auto host_command = reinterpret_cast<command_type *>(&send_buf[send_offset / 4]);
|
||||
auto host_response = reinterpret_cast<response_type *>(&recv_buf[recv_offset / 4]);
|
||||
|
||||
host_command->host_instruction = (end_flag ? host_instruction::end_flag : 0)
|
||||
| (host_port_select & host_instruction::port_select::bit_mask)
|
||||
| host_instruction::transfer_length(data_size / 4);
|
||||
|
||||
host_command->receive_data_storage_address = receive_data_storage_address::address(reinterpret_cast<uint32_t>(host_response));
|
||||
|
||||
host_command->bus_data.command_code = C::command_code;
|
||||
host_command->bus_data.destination_ap = destination_ap;
|
||||
|
||||
host_command->bus_data.source_ap = destination_ap & ap::port_select::bit_mask;
|
||||
host_command->bus_data.data_size = data_size / 4;
|
||||
|
||||
send_offset += (sizeof (command_type)) + data_fields_trailing;
|
||||
recv_offset += (sizeof (response_type));
|
||||
|
||||
return {host_command, host_response};
|
||||
}
|
||||
|
||||
template <typename C, typename R>
|
||||
constexpr inline std::tuple<maple::host_command<typename C::data_fields> *,
|
||||
maple::host_response<typename R::data_fields> *>
|
||||
append_command_all_ports()
|
||||
{
|
||||
auto ret = append_command<C, R, 0>(host_instruction::port_select::a, ap::de::device | ap::port_select::a, false);
|
||||
append_command<C, R, 0>(host_instruction::port_select::b, ap::de::device | ap::port_select::b, false);
|
||||
append_command<C, R, 0>(host_instruction::port_select::c, ap::de::device | ap::port_select::c, false);
|
||||
append_command<C, R, 0>(host_instruction::port_select::d, ap::de::device | ap::port_select::d, true);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "maple/maple.hpp"
|
||||
#include "maple/maple_bus_commands.hpp"
|
||||
#include "maple/maple_bus_bits.hpp"
|
||||
|
||||
namespace maple {
|
||||
|
||||
template <typename C, typename R>
|
||||
uint32_t init_host_command_all_ports(uint32_t * command_buf, uint32_t * receive_buf,
|
||||
const typename C::data_fields& data_fields)
|
||||
{
|
||||
using command_type = maple::host_command<typename C::data_fields>;
|
||||
using response_type = maple::command_response<typename R::data_fields>;
|
||||
|
||||
auto host_command = reinterpret_cast<command_type *>(command_buf);
|
||||
auto response_command = reinterpret_cast<response_type *>(receive_buf);
|
||||
|
||||
init_host_command((uint32_t*)&host_command[0], (uint32_t*)&response_command[0],
|
||||
host_instruction::port_select::a, // destination_port
|
||||
ap::de::device | ap::port_select::a, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
host_command[0].bus_data.data_fields = data_fields;
|
||||
|
||||
init_host_command((uint32_t*)&host_command[1], (uint32_t*)&response_command[1],
|
||||
host_instruction::port_select::b, // destination_port
|
||||
ap::de::device | ap::port_select::b, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
host_command[1].bus_data.data_fields = data_fields;
|
||||
|
||||
init_host_command((uint32_t*)&host_command[2], (uint32_t*)&response_command[2],
|
||||
host_instruction::port_select::c, // destination_port
|
||||
ap::de::device | ap::port_select::c, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
host_command[2].bus_data.data_fields = data_fields;
|
||||
|
||||
init_host_command((uint32_t*)&host_command[3], (uint32_t*)&response_command[3],
|
||||
host_instruction::port_select::d, // destination_port
|
||||
ap::de::device | ap::port_select::d, C::command_code, (sizeof (typename C::data_fields)),
|
||||
true); // end_flag
|
||||
host_command[3].bus_data.data_fields = data_fields;
|
||||
|
||||
return reinterpret_cast<uint32_t>(&host_command[4]) - reinterpret_cast<uint32_t>(&host_command[0]);
|
||||
}
|
||||
|
||||
template <typename C, typename R>
|
||||
uint32_t init_host_command_all_ports(uint32_t * command_buf, uint32_t * receive_buf)
|
||||
{
|
||||
using command_type = maple::host_command<typename C::data_fields>;
|
||||
using response_type = maple::command_response<typename R::data_fields>;
|
||||
//static_assert((sizeof (command_type)) == 12);
|
||||
|
||||
auto host_command = reinterpret_cast<command_type *>(command_buf);
|
||||
auto response_command = reinterpret_cast<response_type *>(receive_buf);
|
||||
|
||||
init_host_command((uint32_t*)&host_command[0], (uint32_t*)&response_command[0],
|
||||
host_instruction::port_select::a, // destination_port
|
||||
ap::de::device | ap::port_select::a, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
|
||||
init_host_command((uint32_t*)&host_command[1], (uint32_t*)&response_command[1],
|
||||
host_instruction::port_select::b, // destination_port
|
||||
ap::de::device | ap::port_select::b, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
|
||||
init_host_command((uint32_t*)&host_command[2], (uint32_t*)&response_command[2],
|
||||
host_instruction::port_select::c, // destination_port
|
||||
ap::de::device | ap::port_select::c, C::command_code, (sizeof (typename C::data_fields)),
|
||||
false); // end_flag
|
||||
|
||||
init_host_command((uint32_t*)&host_command[3], (uint32_t*)&response_command[3],
|
||||
host_instruction::port_select::d, // destination_port
|
||||
ap::de::device | ap::port_select::d, C::command_code, (sizeof (typename C::data_fields)),
|
||||
true); // end_flag
|
||||
|
||||
return reinterpret_cast<uint32_t>(&host_command[1]) - reinterpret_cast<uint32_t>(&host_command[0]);
|
||||
}
|
||||
|
||||
}
|
25
maple/maple_port.hpp
Normal file
25
maple/maple_port.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "maple_bus_bits.hpp"
|
||||
|
||||
constexpr inline uint32_t ap_port_select(const uint32_t port)
|
||||
{
|
||||
switch (port) {
|
||||
default: [[fallthrough]];
|
||||
case 0: return ap::port_select::a;
|
||||
case 1: return ap::port_select::b;
|
||||
case 2: return ap::port_select::c;
|
||||
case 3: return ap::port_select::d;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline uint32_t host_instruction_port_select(const uint32_t port)
|
||||
{
|
||||
switch (port) {
|
||||
default: [[fallthrough]];
|
||||
case 0: return host_instruction::port_select::a;
|
||||
case 1: return host_instruction::port_select::b;
|
||||
case 2: return host_instruction::port_select::c;
|
||||
case 3: return host_instruction::port_select::d;
|
||||
}
|
||||
}
|
@ -121,7 +121,7 @@ def render_format(format):
|
||||
|
||||
def render_formats(name, formats):
|
||||
yield "#pragma once"
|
||||
|
||||
yield ""
|
||||
yield f"namespace {name} {{"
|
||||
for format in formats:
|
||||
yield from render_format(format)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import sys
|
||||
import string
|
||||
|
||||
from csv_input import read_input
|
||||
from generate import renderer
|
||||
@ -9,17 +10,59 @@ def render_row(row):
|
||||
yield f"constexpr uint32_t {usage} = {hex(code)};"
|
||||
|
||||
def render_rows(rows):
|
||||
yield "#include <cstdint>"
|
||||
yield ""
|
||||
yield "namespace ft6 {"
|
||||
yield "namespace scan_codes {"
|
||||
yield "namespace scan_code {"
|
||||
for row in rows:
|
||||
yield from render_row(row)
|
||||
yield "}"
|
||||
yield "}"
|
||||
|
||||
def code_point(s):
|
||||
if not s.strip():
|
||||
return '0'
|
||||
elif len(s) == 1:
|
||||
assert s in string.printable
|
||||
if s == '\\':
|
||||
return "'\\\\'"
|
||||
elif s.strip() == "'":
|
||||
return "'\\''"
|
||||
else:
|
||||
return f"'{s}'"
|
||||
else:
|
||||
assert False, s
|
||||
|
||||
last_printable = 0x38
|
||||
|
||||
def render_normal_shift(row):
|
||||
usage = row['usage']
|
||||
normal = code_point(row['normal'])
|
||||
shift = code_point(row['shift'])
|
||||
yield f"[scan_code::{usage}] = {{ {normal}, {shift} }},"
|
||||
|
||||
def render_scancode_code_point(rows):
|
||||
yield "namespace ft6 {"
|
||||
yield "namespace scan_code {"
|
||||
yield f"constexpr uint32_t last_printable = {hex(last_printable)};"
|
||||
yield ""
|
||||
yield f"const uint8_t code_point[last_printable + 1][2] = {{"
|
||||
for i, row in enumerate(rows):
|
||||
yield from render_normal_shift(row)
|
||||
if i == last_printable:
|
||||
break
|
||||
yield "};"
|
||||
yield "}"
|
||||
yield "}"
|
||||
|
||||
def header():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
yield "#include <cstdint>"
|
||||
yield ""
|
||||
|
||||
if __name__ == "__main__":
|
||||
rows = read_input(sys.argv[1])
|
||||
render, out = renderer()
|
||||
render(header())
|
||||
render(render_rows(rows))
|
||||
render(render_scancode_code_point(rows))
|
||||
print(out.getvalue())
|
||||
|
@ -1,84 +1,84 @@
|
||||
"code","usage",
|
||||
"0x00","no_operation",
|
||||
"0x01","rollover_error",
|
||||
"0x02","post_fail",
|
||||
"0x03","undefined_error",
|
||||
"0x04","a_A",
|
||||
"0x05","b_B",
|
||||
"0x06","c_C",
|
||||
"0x07","d_D",
|
||||
"0x08","e_E",
|
||||
"0x09","f_F",
|
||||
"0x0a","g_G",
|
||||
"0x0b","h_H",
|
||||
"0x0c","i_I",
|
||||
"0x0d","j_J",
|
||||
"0x0e","k_K",
|
||||
"0x0f","l_L",
|
||||
"0x10","m_M",
|
||||
"0x11","n_N",
|
||||
"0x12","o_O",
|
||||
"0x13","p_P",
|
||||
"0x14","q_Q",
|
||||
"0x15","r_R",
|
||||
"0x16","s_S",
|
||||
"0x17","t_T",
|
||||
"0x18","u_U",
|
||||
"0x19","v_V",
|
||||
"0x1a","w_W",
|
||||
"0x1b","x_X",
|
||||
"0x1c","y_Y",
|
||||
"0x1d","z_Z",
|
||||
"0x1e","_1_exclam",
|
||||
"0x1f","_2_at",
|
||||
"0x20","_3_numbersign",
|
||||
"0x21","_4_dollar",
|
||||
"0x22","_5_percent",
|
||||
"0x23","_6_asciicircum",
|
||||
"0x24","_7_ampersand",
|
||||
"0x25","_8_asterisk",
|
||||
"0x26","_9_parenleft",
|
||||
"0x27","_0_parenright",
|
||||
"0x28","_return",
|
||||
"0x29","esc",
|
||||
"0x2a","backspace",
|
||||
"0x2b","tab",
|
||||
"0x2c","spacebar",
|
||||
"0x2d","minus_underscore",
|
||||
"0x2e","equal_plus","underscore carot"
|
||||
"0x2f","bracketleft_braceleft","at"
|
||||
"0x30","bracketright_braceright","braceleft"
|
||||
"0x31","backslash_bar",
|
||||
"0x32","_unknown_",
|
||||
"0x33","semicolon_colon",
|
||||
"0x34","apostrophe_quotedbl",
|
||||
"0x35","grave_asciitilde",
|
||||
"0x36","comma_less",
|
||||
"0x37","period_greater",
|
||||
"0x38","slash_question",
|
||||
"0x39","caps_lock",
|
||||
"0x3a","F1",
|
||||
"0x3b","F2",
|
||||
"0x3c","F3",
|
||||
"0x3d","F4",
|
||||
"0x3e","F5",
|
||||
"0x3f","F6",
|
||||
"0x40","F7",
|
||||
"0x41","F8",
|
||||
"0x42","F9",
|
||||
"0x43","F10",
|
||||
"0x44","F11",
|
||||
"0x45","F12",
|
||||
"0x46","print_screen",
|
||||
"0x47","scroll_lock",
|
||||
"0x48","pause",
|
||||
"0x49","insert",
|
||||
"0x4a","home",
|
||||
"0x4b","page_up",
|
||||
"0x4c","_delete",
|
||||
"0x4d","end",
|
||||
"0x4e","page_down",
|
||||
"0x4f","right_arrow",
|
||||
"0x50","left_arrow",
|
||||
"0x51","down_arrow",
|
||||
"0x52","up_arrow",
|
||||
"code","usage","normal","shift"
|
||||
"0x00","no_operation",,
|
||||
"0x01","rollover_error",,
|
||||
"0x02","post_fail",,
|
||||
"0x03","undefined_error",,
|
||||
"0x04","a_A","a","A"
|
||||
"0x05","b_B","b","B"
|
||||
"0x06","c_C","c","C"
|
||||
"0x07","d_D","d","D"
|
||||
"0x08","e_E","e","E"
|
||||
"0x09","f_F","f","F"
|
||||
"0x0a","g_G","g","G"
|
||||
"0x0b","h_H","h","H"
|
||||
"0x0c","i_I","i","I"
|
||||
"0x0d","j_J","j","J"
|
||||
"0x0e","k_K","k","K"
|
||||
"0x0f","l_L","l","L"
|
||||
"0x10","m_M","m","M"
|
||||
"0x11","n_N","n","N"
|
||||
"0x12","o_O","o","O"
|
||||
"0x13","p_P","p","P"
|
||||
"0x14","q_Q","q","Q"
|
||||
"0x15","r_R","r","R"
|
||||
"0x16","s_S","s","S"
|
||||
"0x17","t_T","t","T"
|
||||
"0x18","u_U","u","U"
|
||||
"0x19","v_V","v","V"
|
||||
"0x1a","w_W","w","W"
|
||||
"0x1b","x_X","x","X"
|
||||
"0x1c","y_Y","y","Y"
|
||||
"0x1d","z_Z","z","Z"
|
||||
"0x1e","_1_exclam",1,"!"
|
||||
"0x1f","_2_at",2,"@"
|
||||
"0x20","_3_numbersign",3,"#"
|
||||
"0x21","_4_dollar",4,"$"
|
||||
"0x22","_5_percent",5,"%"
|
||||
"0x23","_6_asciicircum",6,"^"
|
||||
"0x24","_7_ampersand",7,"&"
|
||||
"0x25","_8_asterisk",8,"*"
|
||||
"0x26","_9_parenleft",9,"("
|
||||
"0x27","_0_parenright",0,")"
|
||||
"0x28","_return",,
|
||||
"0x29","esc",,
|
||||
"0x2a","backspace",,
|
||||
"0x2b","tab",,
|
||||
"0x2c","spacebar",,
|
||||
"0x2d","minus_underscore","-","_"
|
||||
"0x2e","equal_plus","=","+"
|
||||
"0x2f","bracketleft_braceleft","[","{"
|
||||
"0x30","bracketright_braceright","]","}"
|
||||
"0x31","backslash_bar","\","|"
|
||||
"0x32","iso_numbersign_tilde","#","~"
|
||||
"0x33","semicolon_colon",";",":"
|
||||
"0x34","apostrophe_quotedbl","'",""""
|
||||
"0x35","grave_asciitilde","'","~"
|
||||
"0x36","comma_less",",","<"
|
||||
"0x37","period_greater",".",">"
|
||||
"0x38","slash_question","/","?"
|
||||
"0x39","caps_lock",,
|
||||
"0x3a","F1",,
|
||||
"0x3b","F2",,
|
||||
"0x3c","F3",,
|
||||
"0x3d","F4",,
|
||||
"0x3e","F5",,
|
||||
"0x3f","F6",,
|
||||
"0x40","F7",,
|
||||
"0x41","F8",,
|
||||
"0x42","F9",,
|
||||
"0x43","F10",,
|
||||
"0x44","F11",,
|
||||
"0x45","F12",,
|
||||
"0x46","print_screen",,
|
||||
"0x47","scroll_lock",,
|
||||
"0x48","pause",,
|
||||
"0x49","insert",,
|
||||
"0x4a","home",,
|
||||
"0x4b","page_up",,
|
||||
"0x4c","_delete",,
|
||||
"0x4d","end",,
|
||||
"0x4e","page_down",,
|
||||
"0x4f","right_arrow",,
|
||||
"0x50","left_arrow",,
|
||||
"0x51","down_arrow",,
|
||||
"0x52","up_arrow",,
|
||||
|
|
Binary file not shown.
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "string.hpp"
|
||||
|
||||
namespace serial {
|
||||
|
@ -21,7 +21,7 @@ void keyboard_do_get_condition(uint32_t * command_buf,
|
||||
};
|
||||
|
||||
const uint32_t command_size = maple::init_host_command_all_ports<command_type, response_type>(command_buf, receive_buf, data_fields);
|
||||
using host_response_type = struct maple::command_response<response_type::data_fields>;
|
||||
using host_response_type = struct maple::host_response<response_type::data_fields>;
|
||||
auto host_response = reinterpret_cast<host_response_type *>(receive_buf);
|
||||
|
||||
maple::dma_start(command_buf, command_size,
|
||||
@ -68,12 +68,21 @@ void keyboard_debug(ft6::data_transfer::data_format * keyboards, uint32_t frame_
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_shifted(const uint8_t modifier_key)
|
||||
{
|
||||
return
|
||||
(ft6::data_transfer::modifier_key::right_shift() & modifier_key) ||
|
||||
(ft6::data_transfer::modifier_key::left_shift() & modifier_key);
|
||||
}
|
||||
|
||||
void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix, gap_buffer& gb)
|
||||
{
|
||||
uint32_t this_frame = (frame_ix + 0) & 1;
|
||||
uint32_t next_frame = (frame_ix + 1) & 1;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (i < 5 && keyboards[this_frame].scan_code_array[i + 1] != ft6::scan_codes::no_operation)
|
||||
if (keyboards[this_frame].scan_code_array[i] == ft6::scan_code::no_operation)
|
||||
break;
|
||||
if (i < 5 && keyboards[this_frame].scan_code_array[i + 1] != ft6::scan_code::no_operation)
|
||||
continue;
|
||||
bool make = true;
|
||||
for (int j = 0; j < 6; j++) {
|
||||
@ -85,61 +94,23 @@ void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame
|
||||
if (make) {
|
||||
// make
|
||||
uint8_t scan_code = keyboards[this_frame].scan_code_array[i];
|
||||
if (scan_code <= ft6::scan_code::last_printable) {
|
||||
bool shifted = is_shifted(keyboards[this_frame].modifier_key);
|
||||
char_type code_point = ft6::scan_code::code_point[scan_code][shifted];
|
||||
if (code_point != 0) {
|
||||
gap_append(gb, code_point);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
switch (scan_code) {
|
||||
case ft6::scan_codes::a_A: [[fallthrough]];
|
||||
case ft6::scan_codes::b_B: [[fallthrough]];
|
||||
case ft6::scan_codes::c_C: [[fallthrough]];
|
||||
case ft6::scan_codes::d_D: [[fallthrough]];
|
||||
case ft6::scan_codes::e_E: [[fallthrough]];
|
||||
case ft6::scan_codes::f_F: [[fallthrough]];
|
||||
case ft6::scan_codes::g_G: [[fallthrough]];
|
||||
case ft6::scan_codes::h_H: [[fallthrough]];
|
||||
case ft6::scan_codes::i_I: [[fallthrough]];
|
||||
case ft6::scan_codes::j_J: [[fallthrough]];
|
||||
case ft6::scan_codes::k_K: [[fallthrough]];
|
||||
case ft6::scan_codes::l_L: [[fallthrough]];
|
||||
case ft6::scan_codes::m_M: [[fallthrough]];
|
||||
case ft6::scan_codes::n_N: [[fallthrough]];
|
||||
case ft6::scan_codes::o_O: [[fallthrough]];
|
||||
case ft6::scan_codes::p_P: [[fallthrough]];
|
||||
case ft6::scan_codes::q_Q: [[fallthrough]];
|
||||
case ft6::scan_codes::r_R: [[fallthrough]];
|
||||
case ft6::scan_codes::s_S: [[fallthrough]];
|
||||
case ft6::scan_codes::t_T: [[fallthrough]];
|
||||
case ft6::scan_codes::u_U: [[fallthrough]];
|
||||
case ft6::scan_codes::v_V: [[fallthrough]];
|
||||
case ft6::scan_codes::w_W: [[fallthrough]];
|
||||
case ft6::scan_codes::x_X: [[fallthrough]];
|
||||
case ft6::scan_codes::y_Y: [[fallthrough]];
|
||||
case ft6::scan_codes::z_Z:
|
||||
{
|
||||
char_type code_point = (scan_code - ft6::scan_codes::a_A) + 'a';
|
||||
gap_append(gb, code_point);
|
||||
}
|
||||
break;
|
||||
case ft6::scan_codes::_1_exclam: [[fallthrough]];
|
||||
case ft6::scan_codes::_2_at: [[fallthrough]];
|
||||
case ft6::scan_codes::_3_numbersign: [[fallthrough]];
|
||||
case ft6::scan_codes::_4_dollar: [[fallthrough]];
|
||||
case ft6::scan_codes::_5_percent: [[fallthrough]];
|
||||
case ft6::scan_codes::_6_asciicircum: [[fallthrough]];
|
||||
case ft6::scan_codes::_7_ampersand: [[fallthrough]];
|
||||
case ft6::scan_codes::_8_asterisk: [[fallthrough]];
|
||||
case ft6::scan_codes::_9_parenleft:
|
||||
{
|
||||
char_type code_point = (scan_code - ft6::scan_codes::_1_exclam) + '1';
|
||||
gap_append(gb, code_point);
|
||||
}
|
||||
break;
|
||||
case ft6::scan_codes::_0_parenright: gap_append(gb, '0'); break;
|
||||
case ft6::scan_codes::_return: gap_append(gb, '\n'); break;
|
||||
case ft6::scan_codes::backspace: gap_pop(gb); break;
|
||||
case ft6::scan_codes::spacebar: gap_append(gb, ' '); break;
|
||||
case ft6::scan_code::_return: gap_append(gb, '\n'); break;
|
||||
case ft6::scan_code::backspace: gap_pop(gb); break;
|
||||
case ft6::scan_code::spacebar: gap_append(gb, ' '); break;
|
||||
|
||||
case ft6::scan_codes::left_arrow: gap_cursor_pos(gb, -1); break;
|
||||
case ft6::scan_codes::right_arrow: gap_cursor_pos(gb, 1); break;
|
||||
case ft6::scan_codes::up_arrow: gap_cursor_pos_line(gb, -1); break;
|
||||
case ft6::scan_codes::down_arrow: gap_cursor_pos_line(gb, 1); break;
|
||||
case ft6::scan_code::left_arrow: gap_cursor_pos(gb, -1); break;
|
||||
case ft6::scan_code::right_arrow: gap_cursor_pos(gb, 1); break;
|
||||
case ft6::scan_code::up_arrow: gap_cursor_pos_line(gb, -1); break;
|
||||
case ft6::scan_code::down_arrow: gap_cursor_pos_line(gb, 1); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -80,13 +80,13 @@ void main()
|
||||
|
||||
constexpr uint32_t ta_alloc = ta_alloc_ctrl::pt_opb::no_list
|
||||
| ta_alloc_ctrl::tm_opb::no_list
|
||||
//| ta_alloc_ctrl::t_opb::_16x4byte
|
||||
| ta_alloc_ctrl::t_opb::_16x4byte
|
||||
| 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 = 16 * 4
|
||||
, .translucent = 16 * 4
|
||||
, .translucent_modifier = 0
|
||||
, .punch_through = 0
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user