163 lines
3.1 KiB
C
163 lines
3.1 KiB
C
![]() |
// terminalhelp from mini-rv32ima.
|
||
|
#ifndef _TERMINALHELP_H
|
||
|
#define _TERMINALHELP_H
|
||
|
|
||
|
#include <stdint.h>
|
||
|
|
||
|
// Provides the following:
|
||
|
static void CaptureKeyboardInput() __attribute__((used));
|
||
|
static void ResetKeyboardInput() __attribute__((used));
|
||
|
static uint64_t GetTimeMicroseconds() __attribute__((used));
|
||
|
static int ReadKBByte() __attribute__((used));
|
||
|
static int IsKBHit() __attribute__((used));
|
||
|
|
||
|
#if defined(WINDOWS) || defined(WIN32) || defined(_WIN32)
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <conio.h>
|
||
|
|
||
|
#define strtoll _strtoi64
|
||
|
|
||
|
static void CaptureKeyboardInput()
|
||
|
{
|
||
|
system(""); // Poorly documented tick: Enable VT100 Windows mode.
|
||
|
}
|
||
|
|
||
|
static void ResetKeyboardInput()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static uint64_t GetTimeMicroseconds()
|
||
|
{
|
||
|
static LARGE_INTEGER lpf;
|
||
|
LARGE_INTEGER li;
|
||
|
|
||
|
if( !lpf.QuadPart )
|
||
|
QueryPerformanceFrequency( &lpf );
|
||
|
|
||
|
QueryPerformanceCounter( &li );
|
||
|
return ((uint64_t)li.QuadPart * 1000000LL) / (uint64_t)lpf.QuadPart;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int IsKBHit()
|
||
|
{
|
||
|
return _kbhit();
|
||
|
}
|
||
|
|
||
|
static int ReadKBByte()
|
||
|
{
|
||
|
// This code is kind of tricky, but used to convert windows arrow keys
|
||
|
// to VT100 arrow keys.
|
||
|
static int is_escape_sequence = 0;
|
||
|
int r;
|
||
|
if( is_escape_sequence == 1 )
|
||
|
{
|
||
|
is_escape_sequence++;
|
||
|
return '[';
|
||
|
}
|
||
|
|
||
|
r = _getch();
|
||
|
|
||
|
if( is_escape_sequence )
|
||
|
{
|
||
|
is_escape_sequence = 0;
|
||
|
switch( r )
|
||
|
{
|
||
|
case 'H': return 'A'; // Up
|
||
|
case 'P': return 'B'; // Down
|
||
|
case 'K': return 'D'; // Left
|
||
|
case 'M': return 'C'; // Right
|
||
|
case 'G': return 'H'; // Home
|
||
|
case 'O': return 'F'; // End
|
||
|
default: return r; // Unknown code.
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch( r )
|
||
|
{
|
||
|
case 13: return 10; //cr->lf
|
||
|
case 224: is_escape_sequence = 1; return 27; // Escape arrow keys
|
||
|
default: return r;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
#include <sys/ioctl.h>
|
||
|
#include <termios.h>
|
||
|
#undef BS0
|
||
|
#undef BS1
|
||
|
#include <unistd.h>
|
||
|
#include <signal.h>
|
||
|
#include <sys/time.h>
|
||
|
|
||
|
static void CtrlC()
|
||
|
{
|
||
|
fprintf( stderr, "Minichlink Closing\n" );
|
||
|
ResetKeyboardInput();
|
||
|
exit( 0 );
|
||
|
}
|
||
|
|
||
|
// Override keyboard, so we can capture all keyboard input for the VM.
|
||
|
static void CaptureKeyboardInput()
|
||
|
{
|
||
|
// Hook exit, because we want to re-enable keyboard.
|
||
|
atexit(ResetKeyboardInput);
|
||
|
signal(SIGINT, CtrlC);
|
||
|
signal(SIGPIPE, CtrlC);
|
||
|
|
||
|
struct termios term;
|
||
|
tcgetattr(0, &term);
|
||
|
term.c_lflag &= ~(ICANON | ECHO); // Disable echo as well
|
||
|
tcsetattr(0, TCSANOW, &term);
|
||
|
}
|
||
|
|
||
|
static void ResetKeyboardInput()
|
||
|
{
|
||
|
// Re-enable echo, etc. on keyboard.
|
||
|
struct termios term;
|
||
|
tcgetattr(0, &term);
|
||
|
term.c_lflag |= ICANON | ECHO;
|
||
|
tcsetattr(0, TCSANOW, &term);
|
||
|
}
|
||
|
|
||
|
static uint64_t GetTimeMicroseconds()
|
||
|
{
|
||
|
struct timeval tv;
|
||
|
gettimeofday( &tv, 0 );
|
||
|
return tv.tv_usec + ((uint64_t)(tv.tv_sec)) * 1000000LL;
|
||
|
}
|
||
|
|
||
|
static int is_eofd;
|
||
|
|
||
|
static int ReadKBByte()
|
||
|
{
|
||
|
if( is_eofd ) return 0xffffffff;
|
||
|
char rxchar = 0;
|
||
|
int rread = read(fileno(stdin), (char*)&rxchar, 1);
|
||
|
|
||
|
if( rread > 0 ) // Tricky: getchar can't be used with arrow keys.
|
||
|
return rxchar;
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
static int IsKBHit()
|
||
|
{
|
||
|
if( is_eofd ) return -1;
|
||
|
int byteswaiting;
|
||
|
ioctl(0, FIONREAD, &byteswaiting);
|
||
|
if( !byteswaiting && write( fileno(stdin), 0, 0 ) != 0 ) { is_eofd = 1; return -1; } // Is end-of-file for
|
||
|
return !!byteswaiting;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|