Add keyboard processing, fixed version.

This commit is contained in:
andreili 2024-10-02 09:44:50 +02:00
parent 91c1e6807f
commit d945dd98fb
4 changed files with 121 additions and 13 deletions

View File

@ -42,7 +42,7 @@ set(PROJECT_SOURCES
gui/mainwindow.cpp gui/mainwindow.cpp
gui/mainwindow.h gui/mainwindow.h
gui/mainwindow.ui gui/mainwindow.ui
sim_wrappers/kbd.hpp
sim_wrappers/gui_output.hpp sim_wrappers/gui_output.hpp
) )

View File

@ -33,6 +33,8 @@ MainWindow::MainWindow(QWidget *parent)
status_screen = new QLabel(); status_screen = new QLabel();
//ui->statusbar->addPermanentWidget(status_screen); //ui->statusbar->addPermanentWidget(status_screen);
sim->run_cont();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -115,18 +117,16 @@ void MainWindow::keyPressEvent(QKeyEvent *evt)
{ {
if (this->isActiveWindow()) if (this->isActiveWindow())
{ {
// sim->key_press(evt->key());
} }
//this->p_kbd->add_event(evt);
} }
void MainWindow::keyReleaseEvent(QKeyEvent *evt) void MainWindow::keyReleaseEvent(QKeyEvent *evt)
{ {
if (this->isActiveWindow()) if (this->isActiveWindow())
{ {
// sim->key_release(evt->key());
} }
//this->p_kbd->add_event(evt);
} }
void MainWindow::closeEvent(QCloseEvent *evt) void MainWindow::closeEvent(QCloseEvent *evt)

View File

