mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-07-26 10:38:47 +02:00
193 lines
6.0 KiB
C
193 lines
6.0 KiB
C
/* HERCLIN.C (C) Copyright Roger Bowler, 2005-2012 */
|
|
/* (C) and others 2013-2021 */
|
|
/* Hercules Interface Control Program */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
/************************************************/
|
|
/* (C) Copyright 2005-2009 Roger Bowler & Others*/
|
|
/* Initial author : Ivan Warren */
|
|
/* */
|
|
/* HERCLIN.C */
|
|
/* */
|
|
/* THIS IS SAMPLE CODE DEMONSTRATING */
|
|
/* THE USE OF THE INITIAL HARDWARE PANEL */
|
|
/* INTERFACE FEATURE. */
|
|
/************************************************/
|
|
|
|
#include "hstdinc.h"
|
|
#include "hercules.h"
|
|
|
|
/**********************************************/
|
|
/* The following function is the LOG callback */
|
|
/* function. It gets called by the engine */
|
|
/* whenever a log message needs to be */
|
|
/* displayed. This function therefore */
|
|
/* might be invoked from a separate thread */
|
|
/**********************************************/
|
|
|
|
bool hercules_has_exited = false;
|
|
|
|
void log_callback( const char* msg, size_t msglen )
|
|
{
|
|
UNREFERENCED( msg );
|
|
|
|
if (!msglen)
|
|
{
|
|
hercules_has_exited = true;
|
|
return;
|
|
}
|
|
|
|
fflush( stdout );
|
|
fwrite( msg, 1, msglen, stdout );
|
|
fflush( stdout );
|
|
fflush( stderr );
|
|
}
|
|
|
|
/**********************************************/
|
|
/* Keyboard thread responsible for reading */
|
|
/* user input from the keyboard. It's a sep- */
|
|
/* arate thread because 'fgets' blocks until */
|
|
/* the user enters a command and presses */
|
|
/* the enter key. */
|
|
/**********************************************/
|
|
|
|
LOCK kb_lock; // keyboard lock
|
|
COND kb_read_cond; // keyboard read requested
|
|
COND kb_data_cond; // keyboard data available
|
|
TID kb_tid; // keyboard thread id
|
|
char *cmdbuf, *cmd; // keyboard variables
|
|
|
|
#define CMDBUFSIZ 1024
|
|
|
|
void* kb_thread( void* argp )
|
|
{
|
|
UNREFERENCED( argp );
|
|
|
|
while (1)
|
|
{
|
|
if ((cmd = fgets( cmdbuf, CMDBUFSIZ, stdin )))
|
|
{
|
|
obtain_lock( &kb_lock );
|
|
{
|
|
/* (remove newline) */
|
|
cmd[ strlen( cmd ) - 1 ] = 0;
|
|
|
|
broadcast_condition( &kb_data_cond );
|
|
wait_condition( &kb_read_cond, &kb_lock );
|
|
}
|
|
release_lock( &kb_lock );
|
|
}
|
|
}
|
|
|
|
UNREACHABLE_CODE( return NULL );
|
|
}
|
|
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
int rc;
|
|
|
|
/*****************************************/
|
|
/* COMMANDHANDLER is the function type */
|
|
/* of the engine's panel command handler */
|
|
/* this MUST be resolved at run time */
|
|
/* since some HDL module might have */
|
|
/* redirected the initial engine function*/
|
|
/*****************************************/
|
|
|
|
COMMANDHANDLER process_command;
|
|
|
|
#if defined( HDL_USE_LIBTOOL )
|
|
/* LTDL Preloaded symbols for HDL using libtool */
|
|
LTDL_SET_PRELOADED_SYMBOLS();
|
|
#endif
|
|
|
|
/******************************************/
|
|
/* Register the 'log_callback' function */
|
|
/* as the log message callback routine */
|
|
/******************************************/
|
|
registerLogCallback( log_callback );
|
|
|
|
/******************************************/
|
|
/* Initialize the HERCULE Engine */
|
|
/******************************************/
|
|
if ((rc = impl( argc, argv )) == 0)
|
|
{
|
|
sysblk.panel_init = 1;
|
|
sysblk.herclin = 1;
|
|
|
|
/******************************************/
|
|
/* Get the command handler function */
|
|
/* This MUST be done after IML */
|
|
/******************************************/
|
|
process_command = getCommandHandler();
|
|
|
|
/******************************************/
|
|
/* Create locks, conditions and buffers */
|
|
/* needed by the keyboard thread... */
|
|
/******************************************/
|
|
|
|
initialize_lock( &kb_lock );
|
|
initialize_condition( &kb_read_cond );
|
|
initialize_condition( &kb_data_cond );
|
|
|
|
cmdbuf = (char*) malloc( CMDBUFSIZ );
|
|
|
|
/******************************************/
|
|
/* Create a worker thread to read from */
|
|
/* the keyboard so we don't block forever */
|
|
/* waiting for keyboard during shutdown. */
|
|
/******************************************/
|
|
|
|
rc = create_thread( &kb_tid, DETACHED,
|
|
kb_thread, NULL, HERCLIN_KB_THREAD );
|
|
if (rc)
|
|
{
|
|
// "Error in function create_thread(): %s"
|
|
WRMSG( HHC00102, "S", strerror( rc ));
|
|
return -1;
|
|
}
|
|
|
|
/******************************************/
|
|
/* Read keyboard, pass to Command Handler */
|
|
/******************************************/
|
|
|
|
obtain_lock( &kb_lock );
|
|
{
|
|
while (!hercules_has_exited)
|
|
{
|
|
/* Request more keyboard data */
|
|
broadcast_condition( &kb_read_cond );
|
|
|
|
/* Wait for data to arrive */
|
|
while
|
|
(1
|
|
&& !hercules_has_exited
|
|
&& timed_wait_condition_relative_usecs
|
|
(
|
|
&kb_data_cond,
|
|
&kb_lock,
|
|
PANEL_REFRESH_RATE_FAST * 1000,
|
|
NULL
|
|
)
|
|
!= 0
|
|
)
|
|
{
|
|
; // (do nothing! keep waiting!)
|
|
}
|
|
|
|
/* Process keyboard data */
|
|
if (!hercules_has_exited)
|
|
process_command( cmd );
|
|
}
|
|
}
|
|
release_lock( &kb_lock );
|
|
|
|
sysblk.panel_init = 0;
|
|
}
|
|
|
|
return rc;
|
|
}
|