INTERFACE:
-class Irq;
+class Irq_base;
class Vkey
{
// ---------------------------------------------------------------------------
IMPLEMENTATION:
-#include "irq.h"
+#include "irq_chip.h"
-static Irq *vkey_irq;
+static Irq_base *vkey_irq;
PUBLIC static
void
-Vkey::irq(Irq *i)
+Vkey::irq(Irq_base *i)
{ vkey_irq = i; }
+// ------------------------------------------------------------------------
+IMPLEMENTATION [serial && !ux && debug]:
+
+PRIVATE static inline
+bool
+Vkey::is_debugger_entry_key(int key)
+{
+ return key == KEY_ESC;
+}
+
+// ------------------------------------------------------------------------
+IMPLEMENTATION [serial && !ux && !debug]:
+
+PRIVATE static inline
+bool
+Vkey::is_debugger_entry_key(int)
+{
+ return false;
+}
+
// ---------------------------------------------------------------------------
-IMPLEMENTATION [debug && serial && !ux]:
+IMPLEMENTATION [serial && !ux]:
+
+#include <cstdio>
#include "config.h"
#include "cpu.h"
#include "globals.h"
#include "kernel_console.h"
-#include "kernel_uart.h"
#include "keycodes.h"
static Vkey::Echo_type vkey_echo;
static char vkey_buffer[256];
static unsigned vkey_tail, vkey_head;
-static Console *uart = Kconsole::console()->find_console(Console::UART);
PUBLIC static
void
vkey_echo = echo;
}
-PUBLIC static
-int
-Vkey::check_(int irq = -1)
+PRIVATE static
+bool
+Vkey::add(int c)
{
- if (!uart)
- return 1;
-
- int ret = 0;
bool hit = false;
+ unsigned nh = (vkey_head + 1) % sizeof(vkey_buffer);
+ unsigned oh = vkey_head;
+ if (nh != vkey_tail)
+ {
+ vkey_buffer[vkey_head] = c;
+ vkey_head = nh;
+ }
- // disable last branch recording, branch trace recording ...
- Cpu::cpus.cpu(current_cpu()).debugctl_disable();
+ if (oh == vkey_tail)
+ hit = true;
- while(1)
- {
- int c = uart->getchar(false);
+ if (vkey_echo == Vkey::Echo_crnl && c == '\r')
+ c = '\n';
- if (irq == Kernel_uart::uart()->irq() && c == -1)
- {
- ret = 1;
- break;
- }
+ if (vkey_echo)
+ putchar(c);
- if (c == -1 || c == KEY_ESC)
- break;
+ return hit;
+}
- unsigned nh = (vkey_head + 1) % sizeof(vkey_buffer);
- unsigned oh = vkey_head;
- if (nh != vkey_tail)
- {
- vkey_buffer[vkey_head] = c;
- vkey_head = nh;
- }
+PRIVATE static
+bool
+Vkey::add(const char *seq)
+{
+ bool hit = false;
+ for (; *seq; ++seq)
+ hit |= add(*seq);
+ return hit;
+}
- if (oh == vkey_tail)
- hit = true;
+PRIVATE static
+void
+Vkey::trigger()
+{
+ if (vkey_irq)
+ vkey_irq->hit(0);
+}
- if (vkey_echo == Vkey::Echo_crnl && c == '\r')
- c = '\n';
+PUBLIC static
+void
+Vkey::add_char(int v)
+{
+ if (add(v))
+ trigger();
+}
- if (vkey_echo)
- putchar(c);
+PUBLIC static
+int
+Vkey::check_()
+{
+ int ret = 1;
+ bool hit = false;
- ret = 1;
- }
+ // disable last branch recording, branch trace recording ...
+ Cpu::cpus.cpu(current_cpu()).debugctl_disable();
- if (hit && vkey_irq)
- vkey_irq->hit();
+ while (1)
+ {
+ int c = Kconsole::console()->getchar(false);
+
+ if (c == -1)
+ break;
+
+ if (is_debugger_entry_key(c))
+ {
+ ret = 0; // break into kernel debugger
+ break;
+ }
+
+ switch (c)
+ {
+ case KEY_CURSOR_UP: hit |= add("\033[A"); break;
+ case KEY_CURSOR_DOWN: hit |= add("\033[B"); break;
+ case KEY_CURSOR_LEFT: hit |= add("\033[D"); break;
+ case KEY_CURSOR_RIGHT: hit |= add("\033[C"); break;
+ case KEY_CURSOR_HOME: hit |= add("\033[1~"); break;
+ case KEY_CURSOR_END: hit |= add("\033[4~"); break;
+ case KEY_PAGE_UP: hit |= add("\033[5~"); break;
+ case KEY_PAGE_DOWN: hit |= add("\033[6~"); break;
+ case KEY_INSERT: hit |= add("\033[2~"); break;
+ case KEY_DELETE: hit |= add("\033[3~"); break;
+ case KEY_F1: hit |= add("\033OP"); break;
+ case KEY_BACKSPACE: hit |= add(127); break;
+ case KEY_TAB: hit |= add(9); break;
+ case KEY_ESC: hit |= add(27); break;
+ case KEY_RETURN: hit |= add(13); break;
+ default: hit |= add(c); break;
+ }
+ }
- if(Config::serial_esc == Config::SERIAL_ESC_IRQ)
- Kernel_uart::uart()->enable_rcv_irq();
+ if (hit)
+ trigger();
// reenable debug stuff (undo debugctl_disable)
Cpu::cpus.cpu(current_cpu()).debugctl_enable();
}
//----------------------------------------------------------------------------
-IMPLEMENTATION [!debug || !serial || ux]:
+IMPLEMENTATION [!serial || ux]:
-PUBLIC static
+#include "kernel_console.h"
+
+PUBLIC static inline
void
Vkey::set_echo(Echo_type)
{}
-PUBLIC static
+PUBLIC static inline
void
Vkey::clear()
{}
-
-//----------------------------------------------------------------------------
-IMPLEMENTATION [debug && (!serial || ux)]:
-
-#include "kernel_console.h"
+PUBLIC static inline
+void
+Vkey::add_char(int)
+{}
PUBLIC static
int
return Kconsole::console()->getchar(0);
}
-//----------------------------------------------------------------------------
-IMPLEMENTATION [!debug && serial]:
-
-#include "kernel_console.h"
-#include "kernel_uart.h"
-
-static Console *uart = Kconsole::console()->find_console(Console::UART);
-
-PUBLIC static
-int
-Vkey::get()
-{
- return uart->getchar(false);
-}
-
-//----------------------------------------------------------------------------
-IMPLEMENTATION[!debug && !serial]:
-
-PUBLIC static
-int
-Vkey::get()
-{ return -1; }
-
-//----------------------------------------------------------------------------
-IMPLEMENTATION[!debug || !serial]:
-
PUBLIC static inline
int
Vkey::check_(int = -1)