panel
This commit is contained in:
parent
73027de4d2
commit
73a1add2f1
5 changed files with 106 additions and 9 deletions
|
@ -13,8 +13,6 @@ constexpr const int t_height { 25 };
|
|||
class console
|
||||
{
|
||||
private:
|
||||
std::atomic_bool *const terminate { nullptr };
|
||||
|
||||
std::vector<char> input_buffer;
|
||||
|
||||
char screen_buffer[t_height][t_width];
|
||||
|
@ -22,6 +20,8 @@ private:
|
|||
uint8_t ty { 0 };
|
||||
|
||||
protected:
|
||||
std::atomic_bool *const terminate { nullptr };
|
||||
|
||||
bus *const b { nullptr };
|
||||
std::thread *th { nullptr };
|
||||
std::atomic_bool disk_read_activity_flag { false };
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "console_ncurses.h"
|
||||
#include "cpu.h"
|
||||
#include "error.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
console_ncurses::console_ncurses(std::atomic_bool *const terminate, bus *const b) :
|
||||
|
@ -15,31 +17,50 @@ console_ncurses::console_ncurses(std::atomic_bool *const terminate, bus *const b
|
|||
resize_terminal();
|
||||
|
||||
th = new std::thread(std::ref(*this));
|
||||
|
||||
th_panel = new std::thread(&console_ncurses::panel_update_thread, this);
|
||||
}
|
||||
|
||||
console_ncurses::~console_ncurses()
|
||||
{
|
||||
if (th_panel) {
|
||||
th_panel->join();
|
||||
|
||||
delete th_panel;
|
||||
}
|
||||
|
||||
if (th) {
|
||||
th->join();
|
||||
|
||||
delete th;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lck(ncurses_mutex);
|
||||
|
||||
wprintw(w_main->win, "\n\n *** PRESS ENTER TO TERMINATE ***\n");
|
||||
mydoupdate();
|
||||
|
||||
while(getch() != 13) {
|
||||
}
|
||||
|
||||
delete_window(w_panel_b);
|
||||
delete_window(w_panel);
|
||||
|
||||
delete_window(w_main_b);
|
||||
delete_window(w_main);
|
||||
|
||||
endwin();
|
||||
}
|
||||
|
||||
int console_ncurses::wait_for_char(const int timeout)
|
||||
{
|
||||
struct pollfd fds[] = { { STDIN_FILENO, POLLIN, timeout } };
|
||||
struct pollfd fds[] = { { STDIN_FILENO, POLLIN, 0 } };
|
||||
|
||||
if (poll(fds, 1, timeout) == 1 && fds[0].revents) {
|
||||
std::unique_lock<std::mutex> lck(ncurses_mutex);
|
||||
|
||||
if (poll(fds, 1, 0) == 1 && fds[0].revents)
|
||||
return getch();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -47,14 +68,20 @@ int console_ncurses::wait_for_char(const int timeout)
|
|||
void console_ncurses::put_char_ll(const char c)
|
||||
{
|
||||
if (c >= 32 || (c != 12 && c != 27 && c != 13)) {
|
||||
std::unique_lock<std::mutex> lck(ncurses_mutex);
|
||||
|
||||
wprintw(w_main->win, "%c", c);
|
||||
|
||||
getyx(w_main->win, ty, tx);
|
||||
|
||||
mydoupdate();
|
||||
}
|
||||
}
|
||||
|
||||
void console_ncurses::resize_terminal()
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(ncurses_mutex);
|
||||
|
||||
determine_terminal_size();
|
||||
|
||||
if (ERR == resizeterm(max_y, max_x))
|
||||
|
@ -70,7 +97,9 @@ void console_ncurses::resize_terminal()
|
|||
delete_window(w_main_b);
|
||||
delete_window(w_main);
|
||||
|
||||
create_win_border(0, 0, max_x - 2, max_y - 2, "window", &w_main_b, &w_main, false);
|
||||
create_win_border(0, 0, max_x - 2, max_y - 6, "window", &w_main_b, &w_main, false);
|
||||
|
||||
create_win_border(0, max_y - 4, max_x - 2, 2, "panel", &w_panel_b, &w_panel, false);
|
||||
|
||||
scrollok(w_main -> win, TRUE);
|
||||
|
||||
|
@ -79,4 +108,39 @@ void console_ncurses::resize_terminal()
|
|||
|
||||
void console_ncurses::panel_update_thread()
|
||||
{
|
||||
cpu *const c = b->getCpu();
|
||||
|
||||
while(!*terminate) {
|
||||
myusleep(1000000 / 50); // 50 updates/sec
|
||||
|
||||
// note that these are approximately as there's no mutex on the emulation
|
||||
uint16_t current_PC = c->getPC();
|
||||
uint32_t full_addr = b->calculate_full_address(current_PC);
|
||||
|
||||
uint16_t current_instr = b->readWord(current_PC);
|
||||
|
||||
uint16_t current_PSW = c->getPSW();
|
||||
|
||||
//uint32_t led_color = run_mode_led_color[current_PSW >> 14];
|
||||
|
||||
std::unique_lock<std::mutex> lck(ncurses_mutex);
|
||||
|
||||
for(uint8_t b=0; b<22; b++)
|
||||
mvwprintw(w_panel->win, 0, 1 + 22 - b, "%c", full_addr & (1 << b) ? '1' : '0');
|
||||
|
||||
for(uint8_t b=0; b<16; b++)
|
||||
mvwprintw(w_panel->win, 1, 1 + 16 - b, "%c", current_PSW & (1 << b) ? '1' : '0');
|
||||
|
||||
for(uint8_t b=0; b<16; b++)
|
||||
mvwprintw(w_panel->win, 1, 1 + 16 - b + 17, "%c", current_instr & (1 << b) ? '1' : '0');
|
||||
|
||||
mvwprintw(w_panel->win, 1, 1 + 35, "%c%c%c",
|
||||
running_flag ? '+' : '-',
|
||||
disk_read_activity_flag ? '*' : 'o',
|
||||
disk_write_activity_flag ? '*' : 'o');
|
||||
|
||||
wmove(w_main->win, ty, tx);
|
||||
|
||||
mydoupdate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <mutex>
|
||||
#include <ncurses.h>
|
||||
|
||||
#include "console.h"
|
||||
|
@ -9,6 +10,15 @@ class console_ncurses : public console
|
|||
private:
|
||||
NEWWIN *w_main_b { nullptr };
|
||||
NEWWIN *w_main { nullptr };
|
||||
NEWWIN *w_panel_b { nullptr };
|
||||
NEWWIN *w_panel { nullptr };
|
||||
|
||||
std::mutex ncurses_mutex;
|
||||
|
||||
std::thread *th_panel { nullptr };
|
||||
|
||||
int tx { 0 };
|
||||
int ty { 0 };
|
||||
|
||||
protected:
|
||||
int wait_for_char(const int timeout) override;
|
||||
|
|
23
utils.cpp
23
utils.cpp
|
@ -1,11 +1,13 @@
|
|||
// (C) 2018 by Folkert van Heusden
|
||||
// (C) 2018-2022 by Folkert van Heusden
|
||||
// Released under Apache License v2.0
|
||||
#if defined(ESP32)
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
void setBit(uint16_t & v, const int bit, const bool vb)
|
||||
|
@ -50,3 +52,22 @@ int parity(int v)
|
|||
{
|
||||
return __builtin_parity(v); // FIXME
|
||||
}
|
||||
|
||||
void myusleep(uint64_t us)
|
||||
{
|
||||
struct timespec req;
|
||||
|
||||
req.tv_sec = us / 1000000l;
|
||||
req.tv_nsec = (us % 1000000l) * 1000l;
|
||||
|
||||
for(;;) {
|
||||
struct timespec rem { 0, 0 };
|
||||
|
||||
int rc = nanosleep(&req, &rem);
|
||||
if (rc == 0 || (rc == -1 && errno != EINTR))
|
||||
break;
|
||||
|
||||
memcpy(&req, &rem, sizeof(struct timespec));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
utils.h
2
utils.h
|
@ -9,4 +9,6 @@ int parity(int v);
|
|||
#define sign(a) ( ( (a) < 0 ) ? -1 : ( (a) > 0 ) )
|
||||
|
||||
std::string format(const char *const fmt, ...);
|
||||
|
||||
unsigned long get_ms();
|
||||
void myusleep(uint64_t us);
|
||||
|
|
Loading…
Add table
Reference in a new issue