mirror of
https://github.com/andreili/OriVEmu.git
synced 2025-08-23 19:34:07 +02:00
Add keyboard processing, fixed version.
This commit is contained in:
parent
91c1e6807f
commit
d945dd98fb
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user