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.h
gui/mainwindow.ui
sim_wrappers/kbd.hpp
sim_wrappers/gui_output.hpp
)

View File

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

View File

@ -2,6 +2,7 @@
#include "tb.h"
#include CONCAT5(V,TOP_NAME,_,TOP_NAME,.h)
#include CONCAT5(V,TOP_NAME,_,orion_pro_top,.h)
#include <QEvent>
double sc_time_stamp() { return 0; }
@ -13,6 +14,18 @@ double sc_time_stamp() { return 0; }
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)
{
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_cb_start_draw = cb_to_draw;
m_cb_resize = cb_resize;
m_state = SIM_STATE::INIT;
//this->p_gui = p_gui;
//this->p_kbd = p_kbd;
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_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_kbd_input = (uint8_t*)&top->TOP_NAME->u_orion_core->kbd_input;
p_kbd_output = (uint8_t*)&top->TOP_NAME->u_orion_core->kbd_output;
p_kbd_input = (kbd_port_u*) &top->TOP_NAME->u_orion_core->kbd_input;
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->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()
{
TOP_CLASS* top = obj_tb->get_top();
@ -55,13 +80,31 @@ void SIM_TOP::thread_main()
uint32_t screen_cycle = 0;
uint32_t sec_cycle = 0;
time_t time_prev = time(0);
bool screen_refresh;
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);
//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);
if (++screen_cycle == screen_period)
//sim_time = (cycle * 1.f) / cycle_len;
kbd_proc();
if (screen_refresh)
{
screen_proc();
m_cb_start_draw();
@ -75,6 +118,12 @@ void SIM_TOP::thread_main()
printf("Sim time for 1 second: %ld\n", delta);
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();
@ -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
#include <thread>
#include <functional>
#include <mutex>
#include <set>
typedef union
{
@ -33,20 +35,46 @@ typedef union
uint8_t bt;
} 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_WIDTH_NORMAL 384
#define SCREEN_WIDTH_WIDE 512
enum class SIM_STATE
{
INIT,
IDLE,
RUN,
RUN_STEP,
};
typedef std::function<void()> thread_cb_t;
class SIM_TOP
{
public:
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_height() { return SCREEN_HEIGHT; }
uint32_t* get_screen() { return p_screen; }
void stop() { m_active = false; }
void key_press(uint32_t key);
void key_release(uint32_t key);
private:
std::thread* p_thr;
bool m_active;
@ -56,11 +84,15 @@ private:
video_mode_u* p_video_mode;
screen_mode_u* p_screen_mode;
colors_pseudo_u*p_colors_pseudo;
uint8_t* p_kbd_input;
uint8_t* p_kbd_output;
kbd_port_u* p_kbd_input;
kbd_port_u* p_kbd_output;
thread_cb_t m_cb_start_draw;
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 screen_proc();
void kbd_proc();
};