mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-07-26 02:29:51 +02:00
d79382bbfe
* chore: run codespell on source/header files Fixes most reported typos discovered by codespell (while trying to be unopinionated about American vs. British English). * chore: run codespell on build/readme files
607 lines
22 KiB
C
607 lines
22 KiB
C
/* CON1052.C (c)Copyright Jan Jaeger, 2004-2012 */
|
|
/* (C) and others 2013-2023 */
|
|
/* Emulated Console Printer Keyboard on Hercules HMC */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* This module contains device handling functions for integrated */
|
|
/* 1052 and 3215 console printer keyboard devices for the Hercules */
|
|
/* ESA/390 emulator. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#include "hstdinc.h"
|
|
#include "hercules.h"
|
|
#include "devtype.h"
|
|
#include "opcode.h"
|
|
#include "sr.h"
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Tweakable build constants */
|
|
/*-------------------------------------------------------------------*/
|
|
#define BUFLEN_1052 150 /* 1052 Send/Receive buffer */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Forward reference */
|
|
/*-------------------------------------------------------------------*/
|
|
static DEVHND con1052_device_hndinfo;
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Ivan Warren 20040227 */
|
|
/* */
|
|
/* This table is used by channel.c to determine if a CCW code */
|
|
/* is an immediate command or not. */
|
|
/* */
|
|
/* The table is addressed in the DEVHND structure as 'DEVIMM immed' */
|
|
/* */
|
|
/* 0: ("false") Command is *NOT* an immediate command */
|
|
/* 1: ("true") Command *IS* an immediate command */
|
|
/* */
|
|
/* Note: An immediate command is defined as a command which returns */
|
|
/* CE (channel end) during initialization (that is, no data is */
|
|
/* actually transferred). In this case, IL is not indicated for a */
|
|
/* Format 0 or Format 1 CCW when IL Suppression Mode is in effect. */
|
|
/* */
|
|
/*-------------------------------------------------------------------*/
|
|
static BYTE con1052_immed [256] =
|
|
|
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
|
{ 0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0, /* 00 */ // 03, 0B
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 10 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 20 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 30 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 80 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* A0 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* B0 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* C0 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* D0 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* E0 */
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* F0 */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* MinGW (Windows, but *not* MSVC) */
|
|
/*-------------------------------------------------------------------*/
|
|
#if defined( WIN32 ) && !defined( _MSVC_ ) && !defined( HDL_USE_LIBTOOL )
|
|
|
|
SYSBLK *psysblk;
|
|
#define sysblk (*psysblk)
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* CLOSE THE 1052/3215 DEVICE HANDLER */
|
|
/*-------------------------------------------------------------------*/
|
|
static int con1052_close_device( DEVBLK *dev )
|
|
{
|
|
/* If the first character of our command prefix matches
|
|
one of the characters in our list of default command
|
|
prefixes, then mark that command prefix character as
|
|
being unused and once again available for reuse.
|
|
*/
|
|
char* p;
|
|
size_t i;
|
|
|
|
p = memchr( sysblk.cmd_pfxs, dev->filename[0], sysblk.num_pfxs );
|
|
|
|
if (p)
|
|
{
|
|
i = (p - sysblk.cmd_pfxs);
|
|
sysblk.used_pfxs[i] = FALSE;
|
|
}
|
|
|
|
dev->fd = -1; /* device has now been closed */
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* QUERY THE 1052/3215 DEVICE DEFINITION */
|
|
/*-------------------------------------------------------------------*/
|
|
static void con1052_query_device( DEVBLK *dev, char **devclass,
|
|
int buflen, char *buffer )
|
|
{
|
|
char filename[ PATH_MAX + 1 ]; /* full path or just name */
|
|
|
|
ASSERT( IS_INTEGRATED_CONS( dev )); // (sanity check)
|
|
|
|
BEGIN_DEVICE_CLASS_QUERY( "CON", dev, devclass, buflen, buffer );
|
|
|
|
snprintf( buffer, buflen, "*syscons cmdpref '%s' %sprompt IO[%"PRIu64"]",
|
|
filename, dev->prompt1052 ? "" : "no", dev->excps );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* INITIALIZE THE 1052/3215 DEVICE HANDLER */
|
|
/*-------------------------------------------------------------------*/
|
|
static int con1052_init_handler( DEVBLK *dev, int argc, char *argv[] )
|
|
{
|
|
int ac;
|
|
DEVBLK *our_dev, *their_dev;
|
|
char *our_pfx, *their_pfx, *p;
|
|
size_t our_pfxlen, their_pfxlen, shorter_pfxlen, i;
|
|
|
|
/* For re-initialisation, close the existing file, if any */
|
|
if (dev->fd >= 0)
|
|
(dev->hnd->close)( dev );
|
|
|
|
/* reset excp count */
|
|
dev->excps = 0;
|
|
|
|
/* Indicate that this is NOT a console device */
|
|
dev->console = 0;
|
|
|
|
/* Integrated console is always connected */
|
|
dev->connected = 1;
|
|
|
|
/* Set number of sense bytes */
|
|
dev->numsense = 1;
|
|
|
|
/* Initialize device dependent fields */
|
|
dev->keybdrem = 0;
|
|
|
|
/* Set length of console buffer reserving extra room for
|
|
possible newline character and null string terminator.
|
|
*/
|
|
dev->bufsize = BUFLEN_1052 +1 +1;
|
|
|
|
/* Assume we want to prompt */
|
|
dev->prompt1052 = 1;
|
|
|
|
/* Initialize command prefix string to undefined */
|
|
STRLCPY( dev->filename, "" );
|
|
|
|
/* Determine device type. Default to 1052 */
|
|
if (!sscanf( dev->typname, "%hx", &dev->devtype))
|
|
dev->devtype = 0x1052;
|
|
|
|
/* Initialize the device identifier bytes */
|
|
dev->devid[0] = 0xFF;
|
|
dev->devid[1] = dev->devtype >> 8;
|
|
dev->devid[2] = dev->devtype & 0xFF;
|
|
dev->devid[3] = 0x00;
|
|
dev->devid[4] = dev->devtype >> 8;
|
|
dev->devid[5] = dev->devtype & 0xFF;
|
|
dev->devid[6] = 0x00;
|
|
dev->numdevid = 7;
|
|
|
|
/* Process optional arguments */
|
|
for (ac=0; argc > 0; ac++, argc--)
|
|
{
|
|
if (strcasecmp( argv[ac], "noprompt" ) == 0)
|
|
dev->prompt1052 = 0;
|
|
else
|
|
STRLCPY( dev->filename, argv[ac] );
|
|
}
|
|
|
|
/* Set default command prefix if one wasn't specified */
|
|
if (!dev->filename[0])
|
|
{
|
|
/* Locate an unused command prefix */
|
|
p = memchr( sysblk.used_pfxs, 0, sysblk.num_pfxs );
|
|
|
|
if (!p)
|
|
{
|
|
// "%1d:%04X COMM: default command prefixes exhausted"
|
|
WRMSG( HHC01085, "E", LCSS_DEVNUM );
|
|
return -1;
|
|
}
|
|
|
|
i = (p - sysblk.used_pfxs);
|
|
sysblk.used_pfxs[i] = TRUE;
|
|
dev->filename[0] = sysblk.cmd_pfxs[i];
|
|
dev->filename[1] = 0;
|
|
}
|
|
|
|
/* Check if valid command prefix: cannot be a subset or superset
|
|
of any other console printer keyboard device's command prefix.
|
|
*/
|
|
our_dev = dev;
|
|
our_pfx = our_dev->filename;
|
|
our_pfxlen = strlen( our_pfx );
|
|
|
|
for (their_dev = sysblk.firstdev; their_dev; their_dev = their_dev->nextdev)
|
|
{
|
|
if (1
|
|
&& their_dev != our_dev
|
|
&& their_dev->allocated
|
|
&& their_dev->hnd == &con1052_device_hndinfo
|
|
)
|
|
{
|
|
their_pfx = their_dev->filename;
|
|
their_pfxlen = strlen( their_pfx );
|
|
shorter_pfxlen = min( their_pfxlen, our_pfxlen );
|
|
|
|
if (strncmp( our_pfx, their_pfx, shorter_pfxlen ) == 0)
|
|
{
|
|
// "%1d:%04X COMM: device %1d:%04X already using prefix '%s'"
|
|
WRMSG( HHC01086, "E",
|
|
SSID_TO_LCSS( our_dev -> ssid ), our_dev -> devnum,
|
|
SSID_TO_LCSS( their_dev -> ssid ), their_dev -> devnum,
|
|
their_pfx
|
|
);
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If the first character of our command prefix matches
|
|
one of the characters in our list of default command
|
|
prefixes, then mark that command prefix character as
|
|
being used and no longer available for use.
|
|
*/
|
|
p = memchr( sysblk.cmd_pfxs, our_pfx[0], sysblk.num_pfxs );
|
|
|
|
if (p)
|
|
{
|
|
i = (p - sysblk.cmd_pfxs);
|
|
sysblk.used_pfxs[i] = TRUE;
|
|
}
|
|
|
|
/* PROGRAMMING NOTE: it is CRITICAL that we set our file
|
|
descriptor integer to a non-zero value greater than 2
|
|
(even though we'll never use it) in order to force the
|
|
config.c "detach_devblk" function to call our 'close'
|
|
function so we can mark our prefix as being once again
|
|
available for reuse.
|
|
*/
|
|
dev->fd = INTEGRATED_CONS_FD; /* CRITICAL! See above! */
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* CONSOLE PRINTER KEYBOARD PANEL COMMAND FUNCTION */
|
|
/*-------------------------------------------------------------------*/
|
|
static void* con1052_panel_command( char *cmd )
|
|
{
|
|
DEVBLK *dev;
|
|
char *input;
|
|
int i;
|
|
size_t pfxlen;
|
|
|
|
void* (*next_panel_command_handler)( char *cmd );
|
|
|
|
/* Scan device chain looking for integrated console printer keyboard
|
|
devices whose command prefix string (kept in dev->filename field)
|
|
matches the command prefix used in the command that was entered.
|
|
*/
|
|
for (dev = sysblk.firstdev; dev; dev = dev->nextdev)
|
|
{
|
|
if (1
|
|
&& dev->allocated
|
|
&& dev->hnd == &con1052_device_hndinfo
|
|
&& (pfxlen = strlen( dev->filename )) > 0
|
|
&& strncasecmp( cmd, dev->filename, pfxlen ) == 0
|
|
)
|
|
{
|
|
/* Get past command prefix to the actual command */
|
|
input = cmd + pfxlen;
|
|
|
|
/* Echo what they typed to the Hercules console */
|
|
// "'%s' input entered for console %1d:%04X: \"%s\""
|
|
WRMSG( HHC00013, "I", dev->filename, LCSS_DEVNUM, input );
|
|
LOGMSG( "%s\n", input );
|
|
|
|
/* Convert ASCII input to EBCDIC */
|
|
for (i=0; i < dev->bufsize && input[i] != '\0'; i++)
|
|
dev->buf[i] = isprint( (unsigned char)input[i] ) ?
|
|
host_to_guest( input[i] ) : ' ';
|
|
|
|
/* Update number of bytes in keyboard buffer */
|
|
dev->keybdrem = i;
|
|
dev->buflen = i;
|
|
|
|
/* Wakup the channel if it's waiting for input
|
|
or present unsolicited attention interrupt.
|
|
*/
|
|
OBTAIN_DEVLOCK( dev );
|
|
|
|
if (dev->kbwaiters)
|
|
{
|
|
signal_condition( &dev->kbcond );
|
|
RELEASE_DEVLOCK( dev );
|
|
}
|
|
else
|
|
{
|
|
RELEASE_DEVLOCK( dev );
|
|
device_attention( dev, CSW_ATTN );
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/* The entered command wasn't meant for us. Pass it
|
|
on to the next command handler, if there is one.
|
|
*/
|
|
next_panel_command_handler = hdl_next( &con1052_panel_command );
|
|
|
|
if (next_panel_command_handler)
|
|
return next_panel_command_handler( cmd );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* EXECUTE A 1052/3215 CHANNEL COMMAND WORD */
|
|
/*-------------------------------------------------------------------*/
|
|
static void con1052_execute_ccw( DEVBLK *dev, BYTE code, BYTE flags,
|
|
BYTE chained, U32 count, BYTE prevcode, int ccwseq,
|
|
BYTE *iobuf, BYTE *more, BYTE *unitstat, U32 *residual )
|
|
{
|
|
U32 len; /* Length of data */
|
|
U32 num; /* Number of bytes to move */
|
|
BYTE c; /* Print character */
|
|
|
|
UNREFERENCED( chained );
|
|
UNREFERENCED( prevcode );
|
|
UNREFERENCED( ccwseq );
|
|
|
|
/* Unit check with intervention required if no client connected */
|
|
if (dev->connected == 0 && !IS_CCW_SENSE( code ))
|
|
{
|
|
dev->sense[0] = SENSE_IR;
|
|
*unitstat = CSW_UC;
|
|
return;
|
|
}
|
|
|
|
/* Process depending on CCW opcode */
|
|
switch (code) {
|
|
|
|
case 0x01:
|
|
/*---------------------------------------------------------------*/
|
|
/* WRITE, NO CARRIER RETURN */
|
|
/*---------------------------------------------------------------*/
|
|
|
|
case 0x09:
|
|
/*---------------------------------------------------------------*/
|
|
/* WRITE, AUTO CARRIER RETURN */
|
|
/*---------------------------------------------------------------*/
|
|
|
|
/* Calculate number of bytes to write and set residual count */
|
|
num = (count < BUFLEN_1052) ? count : BUFLEN_1052;
|
|
*residual = count - num;
|
|
|
|
/* Translate channel buffer data to ASCII */
|
|
for (len = 0; len < num; len++)
|
|
{
|
|
c = guest_to_host( iobuf[len] );
|
|
if (1
|
|
&& c != 0x0d
|
|
&& c != 0x0a
|
|
&& !isprint((unsigned char)c)
|
|
)
|
|
c = ' ';
|
|
iobuf[len] = c;
|
|
}
|
|
|
|
/* Perform end of record processing if not data-chaining */
|
|
if ((flags & CCW_FLAGS_CD) == 0)
|
|
{
|
|
/* CCW opcode == Write, Auto Carrier Return? */
|
|
if (code == 0x09)
|
|
iobuf[len++] = '\n';
|
|
}
|
|
|
|
/* Append string terminator */
|
|
iobuf[len] = '\0';
|
|
|
|
/* Process multiline messages */
|
|
{
|
|
char* str = (char*) iobuf;
|
|
char* nl;
|
|
|
|
while (str && *str)
|
|
{
|
|
nl = strchr( str, '\n' );
|
|
|
|
if (nl) *nl++ = 0;
|
|
|
|
LOGMSG( "%s%s\n", dev->filename, str );
|
|
|
|
str = nl;
|
|
}
|
|
}
|
|
|
|
/* Return normal status */
|
|
*unitstat = CSW_CE | CSW_DE;
|
|
break;
|
|
|
|
case 0x03:
|
|
/*---------------------------------------------------------------*/
|
|
/* CONTROL NO-OPERATION */
|
|
/*---------------------------------------------------------------*/
|
|
*unitstat = CSW_CE | CSW_DE;
|
|
break;
|
|
|
|
case 0x0A:
|
|
/*---------------------------------------------------------------*/
|
|
/* READ INQUIRY */
|
|
/*---------------------------------------------------------------*/
|
|
|
|
/* Solicit console input if no data in the device buffer */
|
|
if (!dev->keybdrem)
|
|
{
|
|
/* Display prompting message on console if allowed */
|
|
if (dev->prompt1052)
|
|
// "Enter '%s' input for console %1d:%04X"
|
|
WRMSG( HHC00010, "A", dev->filename, LCSS_DEVNUM );
|
|
|
|
OBTAIN_DEVLOCK( dev );
|
|
{
|
|
dev->kbwaiters++;
|
|
wait_condition( &dev->kbcond, &dev->lock );
|
|
dev->kbwaiters--;
|
|
}
|
|
RELEASE_DEVLOCK( dev );
|
|
}
|
|
|
|
/* Calculate number of bytes to move and residual byte count */
|
|
len = dev->keybdrem;
|
|
num = (count < len) ? count : len;
|
|
*residual = count - num;
|
|
if (count < len) *more = 1;
|
|
|
|
/* Copy data from device buffer to channel buffer */
|
|
memcpy( iobuf, dev->buf, num );
|
|
|
|
/* If data chaining is specified, save remaining data */
|
|
if ((flags & CCW_FLAGS_CD) && len > count)
|
|
{
|
|
memmove( dev->buf, dev->buf + count, len - count );
|
|
dev->keybdrem = len - count;
|
|
}
|
|
else
|
|
{
|
|
dev->keybdrem = 0;
|
|
}
|
|
|
|
/* Return normal status */
|
|
*unitstat = CSW_CE | CSW_DE;
|
|
break;
|
|
|
|
case 0x0B:
|
|
/*---------------------------------------------------------------*/
|
|
/* AUDIBLE ALARM */
|
|
/*---------------------------------------------------------------*/
|
|
// "RRR...RING...GGG!\a"
|
|
WRMSG( HHC00009, "I" );
|
|
|
|
// *residual = 0;
|
|
|
|
*unitstat = CSW_CE | CSW_DE;
|
|
break;
|
|
|
|
case 0x04:
|
|
/*---------------------------------------------------------------*/
|
|
/* SENSE */
|
|
/*---------------------------------------------------------------*/
|
|
/* Calculate residual byte count */
|
|
num = (count < dev->numsense) ? count : dev->numsense;
|
|
*residual = count - num;
|
|
if (count < dev->numsense) *more = 1;
|
|
|
|
/* Copy device sense bytes to channel I/O buffer */
|
|
memcpy( iobuf, dev->sense, num );
|
|
|
|
/* Clear the device sense bytes */
|
|
memset( dev->sense, 0, sizeof( dev->sense ));
|
|
|
|
/* Return unit status */
|
|
*unitstat = CSW_CE | CSW_DE;
|
|
break;
|
|
|
|
case 0xE4:
|
|
/*---------------------------------------------------------------*/
|
|
/* SENSE ID */
|
|
/*---------------------------------------------------------------*/
|
|
/* Calculate residual byte count */
|
|
num = (count < dev->numdevid) ? count : dev->numdevid;
|
|
*residual = count - num;
|
|
if (count < dev->numdevid) *more = 1;
|
|
|
|
/* Copy device identifier bytes to channel I/O buffer */
|
|
memcpy( iobuf, dev->devid, num );
|
|
|
|
/* Return unit status */
|
|
*unitstat = CSW_CE | CSW_DE;
|
|
break;
|
|
|
|
default:
|
|
/*---------------------------------------------------------------*/
|
|
/* INVALID OPERATION */
|
|
/*---------------------------------------------------------------*/
|
|
/* Set command reject sense byte, and unit check status */
|
|
dev->sense[0] = SENSE_CR;
|
|
*unitstat = CSW_CE | CSW_DE | CSW_UC;
|
|
|
|
} /* end switch(code) */
|
|
|
|
} /* end function con1052_execute_ccw */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* HERCULES DYNAMIC LOADER (HDL) CONTROL SECTIONS */
|
|
/*-------------------------------------------------------------------*/
|
|
static DEVHND con1052_device_hndinfo =
|
|
{
|
|
&con1052_init_handler, /* Device Initialization */
|
|
&con1052_execute_ccw, /* Device CCW execute */
|
|
&con1052_close_device, /* Device Close */
|
|
&con1052_query_device, /* Device Query */
|
|
NULL, /* Device Extended Query */
|
|
NULL, /* Device Start channel pgm */
|
|
NULL, /* Device End channel pgm */
|
|
NULL, /* Device Resume channel pgm */
|
|
NULL, /* Device Suspend channel pgm */
|
|
NULL, /* Device Halt channel pgm */
|
|
NULL, /* Device Read */
|
|
NULL, /* Device Write */
|
|
NULL, /* Device Query used */
|
|
NULL, /* Device Reserve */
|
|
NULL, /* Device Release */
|
|
NULL, /* Device Attention */
|
|
con1052_immed, /* Immediate CCW Codes */
|
|
NULL, /* Signal Adapter Input */
|
|
NULL, /* Signal Adapter Output */
|
|
NULL, /* Signal Adapter Sync */
|
|
NULL, /* Signal Adapter Output Mult */
|
|
NULL, /* QDIO subsys desc */
|
|
NULL, /* QDIO set subchan ind */
|
|
NULL, /* Hercules suspend */
|
|
NULL /* Hercules resume */
|
|
};
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Libtool static name collision resolution */
|
|
/*-------------------------------------------------------------------*/
|
|
/* Note : lt_dlopen will look for symbol & modulename_LTX_symbol */
|
|
/*-------------------------------------------------------------------*/
|
|
#if defined( HDL_USE_LIBTOOL )
|
|
#define hdl_ddev hdt1052c_LTX_hdl_ddev
|
|
#define hdl_depc hdt1052c_LTX_hdl_depc
|
|
#define hdl_reso hdt1052c_LTX_hdl_reso
|
|
#define hdl_init hdt1052c_LTX_hdl_init
|
|
#define hdl_fini hdt1052c_LTX_hdl_fini
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* HERCULES DYNAMIC LOADER (HDL) CONTROL SECTIONS */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
HDL_DEPENDENCY_SECTION;
|
|
{
|
|
HDL_DEPENDENCY( HERCULES );
|
|
HDL_DEPENDENCY( DEVBLK );
|
|
HDL_DEPENDENCY( SYSBLK );
|
|
}
|
|
END_DEPENDENCY_SECTION
|
|
|
|
#if defined( WIN32 ) && !defined( HDL_USE_LIBTOOL ) && !defined(_MSVC_ )
|
|
#undef sysblk
|
|
HDL_RESOLVER_SECTION;
|
|
{
|
|
HDL_RESOLVE_SYMPTR( psysblk, sysblk );
|
|
HDL_RESOLVE( panel_command );
|
|
}
|
|
END_RESOLVER_SECTION
|
|
#endif
|
|
|
|
HDL_DEVICE_SECTION;
|
|
{
|
|
HDL_DEVICE( 1052-C, con1052_device_hndinfo );
|
|
HDL_DEVICE( 3215-C, con1052_device_hndinfo );
|
|
}
|
|
END_DEVICE_SECTION
|
|
|
|
|
|
HDL_REGISTER_SECTION;
|
|
{
|
|
HDL_REGISTER( panel_command, con1052_panel_command );
|
|
}
|
|
END_REGISTER_SECTION
|