@ -2,6 +2,7 @@
#include "tb.h" #include "tb.h"
#include CONCAT5(V,TOP_NAME,_,TOP_NAME,.h) #include CONCAT5(V,TOP_NAME,_,TOP_NAME,.h)
#include CONCAT5(V,TOP_NAME,_,orion_pro_top,.h) #include CONCAT5(V,TOP_NAME,_,orion_pro_top,.h)
#include <QEvent>
double sc_time_stamp() { return 0; } double sc_time_stamp() { return 0; }
@ -13,6 +14,18 @@ double sc_time_stamp() { return 0; }
static TB* obj_tb; static TB* obj_tb;
int key_matrix[8][11] = {
/*r D0*/ { '*', Qt::Key_Escape, '+', Qt::Key_F1, Qt::Key_F2, Qt::Key_F3, '4', Qt::Key_F4, Qt::Key_F5, '7', '8' },
/*e D1*/ { Qt::Key_Minus, Qt::Key_Tab, 'J' , '1', '2', '3', 'E', '5', '6', '[', ']' },
/*s D2*/ { 0, Qt::Key_CapsLock, 'F' , 'C', 'U', 'K', 'P', 'N', 'G', 'L', 'D' },
/*u D3*/ { 0, 0, 'Q' , 'Y', 'W', 'A', 'I', 'R', 'O', 'B', 0 },
/*l D4*/ { Qt::Key_Shift, Qt::Key_Control, 0, 0xDE, 'S', 'M', ' ', 'T', 'X', Qt::Key_Left, '<' },
/*t D5*/ { '7' | Qt::KeypadModifier, '0' | Qt::KeypadModifier, '1' | Qt::KeypadModifier, '4' | Qt::KeypadModifier, Qt::Key_Plus, Qt::Key_Backspace, Qt::Key_Right, Qt::Key_Down, '>', '\\', 'V' },
/* D6*/ { '8' | Qt::KeypadModifier, '.', '2' | Qt::KeypadModifier, '5' | Qt::KeypadModifier, Qt::Key_F6, Qt::Key_Home, Qt::Key_Return, Qt::Key_Up, '/', 'H', 'Z' },
/* D7*/ { '9' | Qt::KeypadModifier, Qt::Key_Return, '3' | Qt::KeypadModifier, '6' | Qt::KeypadModifier, Qt::Key_Insert, Qt::Key_End, ';', '?', '-', '0', '9' }};
/*scancode D0 D1 D2 D3 D4 D5 D6 D7 CD0 CD1 CD2 */
static int on_step_cb(uint64_t time, TOP_CLASS* p_top) static int on_step_cb(uint64_t time, TOP_CLASS* p_top)
{ {
p_top->i_clk = !p_top->i_clk; p_top->i_clk = !p_top->i_clk;
@ -25,6 +38,7 @@ SIM_TOP::SIM_TOP(int argc, const char** argv, thread_cb_t cb_to_draw, thread_cb_
m_cur_width = 0; m_cur_width = 0;
m_cb_start_draw = cb_to_draw; m_cb_start_draw = cb_to_draw;
m_cb_resize = cb_resize; m_cb_resize = cb_resize;
m_state = SIM_STATE::INIT;
//this->p_gui = p_gui; //this->p_gui = p_gui;
//this->p_kbd = p_kbd; //this->p_kbd = p_kbd;
obj_tb = new TB(TOP_NAME_STR, argc, argv); obj_tb = new TB(TOP_NAME_STR, argc, argv);
@ -34,12 +48,23 @@ SIM_TOP::SIM_TOP(int argc, const char** argv, thread_cb_t cb_to_draw, thread_cb_
p_video_mode = (video_mode_u*) &top->TOP_NAME->u_orion_core->video_mode; p_video_mode = (video_mode_u*) &top->TOP_NAME->u_orion_core->video_mode;
p_screen_mode = (screen_mode_u*) &top->TOP_NAME->u_orion_core->screen_mode; p_screen_mode = (screen_mode_u*) &top->TOP_NAME->u_orion_core->screen_mode;
p_colors_pseudo = (colors_pseudo_u*)&top->TOP_NAME->u_orion_core->colors_pseudo; p_colors_pseudo = (colors_pseudo_u*)&top->TOP_NAME->u_orion_core->colors_pseudo;
p_kbd_input = (uint8_t*)&top->TOP_NAME->u_orion_core->kbd_input; p_kbd_input = (kbd_port_u*) &top->TOP_NAME->u_orion_core->kbd_input;
p_kbd_output = (uint8_t*)&top->TOP_NAME->u_orion_core->kbd_output; p_kbd_output = (kbd_port_u*) &top->TOP_NAME->u_orion_core->kbd_output;
p_kbd_input->dw = 0xffffffff;
p_thr = new std::thread(&SIM_TOP::thread_main, this); p_thr = new std::thread(&SIM_TOP::thread_main, this);
//p_thr->join(); //p_thr->join();
} }
void SIM_TOP::key_press(uint32_t key)
{
m_key_pressed.insert(key);
}
void SIM_TOP::key_release(uint32_t key)
{
m_key_pressed.erase(key);
}
void SIM_TOP::thread_main() void SIM_TOP::thread_main()
{ {
TOP_CLASS* top = obj_tb->get_top(); TOP_CLASS* top = obj_tb->get_top();
@ -55,13 +80,31 @@ void SIM_TOP::thread_main()
uint32_t screen_cycle = 0; uint32_t screen_cycle = 0;
uint32_t sec_cycle = 0; uint32_t sec_cycle = 0;
time_t time_prev = time(0); time_t time_prev = time(0);
bool screen_refresh;
while (m_active) while (m_active)
{ {
m_mtx.lock();
switch (m_state)
{
case SIM_STATE::INIT:
m_mtx.lock();
break;
case SIM_STATE::IDLE:
m_mtx.lock();
break;
case SIM_STATE::RUN:
obj_tb->run_steps(2); obj_tb->run_steps(2);
//sim_time = (cycle * 1.f) / cycle_len; screen_refresh = (++screen_cycle == screen_period);
break;
case SIM_STATE::RUN_STEP:
obj_tb->run_steps(2);
screen_refresh = true;
break;
}
//p_instance->p_gui->draw(sim_time); //sim_time = (cycle * 1.f) / cycle_len;
if (++screen_cycle == screen_period) kbd_proc();
if (screen_refresh)
{ {
screen_proc(); screen_proc();
m_cb_start_draw(); m_cb_start_draw();
@ -75,6 +118,12 @@ void SIM_TOP::thread_main()
printf("Sim time for 1 second: %ld\n", delta); printf("Sim time for 1 second: %ld\n", delta);
sec_cycle = 0; sec_cycle = 0;
} }
if (m_state == SIM_STATE::RUN_STEP)
{
// pause to next step or state change
//m_mtx.lock();
}
m_mtx.unlock();
} }
obj_tb->finish(); obj_tb->finish();
@ -216,3 +265,30 @@ void SIM_TOP::screen_proc()
} }
} }
} }
void SIM_TOP::kbd_proc()
{
uint32_t scancode_msk = ((p_kbd_output->bt.PC & 0x7) << 8) | p_kbd_output->bt.PB;
static uint32_t scancode_prev;
if (scancode_msk == scancode_prev)
{
return;
}
uint32_t result = 0xff;
for (int j=0 ; j<11 ; ++j)
{
if ((scancode_msk & (1 << j)) == 0)
{
for (int i=0 ; i<8 ; ++i)
{
int key = key_matrix[i][j];
if (m_key_pressed.count(key) != 0)
{
result &= ~(1 << i);
}
}
}
}
p_kbd_input->bt.PA = result;
scancode_prev = scancode_msk;
}

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <thread> #include <thread>
#include <functional> #include <functional>
#include <mutex>
#include <set>
typedef union typedef union
{ {
@ -33,20 +35,46 @@ typedef union
uint8_t bt; uint8_t bt;
} colors_pseudo_u; } colors_pseudo_u;
typedef union
{
uint32_t dw;
struct
{
uint8_t PA;
uint8_t PB;
uint8_t PC;
uint8_t res;
} bt;
} kbd_port_u;
#define SCREEN_HEIGHT 256 #define SCREEN_HEIGHT 256
#define SCREEN_WIDTH_NORMAL 384 #define SCREEN_WIDTH_NORMAL 384
#define SCREEN_WIDTH_WIDE 512 #define SCREEN_WIDTH_WIDE 512
enum class SIM_STATE
{
INIT,
IDLE,
RUN,
RUN_STEP,
};
typedef std::function<void()> thread_cb_t; typedef std::function<void()> thread_cb_t;
class SIM_TOP class SIM_TOP
{ {
public: public:
SIM_TOP(int argc, const char** argv, thread_cb_t cb_to_draw, thread_cb_t cb_resize); SIM_TOP(int argc, const char** argv, thread_cb_t cb_to_draw, thread_cb_t cb_resize);
void run_cont() { m_state = SIM_STATE::RUN; m_mtx.unlock(); }
void run_step() { m_state = SIM_STATE::RUN_STEP; m_mtx.unlock(); }
void run_pause() { m_state = SIM_STATE::IDLE; m_mtx.lock(); }
int get_width() { return m_cur_width; } int get_width() { return m_cur_width; }
int get_height() { return SCREEN_HEIGHT; } int get_height() { return SCREEN_HEIGHT; }
uint32_t* get_screen() { return p_screen; } uint32_t* get_screen() { return p_screen; }
void stop() { m_active = false; } void stop() { m_active = false; }
void key_press(uint32_t key);
void key_release(uint32_t key);
private: private:
std::thread* p_thr; std::thread* p_thr;
bool m_active; bool m_active;
@ -56,11 +84,15 @@ private:
video_mode_u* p_video_mode; video_mode_u* p_video_mode;
screen_mode_u* p_screen_mode; screen_mode_u* p_screen_mode;
colors_pseudo_u*p_colors_pseudo; colors_pseudo_u*p_colors_pseudo;
uint8_t* p_kbd_input; kbd_port_u* p_kbd_input;
uint8_t* p_kbd_output; kbd_port_u* p_kbd_output;
thread_cb_t m_cb_start_draw; thread_cb_t m_cb_start_draw;
thread_cb_t m_cb_resize; thread_cb_t m_cb_resize;
SIM_STATE m_state;
std::mutex m_mtx;
std::set<uint32_t> m_key_pressed;
void thread_main(); void thread_main();
void screen_proc(); void screen_proc();
void kbd_proc();
}; };