CHARON™ CHAPI for Windows Version: 4.
© 2006 - 2012 Stromasys SA Under the copyright laws, this manual and the software described within are intellectual property of Stromasys. This document may be copied or translated for non-profit purposes, provided that the content is not modified and this copyright notice is included in every copy or translation. User Manual for CHARON™ W32, an API based system emulator for 32 bit Windows host systems.
Ownership Notice Stromasys SA owns the rights, including proprietary rights, copyrights, trademarks, and world-wide distribution rights to a methodology for the execution of applications and system software by emulating the original hardware components of a legacy system in software and/or microcode. This methodology is based on a portable software architecture henceforth referred to as CHARON™.
Contents CONTENTS .................................................................................................. IV PREFACE ..................................................................................................... X SUMMARY ................................................................................................... XI THIS MANUAL IS FOR... ........................................................................... XIII CONVENTIONS ......................................................
QBUS ADAPTER BASED ON PCIS3BASE PCI BOARD ............................ 37 RL11/RLV12 ........................................................................................................ 39 TS11/TSV05 ......................................................................................................... 40 VT30-H ................................................................................................................. 42 VT30-TV ...................................................................
4.9.3 Clear bus request ................................................................................................................................ 82 4.9.4 Enable/disable bus request ................................................................................................................. 83 4.9.5 Get interrupt vector .............................................................................................................................. 83 4.9.6 Set interrupt vector ...............
4.21.2 The recommended way for message logging .................................................................................. 103 MESSAGE IDENTIFIERS DEFINITION FOR THE CHAPI DEVICE ... 104 4.21.3 Debug trace ..................................................................................................................................... 104 4.22 Retrieving serial number of the license key ........................................... 105 4.23 Encrypting critical data ...........................
C++ CLASS TEMPLATES .............................................................................. 119 C++ WRAPPER TO WORK WITH BUS REQUESTS ................................ 120 C++ WRAPPERS TO WORK WITH CONFIGURATION OPTIONS...... 123 C++ WRAPPERS TO WORK WITH CRITICAL SECTION..................... 130 C++ WRAPPERS TO WORK WITH THREADS ........................................ 130 CHAPI COMMON CONTAINERS ................................................................ 131 5.1.3 5.2 Library usage examples .
6.3.5 CHAPI disk container......................................................................................................................... 163 6.3.6 CHAPI tape controller ........................................................................................................................ 164 6.3.7 CHAPI tape container ........................................................................................................................ 164 6.4 CHAPI device testing .......................
Preface The PDP11 and VAX systems from Digital Equipment Corporation made a major contribution to the 'boom' of the minicomputer market in the 1980's. Not only provided these systems cost-effective and modular computing blocks, their open architecture allowed many third parties to design new interfaces and other product extensions.
Summary CHAPI system components and libraries − Basic CHAPI interface − General CHAPI support library − Serial I/O CHAPI support library − Parallel I/O CHAPI support library − Disk/Tape I/O CHAPI support library − Industrial I/O CHAPI support library CHAPI based perefpheral devices − Serial line controllers DHV11, DL11, DZ11, LPV11 printer port.
− DPV11 synchronous serial I/O adapter mapped to SEALEVEL-5102S − MRV11 Universal programmable read-only memory − IAV1S-AA(IAV1S-C/CA), IAV1S-B industrial ADC/DAC xii
This manual is for... This manual assumes familiarity with the setup and installation of the CHARON-VAX or CHARON-PDP emulators. It is intended for Resellers and end-users who plan to emulate complex VAX or PDP-11 configurations that might required custom emulator components. Extending the emulated system environment with custom components or modifying existing emulated peripheral components with the CHAPI demands significant software development capabilities.
Conventions The following conventions are used in this manual: Notation Description $ or > The dollar sign or the right angle bracket in interactive examples indicates operating system prompt. User Input Bold monospace type in interactive examples indicates typed user input. Bold monospace type enclosed by angle brackets indicates command parameters and parameter values. Output Monospace type in interactive examples indicates the output the command responds with.
1.CHAPI functionality 1.1 CHAPI overview CHARON-PDP / CHARON-VAX is a hardware abstraction layer to replace multiple architecturally related - legacy systems. The CHAPI functionality is limited to QBUS/UNIBUS An essential part of CHARON-VAX/CHARON-PDP emulators / W32 is the design environment for the CHARON API (CHAPI) through which additional run-time components (in the form of Windows DLLs) can be added to the emulated system.
1.2.1 CHAPI components shared by CHARON-VAX and CHARON-PDP emulators: CHAPI(D).DLL – general CHAPI support library and its debug version; CHAPI_DH11.DLL – full functional CHAPI implementation of DH11/DM11 serial multiplexer with ability to map its ports to: 1) Standard COM port; 2) TCP/IP link; 3) MOXA NPort 5210 port; CHAPI_DHV11.
CHAPI_QBUS.DLL – CHAPI implementation of bus adapter link to external QBUS cage using BCI-2104 bus adapter; CHAPI_S3QBUS.DLL – CHAPI implementation of bus adapter link to external QBUS cage using CESYS PCIS3BASE bus adapter; CHAPI_RLV12.
1.2.2 CHAPI Development libraries CHAPI.LIB – The library to link with in case the components described in the CHAPI_LIB.H header file are used for a particular CHAPI module implementation; it should be used in a release build of a CHAPI device; CHAPID.LIB – The debug version of the CHAPI.LIB library; it should be used in a debug build of a CHAPI device; CHAPI_SERIAL.
digital I/O board and CHAPI_DPV11 mapped to SEALEVEL SYNC SERIAL BOARD 5102S board. 1.3 The CHAPI CHARON utilities 1.3.1 The CHARON CHAPI device creation wizard The CHAPI device creation wizard is designed to simplify the creation of a CHAPI device: it is a sequence of GUI dialogs that leads the designer to a Visual Studio C++ project.
1.5 CHAPI based components provided with CHARON-VAX or CHARON-PDP. CHARON kits contains a number of CHAPI based components that are provided on an 'as is' basis. Some of these components are provided in source code to help a developer to modify or create new CHAPI based devices. The supplied examples are chosen to reflect the aspects of general device using CHAPI, they do not necessarily suggest an optimal implementation for a specific project. 1.5.
It is provided in binary form. The implementation supports the following methods to implement its serial lines: 1. As a standard PC COM port 2. As a TCP/IP port; 3. As a RS232 port on the MOXA Nport 5210 family of Ethernet serial line multiplexers. The implementation is based on the general Serial I/O CHAPI support library (see 5.2). Note: The CHAPI DH11 device cannot be configured using the legacy ‘parameter’ configuration method.
• port=; • application=””; • ip=. If this parameter is present, the line will try to connect to this IP address. If this parameter is not present, the line will accept connections • In case of a standard COM port: • com=, (1, 2, …) Example: load chapi YHA dll=chapi_dh11.
Note: The CHAPI DHV11 device cannot be configured using the legacy ‘parameter’ configuration method. The CHAPI DHV11 device is configured as follows (in this example the logical name for the device is TXA. Note that this name is only valid in this configuration file context, and does not define how the device appears in the OS running on CHARON, which is defined by that OS based on how it recognizes the emulated hardware): load chapi TXA dll=chapi_dhv11.
Example: load chapi TXA dll=chapi_dhv11.dll set TXA address=017760520 vector=0340 trace_level=1 #LINE[0] IS SERVER set TXA line_dll[0]=chapi_serial line_cfg[0]=tcpip set TXA line_is_terminal[0]=true line_param[0]="port=10020 application=txa0.ht" set TXA line_dll[1]=chapi_serial line_cfg[1]=com set TXA line_is_terminal[1]=true line_param[1]="com=1" set TXA line_dll[2]=chapi_serial line_cfg[2]=moxa set TXA line_is_terminal[2]=true line_param[2]="ip=192.168.127.
set set set set set set set TT1 TT1 TT1 TT1 TT1 TT1 TT1 rts= mode=”” breaken= erroren= char_len= stop_len= parity=”” Where : • line_dll – The DLL file name to load CHAPI serial line port from. If omitted CHAPI_SERIAL.DLL will be used by default; • line_cfg – The name of the port to load.
• baudselen – must be true to enable OS baud rate selection • dtr – must be true to force the DTR signal to ON. • rts – must be true to force the RTS signal to ON. • mode – Either ‘E’ or ‘F’ to select DLV11-E or DLV11-F functionality. • breaken – must be true to enable break generation • erroren – must be true to enable RX error notification • char_len – the byte length of transmitted and received characters.
set set set set TT1 TT1 TT1 TT1 erroren=true char_len=8 stop_len=1 parity=”none” # DLV11-E connected to TCPIP, line is server load chapi TT1 dll=chapi_dlv11.dll set TT1 address=017760010 vector=0310 trace_level=1 set TT1 line_dll=chapi_serial set TT1 line_cfg=tcpip set TT1 line_is_terminal=true set TT1 line_param=”port=10020 application=term.ht” set TT1 mode=”e” # DLV11-E connected to TCPIP, line is client load chapi TT1 dll=chapi_dlv11.
• line_dll – The DLL file name to load CHAPI serial line port from, must be chapi_serial only. If omitted CHAPI_SERIAL.DLL will be used by default; • trace_level – Debug trace level (0 - 10), 0 for NO traces or 10 for MAX traces. If omitted zero will be used by default; • line_cfg – The name of the port to load. Must be: • seasync – a SEALEVEL PCI 5102S board port If the line_cfg parameter is omitted, the port name seasync will be used. • bus_no - SEALEVEL 5102 PCI bus number.
# RS-422(530), provide clock at 2.4 kHz, NO debug traces load chapi UFA dll=chapi_dpv11.dll set UFA line_cfg=seasync set UFA bus_no=1 device_no=7 function_no=0 set UFA tx_clock_direction="out" set UFA rx_clock_direction="out" set UFA interface_mode="rs530_422" set UFA trace_level=0 set UFA clock_rate=2400 # DPV11, use SEALEVEL 5102S at PCI 1/7/0, # RS-232,NO debug traces, accept external clock load chapi UFA dll=chapi_dpv11.
Where: • port_dll[0] – is the name of DLL library from where the digital IO port for DR11(C)/DRV11 device emulation is loaded; • port[0] – name of digital IO port for DR11(C)/DRV11 device emulation; • bus_no, device_no, function_no - SENSORAY 621 PCI card location description. These numbers should be gathered from the Windows hardware wizard after Sensoray 621 PCI board installation.
• port_dll – is the name of DLL library from where the DRV11-WA device emulation is loaded. If this parameter is omitted, CHAPI_DRV11WA_621_PORT.DLL is used as default; • port_name – the name of DRV-11WA replacement adapter connection module to load from the specified DLL library. If this parameter is omitted, 'drv11wa_621' will be used as default; • bus_no, device_no, function_no - SENSORAY 621 PCI card location description.
• adapter_dll – is the name of DLL library from where the DRV11-WA device emulation is loaded. If this parameter is omitted, chapi_hw.DLL is used as default; • adapter_name – the name of DRV-11WA replacement adapter connection module to load from the specified DLL library.
Where : • port_dll – The DLL file name to load CHAPI ADC port from. If omitted CHAPI_INDIO.DLL will be used by default; • trace_level – Debug trace level (0 - 10), 0 for NO traces or 10 for MAX traces. If omitted zero will be used by default; • port_cfg – The name of the port to load. Can be: • 2600 – a SENSORAY 2601/2608 Ethernet ADC/DAC board port If the port_cfg parameter is omitted, the port name “2600” will be used.
IAV1S-B The CHAPI IAV1S-B QBUS devices are implemented with CHAPI_IAV1S_B.DLL and use CHAPI_INDIO.DLL and CHAPI.DLL for its implementation. The DLL is available in binary only. This implementation can map its DAC lines to SENSORAY 2601, 2608 ADC/DAC Ethernet boards. This device cannot be configured using the legacy ‘parameter’ configuration method. The configuration options are as follows: load chapi DAC dll=chapi_iav1s_b.
set DAC port_param[0]="10.10.10.2" port_offset[0]=8 MRV11 The CHAPI MRV11 QBUS/UNIBUS device are implemented with CHAPI_MRV11.DLL and use CHAPI.DLL for its implementation. MRV11 is universal programmable read-only memory.
6 12 24 48 96 196 8 16 32 64 128 256 10 20 40 80 160 320 12 24 48 96 192 384 14 28 56 112 224 448 16 32 64 128 256 512 – enable/disable window maping mode (by default disable (false)). • window_mode • window_address • bootstrap • bootstrap _address – window maping_address (by default equals 0160000). – enable/disable bootstrap mode (by default is enable (true)). – bootstrap_address (by default equals 0).
external Qbus is visible to the emulated CPU and can be used in a combination with the emulated devices. This example is based on the BCI-2104 Qbus adapter board from The Logical Company. Note that the BCI-2104 is end of life as it does not meet the RoHS environmental requirements, and this implementation is only provided as a demonstration example. The CHAPI_QBUS device is provided in binary form.
s3qbus_design.bin. This device is implemented as an interconnection adapter to connect the emulated Qbus to an external physical Qbus by means of an adapter board based on the FPGA with our custom design. With such connection, the hardware on the external Qbus is visible to the emulated CPU and can be used in a combination with the emulated devices. The CHAPI_S3QBUS device is provided in binary form. To use PCIS3BASE adapter you have to install s3qbus_ppt.sys driver from the CHARON kit.
RL11/RLV12 CHAPI RL11 UNIBUS / RLV12 QBUS devices are implemented in CHAPI_RLV12.DLL library and use CHAPI_STORAGE.DLL and CHAPI.DLL libraries. It is provided only in binaries and allows mapping its disk drive to disk image file. CHAPI RLV12 device can control up to 4 disk drives (0, 1, 2 and 3). CHAPI RLV12 device can be configured by means of user defined configuration options as follows: load chapi DLA dll=chapi_rlv12.
Example: # # CHAPI RL01/RL02 disk controller # load chapi DLA dll=chapi_rlv12.dll trace_level=1 # Disk drive[0] configuration set DLA disk_dll[0]="chapi_storage" set DLA disk_cfg[0]="file" set DLA disk_param[0]="somefile_0.vdisk" # Disk drive[1] configuration set DLA disk_dll[1]="chapi_storage" set DLA disk_cfg[1]="phys" set DLA disk_param[1]=" \\.
load chapi MSA dll=chapi_tsv05.dll set MSA address=
vector= trace_level= set MSA tape_dll[0]= set MSA tape_cfg[0]= set MSA tape_param[0]=”” set MSA extended_mode[0]= set MSA use_wtm_trick[0]= Where : - tape_dll[0] – DLL file name from where to load the CHAPI tape transport emulation.#set #set #set #set tape MSA0 MSA0 MSA0 transport as a tape image file on the host system tape_dll[0]=chapi_storage tape_cfg[0]=mtd tape_param[0]="somefile.mtd" #set tape transport to connect to a physical SCSI device #set MSA0 tape_dll[0]=chapi_storage #set MSA0 tape_cfg[0]=scsi #set MSA0 tape_param[0]= \\.\SCSI1:0:1 #to avoid RSX TS11/TSV05 driver WTM timeouts #set MSA0 use_wtm_trick[0]=true #set tape transport to a Windows tape drive with dsriver installed.
VT30-TV The CHAPI VT30-TV implemented in vt30-tv.exe. The VT30-TV virtual color television monitor should be connected to a PDP-11 via VT30-H. It shoud be started with desktop color quality equally 8-bit, 16-bit or 32-bit. The CHAPI VT30-TV can be started by means of user defined configuration options as follows: vt30-tv.exe –-address= --port= -log= --trace_level= • address – IP address for connection to VT30-H.
- adapter_dll – is the name of DLL library to load a particular low level bus adapter implementation from. If this parameter is omitted, 'chapi_hw' will be used as default; - adapter_name – is the name of the specific low level bus adapter implementation to load from the specified DLL library. If this parameter is omitted, 'bci' will be used as default; - adapter_instance – is the instance number of the adapter to use. This parameter is relevant when multiple adapters are installed.
load chapi LPA dll=lpv11.dll address=
vector= trace_level= set LPA host=”” port= application=”” file=”” Where: - host - is a host name or IP addres. If this parameter is omitted, localhost is used as defualt value; - port - is the port number to connect to on the specified host; - application – The name of application to start.2.CHAPI programming concepts 2.1 Overview The CHAPI interface provides the ability to load dynamically (at run-time, during the configuration phase) additional emulator components that implement customer specific devices (for QBUS and UNIBUS in the version discussed in this release). The CHAPI architecture defines a programming interface of communication between such a loadable component and the core of CHARON.
The name of the .DLL module is constructed as follows: .DLL where represents the name of the loadable component. The use of delimiting characters in (spaces, tabs, and other “invisible” characters) is not allowed. In case when component is already implemented in CHARON core and has the name like .DLL but customer wants to create its own implementation, the following naming convention should be used: CHAPI_.DLL 2.
__declspec(dllexport) void * __cdecl _INIT (const chapi_in * ci, chapi_out * co, const char * instance_name); where represents the name of the loadable component (see also “Loadable component naming conventions” above). Note that the name of the initialization routine must be converted to upper case. For example, the loadable module called dl11.
The loadable component shall create its own contexts (if any) in its initialization routine, just before confirming the creation of a new device instance. The loadable component shall fill all required fields of the provided descriptor of the chapi_out communication context with their respective values. The loadable component can store the data path to both the chapi_in and the chapi_out descriptors provided to the component by the CHARON core.
processing such an operation as soon as possible. Note that the CHARON can run several CPU emulation threads. • Setup bus requests. Such an operation is only initiated by CHARON core with loadable device as a target. CHARON core notify loadable component that it is a right time to setup bus requests, i.e. connect them to the bus for service. • Set/initiate the interrupt on the bus. Such an operation is only initiated by the device instance.
transactions initiated by the CHARON core are processed by routines specified in the chapi_out descriptor, and transactions initiated by the device instance are processed by routines specified in the chapi_in descriptor. This is why a device instance must store the data path to at least the chapi_in descriptor. Both CHARON and the loadable component are allowed to omit (i.e. set to 0) some or all entry points in the chapi_in and the chapi_out descriptors respectively.
3.The CHAPI communication context descriptors The part covers the details of the communication context descriptors and the component initialization process. 3.1 The CHAPI_IN communication context descriptor The chapi_in descriptor contains entry points to routines provided by the CHARON core, as well as base address of control and status registers (CSRs) and base interrupt vector, which might be specified in the configuration file (see below).
// Configuration option processing calls __chapi_add_config_option_p add_config_option; __chapi_set_option_value_p set_option_value; __chapi_undo_option_value_p undo_option_value; __chapi_commit_option_value_p commit_option_value; __chapi_is_option_value_specified_p is_option_value_specified; __chapi_is_option_value_changed_p is_option_value_changed; __chapi_option_value_change_ack_p option_value_change_ack; // Bus adapter calls // NOTE: THIS IS CHARON DEEP INTEGRATION __chapi_intercept_bus_address_space_p
__chapi_get_chapi_major_version_p get_chapi_major_version; __chapi_get_chapi_minor_version_p get_chapi_minor_version; // I/O spaces processing extension __chapi_connect_io_space_procedure_p connect_io_space; __chapi_disconnect_io_space_procedure_p disconnect_io_space; // // All new methods/data have to be added to the end of this structure, otherwise // all customer chapi devices have to be rebuilt with the new header file!!! // } chapi_in; where: #if defined(_MSC_VER) #define CHAPI __cdecl #if defined(__c
(const struct __chapi_in * ci, unsigned long delay, __chapi_sst_handler_p fun, void * arg1, int arg2); //----------------------------------------------------------------------------// IRQ/BRQ relative stuff. // typedef int (CHAPI * __chapi_irq_handler_p) (void * arg1, int arg2); #if !defined(irq_handler) #define irq_handler __chapi_irq_handler_p #endif // !defined(irq_handler) // // Obsolete way to handle IRQ - left only to support old applications.
(const struct __chapi_in * ci, brq_handle_t brq_handle); typedef bool (CHAPI * __chapi_get_attention_objects_p) (const struct __chapi_in * ci, brq_handle_t brq_handle, int cpu_no, volatile unsigned long *& attention_object, unsigned long & attention_value); typedef bool (CHAPI * __chapi_get_brq_objects_p) (const struct __chapi_in * ci, brq_handle_t brq_handle, int cpu_no, volatile unsigned long *& brq_object, unsigned long & brq_mask); typedef int (CHAPI * __chapi_get_vector_p) (const struct __chapi_in * ci
typedef bool (CHAPI * __chapi_get_license_no_procedure_p) (const struct __chapi_in * ci, unsigned int *license_serial_no); typedef void (CHAPI * __chapi_decrypt_data_block_procedure_p) (const struct __chapi_in * ci, void * buf, unsigned int len); typedef void (CHAPI * __chapi_encrypt_data_block_procedure_p) (const struct __chapi_in * ci, void * buf, unsigned int len); //----------------------------------------------------------------------------// Message logging / debugging routines // // Possible types of
DEVICE_ID_LPV11, DEVICE_ID_SDZV11, DEVICE_ID_DH11, DEVICE_ID_VT30H, DEVICE_ID_MRV11, DEVICE_ID_DPV11, DEVICE_ID_IAV1S_AA, DEVICE_ID_IAV1S_B, DEVICE_ID_INDIO, // // // // // // // // // CHAPI LP11/LPV11 device implementation CHAPI_SHELL_DZV11 CHAPI DH11 devices implementation CHAPI VT30-H devices implementation CHAPI MRV11-C(D) devices implementation CHAPI DPV11 devices implementation CHAPI IAV1S-AA(-CA) devices implementation CHAPI IAV1S-B devices implementation CHAPI industrial IO implementation }; // G
typedef bool (CHAPI * __chapi_is_option_value_changed_p) (const struct __chapi_in * ci, const char *opt_name, int opt_val_idx); typedef void (CHAPI * __chapi_option_value_change_ack_p) (const struct __chapi_in * ci, const char *opt_name, int opt_val_idx); typedef void (CHAPI * __chapi_enable_option_value_p) (const struct __chapi_in * ci, const char *opt_name, int opt_val_idx, bool force); typedef void (CHAPI * __chapi_freeze_option_value_p) (const struct __chapi_in * ci, const char *opt_name, int opt_val_id
typedef bool (CHAPI * __chapi_intercept_bus_address_space_p) (const struct __chapi_in * ci); typedef void (CHAPI * __chapi_release_bus_address_space_p) (const struct __chapi_in * ci); typedef unsigned int (CHAPI * __chapi_get_configured_ram_size_p) (const struct __chapi_in * ci); typedef unsigned int (CHAPI * __chapi_get_ram_segment_p) (const struct __chapi_in * ci, int n_of_segment, unsigned int &addr, char * &base); typedef void (CHAPI * __chapi_read_bus_timeout_p) (const struct __chapi_in * ci); typedef
The base_b_address field contains the starting bus address of the device instance I/O region. Usually it is an address of the device’s control and status register (CSR). The CHARON core provides a value in this field upon completion loading the configuration. Initially it is set to 0. The CHAPI allows the user to override this value with configuration parameters (see below). The base_i_vector field contains the starting interrupt vector address, assigned to the device.
The clear_bus_request field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The enable_bus_request field contains an entry point to the corresponding routine.
The write_mem field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The create_io_space field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine.
The debug_trace field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The add_config_option field contains an entry point to the corresponding routine.
The release_bus_address_space field contains an entry point to the corresponding routine. It could require Stromasys consulting. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The get_configured_ram_size field contains an entry point to the corresponding routine.
routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The translate_for_dma field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field.
initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The get_hardware_name field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field.
initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field. The disconnect_io_space field contains an entry point to the corresponding routine. The CHARON core provides a value in this field before calling the loadable component initialization routine. Initially set to 0. Later, but before calling the initialization routine, the CHARON core is allowed to put a non-zero value into the field.
// all customer chapi devices have to be rebuilt with the new header file!!! // } chapi_out; where: #if !defined(__chapi_out_context_p) typedef void * __chapi_out_context_p; #endif // !defined(__chapi_out_context_p) typedef void (CHAPI * __chapi_start_procedure_p) (const struct __chapi_out * co); typedef void (CHAPI * __chapi_stop_procedure_p) (const struct __chapi_out * co); typedef void (CHAPI * __chapi_reset_procedure_p) (const struct __chapi_out * co); typedef int (CHAPI * __chapi_read_procedure_p) (co
the request to confirm the creation of a device (i.e. in the corresponding _INIT routine). The combination of the base_b_address and b_address_range shall meet the following two requirements: • The length of address range must be a power of two. Or more formally: (b_address_range & (b_address_range - 1)) == 0 • The address range shall be naturally aligned. Which means that the base_b_address shall be aligned to a boundary that is a multiple of b_address_range.
The read field contains an entry point to the corresponding routine. This field is optional. The loadable component provides a value in this field when processing the request to confirm the creation of a device (i.e. in the corresponding _INIT routine). The mapping_register_updated field contains an entry point to the corresponding routine. Using this function could require Stromasys consulting. This field is optional.
3.3 Initialization steps When the structure of the communication contexts is available, it is time to present more information about the component initialization process. The initialization steps are as follows: 1. As soon as the CHARON core has finished processing the load command, it creates the necessary internal structures representing the device and allocates resources for both the chapi_in and the chapi_out communication context descriptors. 2.
• Procedure identified by entry point connect_bus_request in the chapi_in communication context descriptor shall be invoked from the routine identified by setup_bus_requests entry in chapi_out communication context descriptor. • All the procedures identified by entry points stored in the create_io_space and destroy_io_space fields of a chapi_in communication context descriptor shall be invoked in the same execution context.
• Procedure identified by the entry point stored in the set_configuration_ex field of a chapi_out communication context is called each time when one of the options added by the loadable component using procedure specified by the entry point add_config_option of a chapi_in communication context is modified in the CHARON configuration file. • Any procedure call does not change the execution context. • Each thread has its own execution context.
4.CHAPI operation 4.1 Reading the device control and status register The operation of reading a device control and status register belongs to the class of operations previously called “Access to device control and status registers”. The CHARON core initiates such an operation. More precisely, one of the CPU instruction interpretation threads is the initiator. The device is considered to be a target of the operation.
In order to perform the operation, the initiator invokes a routine identified by the create_io_space field of the chapi_in descriptor. The initiator is to provide the initial bus location of the I/O space in the addr and the len arguments. The combination of the addr and the len shall meet the following requirements: The length of address range indicated by the len must be a power of two. Or more formally: (len & (len - 1)) == 0 The address range shall be naturally aligned.
In order to perform the operation, the initiator invokes a routine identified by the destroy_io_space field of the chapi_in descriptor. The initiator is to provide an I/O space identifier in the sid argument. The procedure is invoked as follows: io_space_id_t sid = …; const chapi_in * ci = …; if (ci->destroy_io_space) { ci->destroy_io_space(ci, sid); } The example above shows that the CHARON core is not obliged to support the indicated operation.
space identifier returned in the previous call to create_io_space procedure (see above), and the chapi_in descriptor. 4.6 Disconnecting I/O space The operation of disconnecting (additional) I/O space belongs to the class of operations previously called “Access to device control and status registers”. Such an operation is initiated by the device instance. The CHARON core is defined as a target of the operation.
• The address range shall be naturally aligned. Which means that the addr shall be aligned to a boundary that is multiple of the len. Or more formally: (addr + (len - 1)) == (addr | (len - 1)) The procedure is invoked as follows: io_space_id_t sid = …; const chapi_in * ci = …; if (ci->connect_io_space) { ci->connect_io_space(ci, sid, addr, len); } The example above shows that the CHARON core is not obliged to support the indicated operation.
defined as the target of the operation. It is the task of the CPU instruction interpretation thread to respond to the operation of removing the bus interrupt request. To perform the operation, the initiator invokes a routine identified by the clear_irq field of the chapi_in descriptor. The initiator shall indicate through the vec parameter the vector of the interrupt requests to clear. The target shall clear all the interrupt requests previously originated by the initiator through the vector supplied.
4.9 The recommended way to process interrupts This methods described in this section are the recommended way to process interrupts in a CHAPI implementation. They interact more efficiently with the CHARON kernel. See section (5.1) for description of the appropriate C++ wrapper for that part of CHAPI. 4.9.1 Connect bus request to the bus Connecting a bus request to the bus belongs to the “Request for bus interrupt” group of operations.
The example above shows that the CHARON core is not obliged to support the indicated operation. It also indicates why the device instance should retain the chapi_in descriptor. 4.9.2 Set bus request The operation of setting a bus request belongs to the group of operations previously called “Request for bus interrupt”. Such an operation is initiated by the device instance when it is in execution context synchronized to the CPU instruction interpretation thread.
The example above shows that the CHARON core is not obliged to support the indicated operation. It also indicates why the device instance should remember the chapi_in descriptor. 4.9.4 Enable/disable bus request The operation of enabling/disabling a bus request belongs to the group of operations previously called “Request for bus interrupt”. Such an operation is initiated by the device instance and CHARON core is defined as the target of the operation.
// acknowledge routine which should return correct interrupt vector // to be used by the bus server… int brq_ack(void *dev_inst, int arg2) { my_dev_t *dev = (my_dev_t*)dev_inst; if (dev->ci->get_vector) { return dev->ci->get_vector(dev->ci, dev->vector); } else { return dev->vector; } } The example above shows that the CHARON core is not obliged to support the indicated operation. It also indicates why the device instance should remember the chapi_in descriptor. 4.9.
In order to perform the operation, the initiator invokes a routine identified by the set_bus_request_affinity field of the chapi_in descriptor supplying in the parameter brq_handle the identifier of bus request to set affinity mask for and in the parameter mask the affinity mask to set. Affinity mask is a bit mask where each particular bit is designated to particular emulated CPU – lowest bit to the first CPU and so on.
if (ci->set_affinity_callback) { ci->set_affinity_callback (ci, brq_handle, sa_procedure, , ); } The example above shows that the CHARON core is not obliged to support the indicated operation. It also indicates why the device instance should remember the chapi_in descriptor. 4.9.
In order to perform the operation, the initiator invokes a routine identified by the get_attention_objects field of the chapi_in descriptor supplying in the parameter brq_handle the identifier of bus request to get attention objects for, int the parameter cpu_no the number of CPU which attention objects should be retrieved, in the parameter attention_object the pointer which will be updated with the pointer to attention object and in the parameter attention_value the reference where attention value will be
// Failure – report error message here } } // Set bus request and interrupt bus server (CPU) to process it if(attention_object && brq_object) { *brq_object |= brq_mask; *attention_object = attention_value; } … // Clear bus request as follows if(brq_object) { *brq_object &= ~brq_mask; } The example above shows that the CHARON core is not obliged to support the indicated operations. It also indicates why the device instance should remember the chapi_in descriptor. 4.9.
} The example above shows that the device is not obliged to support the indicated operation. Which means that it is allowed to supply 0 for the brq_ack parameter when connecting a bus interrupt to the bus through the connect_bus_request entry point of the chapi_in descriptor. Note that the CHAPI defines an additional argument, supplied through the arg1 and the arg2 parameters, to help the target dispatching requests.
target of the operation. Really it does one or several memcpy to CHARON core from provided buffer. To perform the operation, the initiator invokes a routine identified by the write_mem field of the chapi_in descriptor. The initiator provides in the addr parameter a starting bus address of the memory region to write to, in the len parameter the length of transaction (length of transfer), and in the buf parameter the address of private buffer to transfer from.
To perform the operation, the initiator invokes a routine identified by the fun argument previously supplied in the corresponding request for synchronizing execution to the CPU instruction interpretation thread(s). The initiator provides in the arg1 and the arg2 arguments additional parameters previously supplied together with the fun argument requesting for synchronizing execution to the CPU instruction interpretation thread(s).
4.15 Delayed synchronized invocation The operation of delayed invocation is part of the class of operations called “Synchronization request acknowledge”. The CHARON core initiates such an operation. The device instance is defined as the target of the operation. In order to perform the operation, the initiator invokes a routine identified by the fun argument - previously supplied in the corresponding request - delaying synchronized (with the CPU instruction interpretation thread) execution.
4.17 Processing a bus power-down condition Handling the bus power-down condition belongs to the class of operations called “Request for processing bus power events”.. The CHARON core initiates such an operation when “powering” down the configured node. In order to perform the operation, the initiator invokes a routine identified by the stop field of the chapi_out descriptor.
To perform the operation, the initiator invokes a routine identified by the add_config_option field of the chapi_in descriptor.
… const chapi_in * ci = …; if (ci->set_option_value) { my_int_opt = 10; if(ci->set_option_value(ci, “int_opt”, 0, &my_int_opt)) { // Ok, new option value is set. It is usually used to set defaults when no values is // specified in configuration file. … } my_bool_opt[1] = true; if(ci->set_option_value(ci, “bool_opt”, 1, &my_bool_opt[1])) { // Ok, new option value is set for the second value of // ‘bool_opt’ option. It is usually used to set defaults when // no values is specified in configuration file.
} } The example above shows that the CHARON core is not obliged to support the indicated operation. It indicates why the device instance must remember the chapi_in descriptor. 4.19.4 Committing last change of configuration option value Committing option value belongs to the “A request to process loadable component defined configuration options” class of operations. Such an operation is initiated by the device instance. The CHARON core is defined as a target of the operation.
opt_name parameter the name of configuration option to check and in the opt_val_idx the index of option value to check (from 0 to opt_vals_count - 1).
// Check / commit values for(int idx = 0; idx < 3; idx++) { if(!ci->is_option_value_changed(ci, “bool_opt”, idx)) { // Need to commit in order to see the change in // internal option buffer if(ci->commit_option_value) { ci->commit_option_value(ci, “bool_opt”, idx); } if(ci->option_value_change_ack) { ci->option_value_change_ack(ci, “bool_opt”, idx); } } } } The example above shows that the CHARON core is not obliged to support the indicated operation.
To perform the operation, the initiator invokes a routine identified by the set_and_disable_option_value field of the chapi_in descriptor. The initiator provides in the opt_name parameter the name of configuration option to set the value for, in the opt_val_idx parameter the index of option value to set value for (from 0 to opt_vals_count - 1) and value to set in the val parameter. See invocation example in the chapter 4.19.
4.19.10 Freezing option value Freezing configuration option value belongs to the “A request to process loadable component defined configuration options” class of operations. Such an operation is initiated by the device instance. The CHARON core is defined as a target of the operation. This operation makes specified option value access level readonly. To perform the operation, the initiator invokes a routine identified by the freeze_option_value field of the chapi_in descriptor.
// Disable all option values for the “bool_opt” for(int idx = 0; idx < 3; idx++) { ci->disable_option_value(ci, “bool_opt”, idx); } } The example shows that the CHARON core is not obliged to support the indicated operation. It indicates why the device instance must remember the chapi_in descriptor. 4.19.12 Chacking if option value is hidden Checking if configuration option value is hiodden belongs to the “A request to process loadable component defined configuration options” class of operations.
device defined configuration options. Both ways are described below but the new one is preferable. 4.20.1 The legacy way of changing the configuration The legacy way of changing the configuration belongs to the class of operations called “Request for changing the configuration”. The CHARON core initiates such an operation when loading the configuration.
that one of its configuration options are changed and should be processed somehow (see 4.19.2 for examples). The procedure is invoked as follows: const chapi_out * co = …; if (co->set_configuration_ex) { co->set_configuration_ex(co); } The example above shows that the device is not obliged to support the indicated operation. 4.21 Message logging The legacy way to log messages has been preserved for compatibility reasons. The new method has two options to handle debug trace and messaging. 4.21.
define should be passed there), in the line parameter the line of code where the message is logged from (__LINE__ define should be passed there), in the log_msg_id parameter the identifier of the message to log and in the fmt parameter the format string like in printf C runtime call and variable number of parameters to be used in accordance with the fmt parameter.
CHARON enables the component that logs debug trace messages in the emulator’s log file. Both the CHARON core and the loadable component may initiate such an operation, but only the emulator can be a target. To perform the operation, the initiator invokes a routine identified by the debug_trace field of the chapi_in descriptor.
The example above shows that the CHARON core is not obliged to support the indicated operation. It also shows why the loadable component instance must retain the chapi_in descriptor. 4.23 Encrypting critical data The operation of encrypting protected data belongs to the class of operations called “Protection and license verification”. The CHARON core enables the component encrypting critical data.
4.25 Intercept bus address space (CHARON deep integration) The operation of intercepting bus address space belongs to the class of operations called “Bus adapter support requests”, Using this function could require Stromasys consulting. Such an operation is initiated by the device instance. The CHARON core is defined as a target of the operation. This operation is commonly used in bus adapter’s implementation when it is necessary to intercept the whole address space of particular bus.
In order to perform the operation, the initiator invokes a routine identified by the get_configured_ram_size field of the chapi_in descriptor. The procedure is invoked as follows: const chapi_in * ci = …; if (ci->get_configured_ram_size) { ci-> get_configured_ram_size (ci); } The example above shows that the CHARON core is not obliged to support the indicated operation. It also shows why the loadable component instance must retain the chapi_in descriptor. 4.
The example above shows that the CHARON core is not obliged to support the indicated operation. It also shows why the loadable component instance must retain the chapi_in descriptor. 4.29 Translate emulator’s memory for DMA (CHARON deep integration) The operation of translating emulator’s memory for DMA belongs to the class of operations called “Replacement hardware support requests”, Using this function could require Stromasys consulting. Such an operation is initiated by the device instance.
requests” ”, Using this function could require Stromasys consulting. They are initiated by the device instance. The CHARON core is defined as a target of these operations. Particular event specific details are provided in chapters below. 4.30.1 read bus timeout In order to perform the operation, the initiator invokes a routine identified by the read_bus_timeout field of the chapi_in descriptor.
4.31 Update of bus mapping registers (CHARON deep integration) Update of bus mapping register belongs to the class of operations called “Replacement hardware support requests” ”, Using this function could require Stromasys consulting. The CHARON core initiates such an operation when particular bus mapping register is updated. To perform the operation, the initiator invokes a routine identified by the mapping_register_updated field of the chapi_out descriptor.
4.33 Get bus address range The operation of getting bus address range belongs to the class of operations called “A request for changing the configuration and support requests”. Such an operation is initiated by the CHARON core. The device instance is defined as a target of the operation. This operation is commonly used by devices which implementation is almost but not exactly the same for different bus types (QBUS/UNIBUS) – it is possible to inform CHARON core about particular bus register window size.
4.34.2 Getting running hardware model string The operation of getting running hardware model string belongs to the class of operations called “Versioning information support requests”. Such an operation is initiated by the device instance. The CHARON core is defined as a target of the operation. This operation can be used when CHAPI device need to use running hardware model string somehow, e.g. to check that the running model is accepted for emulated device.
In order to perform the operation, the initiator invokes a routine identified by the get_product_copyright field of the chapi_in descriptor. The procedure should be invoked like follows from device instance: char *prod_copy_str; … if(ci && ci->get_product_copyright) { prod_copy_str = ci->get_product_copyright(ci); } else { // No valid communication context – issue error message if necessary prod_copy_str = 0; } 4.34.
can be used when CHAPI device need to use product minor number somehow, e.g. to check product version to be greater than something. In order to perform the operation, the initiator invokes a routine identified by the get_product_minor_version field of the chapi_in descriptor. Procedure invocation example will be given later. 4.34.8 Getting product build number The operation of getting product build version number belongs to the class of operations called “Versioning information support requests”.
In order to perform the operation, the initiator invokes a routine identified by the get_chapi_major_version field of the chapi_in descriptor. Procedure invocation example will be given later. 4.34.10 Getting CHAPI minor version number The operation of getting chapi minor version number belongs to the class of operations called “Versioning information support requests”. Such an operation is initiated by the device instance. The CHARON core is defined as a target of the operation.
5.CHAPI support libraries Note: While using any of mentioned below libraries be sure that correspondent DLL files are in the same location as CHAPI device DLL file and emulator executable or the path to these DLL files are added to the system PATH environment variable. 5.1 General CHAPI support library 5.1.1 Library files General CHAPI support library consists of: 1) Header file which contains all definitions – chapi_lib.h; 2) Library files to link with in order to use the library – release chapi.
typedef volatile udword_t * volatile_udword_lp_t; // Some typedef typedef typedef typedef additional types using in chapi library unsigned int chapi_timeout_t; unsigned long chapi_proc_t; HANDLE chapi_handle_t; HANDLE chapi_event_t; Register access functions word_t write_byte(int adr, byte_t byte, word_t word) Where, adr - is the address to write byte to; byte - data to write to specified address; word - word value to write data to; This function is used to store specified byte properly in specified
This function is used to read value from specified word register using specified addressing mode (word or byte). Properly read byte or word is returned as a result of this call.
… protected: … private: … }; After that it is possible to link objects of my_data_t class together in bi-directional list as follows: … my_data_t *list_of_data = 0; … new_data *my_data_t = new my_data_t(&list_of_data); C++ wrapper to work with bus requests CHAPI protocol part relative to the new way of bus requests processing (see 4.9) is wrapped by the C++ class called chapi_brq_t.
ipl - BRQ level to use; brq_ack - BRQ acknowledge procedure; arg1, arg2 - BRQ acknowledge procedure arguments. All of these members can be used to connect BRQ to the bus. All methods are mapped to the routine specified by the connect_bus_request entry in the chapi_in communication context. The best place to connect bus requests to the bus is the routine specified in the setup_bus_requests entry of chapi_out communication context. void set(); This member is used in order to set connected bus request.
This member is used in order to set bus request affinity mask which defines the set of bus servers which can process this particular bus request. It is mapped to the routine specified by the set_affinity_mask entry in the chapi_in communication context. void set_affinity_callback(__chapi_sa_handler_p sa_callback, void *arg1, int arg2); where sa_callback - affinity change callback routine; arg1 - first argument to the callback; arg2 - second argument to the callback.
bool get_brq_objects(unsigned int cpu_no, volatile unsigned long *& brq_object, unsigned long & brq_mask); where cpu_no - CPU number to get brq objects for; brq_object reference to the pointer which will be updated with the pointer to the bus requests mask of specified CPU; brq_mask reference to the bus request mask for particular bus request which defines the bit in bus requests server mask correspondent to the bus request.
chapi_cfg_option_value_t Basic functionality of option value is defined by the class chapi_cfg_option_value_t which establishes wrappers for the all CHAPI protocol routines relative to the option value processing. This class shouldn’t be used directly during the loadable components development. See description of derived classes below.
This method is used to commit option value change if any. It wrappes routine identified by the commit_option_value entry of chapi_in communication context. virtual bool is_specified() const; This method is used in order to define if specified value was mentioned in configuration file. It wraps routine identified by the is_option_value_specified entry of chapi_in communication context.
This method is used to define if option value is hidden, i.e. not accessible for view/change. It wraps routine identified by the is_option_value_hidden entry of chapi_in communication context. chapi_cfg_option_t class derivatives CHAPI protocol supports three different types of options: integer, boolean and string. For each kind of option dedicated wrapper is implemented. Integer options are wrapped by the C++ class chapi_integer_option_t derived from the class chapi_cfg_option_t.
ci pointer to chapi_in communication context supplied during the loadable component initialization; opt_name - option name to create; opt_vals_count - the number of option values within the option; option - reference to the option which should be used for initialization. This constructors are used to create integer option. chapi_bool_option_value_t & operator[] (int idx); where idx - index of option value to access. This operator is used to access option values by index.
This operator is used to access option values by index. Reference to the string option value with specified index is returned. chapi_cfg_option_value_t class derivatives All options can work with appropriate option values. Each option value type is wrapped by dedicated C++ class. Note that it is not necessary to create option values manually – they are created during the option creation and accessed like the follows: opt[idx].
opt_val_idx - option value index among the all option values; opt_buffer - option value buffer. This constructor is used to initialize integer option value. operator bool (); This operator converts boolean option value to the bool value. bool set(bool val); where val - value to set for the option. This method is used to set the new value for the option value. String option value is wrapped by C++ class chapi_string_option_value_t derived from the class chapi_cfg_option_value_t.
C++ wrappers to work with critical section The basic interface of critical section is defined in abstract chapi_critical_section_interface. Here is the list of public members: class virtual bool try_enter() = 0; Abstract method attempts to enter a critical section without blocking. If the call is successful, the calling thread takes ownership of the critical section and method return “true”, else return value shell be equal “false”.
where task_body - pointer on thread main function. task_arg - pointer on arguments of thread`s main function. Create and execute new task. Returns chapi_invalid_handle if create task failed. chapi_proc_t chapi_task::wait_for_result(chapi_handle_t the_task); where the_task - Task hendler. This method waits for the task to complete, and returns the task's completion status. template chapi_task_starter where T - class containing thread main method.
-ring buffer is common container, it`s use FIFO strategy for contain elements. The following public methods are defined: max_buffer_size void clean() Clean buffer bool is_empty() const This methos return true if buffer is empty else false. bool is_full() const This methos return true if buffer is full else false. uword_t size() const This methos return current buffers size.
5.1.3 Library usage examples General CHAPI support library is used by all examples supplied with the product. Examples source code can be found in chapters (6.1, 6.2). 5.2 Serial I/O CHAPI support library Note: This library depends on CHAPI.DLL one. 5.2.1 Library files Serial I/O CHAPI support library consists of: 1) Header file which contains base class (chapi_serial_device_interface) for all CHAPI serial line controller (also chapi_dhv11.dll, chapi_dlv11.
CHAPI serial line controller’s methods CHAPI serial line controller’s methods described in class chapi_serial_device_interface, so all CHAPI serial line controllers’ classes must be derived from the class chapi_serial_device_interface. chapi_serial_line_interface * line[_MAX_SERIAL_LINE_NUMBER_]; Array of CHAPI serial line pointers, instances of CHAPI serial lines.
controller must provide TX buffer. Simple wrapper is implemented in class chapi_serial_line_interface for calling this function. from_buf - place to put char for transmission line_id - line number Return: 1 - No errors, you have got 1 char for transmission -1 - No char for transmission, serial line controller’s TX buffer is empty virtual int input_signal(unsigned char in_signal, unsigned char line_id) = 0; Callback function, serial line must call serial line controller’s callback function input_signal(...
line_id - line number Return: 0 - No errors virtual int extra(void * extra, int arg, unsigned char line_id) = 0; Callback function, serial line must call serial line controller’s callback function extra (...) for extra features. Simple wrapper is implemented in class chapi_serial_line_interface for calling this function.
debug_level - debug level *str - trace message CHAPI serial line methods CHAPI serial line’s methods described in class chapi_serial_line_interface, so all CHAPI serial line classes must be derived from the class chapi_serial_line_interface. chapi_serial_line_interface(void * ctrl, unsigned char line_id) Constructor of CHAPI serial line instance. ctrl - serial line controller instance (pointer) line_id - current serial line instance number virtual int start() = 0; Start serial line.
virtual int setup_stop_len(unsigned char stop_len) = 0; Setup serial line stop bits length. stop_len - stop bits length Return: 0 - No errors virtual int setup_parity(unsigned char parity) = 0; Setup serial line parity control. parity - parity control Return : 0 - No errors virtual int setup_flow_ctrl(unsigned char flow_ctrl) = 0; Setup serial line flow control.
Setup serial line break transmission. break_signal - start/stop break Return: 0 - No errors virtual int do_tx(unsigned int len) = 0; Initiate transmission. len - number of bytes for transmission, or 0 for transmission all bytes from serial line controller TX buffer. So CHAPI serial line understand that CHAPI serial line controller has data for transmission and must call CHAPI serial line controller’s method get_tx_char(…) via wrapper ctrl_get_tx_char(…) to obtain data for transmission.
virtual int set_extra_command(void * extra_command, int arg) = 0; Set serial line’s extra features. extra - void pointer arg - integer argument Return: 0 - No errors virtual int get_rx_char(unsigned char & from_buf) = 0; Get received data from serial line RX buffer, CHAPI serial line must provide RX buffer.
Return: 1 - No errors, you have got 1 char for transmission -1 - No char for transmission, serial line controller’s TX buffer is empty int ctrl_input_signal(unsigned char in_signal); Wrapper for calling CHAPI serial line controller’s callback function, serial line must call function ctrl_input_signal(...) to notify controller about new input signals (modem).
void log_msg(log_message_type_t msg_type, const char *fmt, ...); Message logging. msg_type - type of message *fmt - message void debug_trace(unsigned char debug_level, const char *fmt, ...); Trace logging. debug_level - debug level *fmt - trace message void get_sys_err( unsigned long err ); System error logging. err - system error number NOTE about implemented CHAPI serial line controllers and CHAPI serial lines.
ctrl - pointer to CHAPI serial line controller instance p_serial_l_i – place to put created CHAPI serial line instance line_id – CHAPI serial line instance number In implemented CHAPI serial line controllers and CHAPI serial lines used predefined options.
Setup parameters pass to the CHAPI serial line via set_extra_command(void * extra_command, int arg) as a NULL TERMINATED string and arg must be EXTRA_LINE_SETUP. For example: - to pass setup option to CHAPI serial line mapped to COM port we must call: line[0]->set_extra_command(“com=1”, EXTRA_LINE_SETUP); - to pass setup option to CHAPI serial line mapped to NPort5210 we must call: line[7]->set_extra_command(“ip=192.168.127.
1) Header file which contains base class chapi_tape_device_iface for all CHAPI tape controllers (also chapi_tsv05.dll) that can work with CHAPI tape transports based on class chapi_tape_transport_iface - chapi_tape_device_iface.h; 2) Header file which contains base class chapi_disk_device_iface for all CHAPI disk drive controllers (also chapi_rlv12.dll) that can work with CHAPI disk drive based on class chapi_disk_drive_iface - chapi_disk_device_iface.
chapi_tape_transport_iface * tape[_MAX_TAPE_NUMBER_]; Array of CHAPI tape transport pointers, instances of CHAPI tape transports. virtual int cmd_done(int transport_number, int cmd, unsigned int status, unsigned int n_of_data) The only callback function, CHAPI tape transport must calls controller’s callback cmd_done(...) to notify CHAPI tape controller about requested command completion, initiated by calling CHAPI tape transport’s method do_command(…)).
*str - trace message; CHAPI tape transport methods CHAPI tape transport’s methods described in class chapi_tape_transport_iface, so all CHAPI tape transport classes must be derived from the class chapi_tape_transport_iface. chapi_tape_transport_iface(void * ctrl, unsigned char transport_number) Constructor of CHAPI tape transport instance. ctrl - tape controller instance (pointer); transport_number - current tape transport instance number; virtual void start() Start tape transport.
virtual bool is_write_prot() Check if tape is write protected. Returns: true - tape is write protected; false - tape is not write protected; virtual void do_command(unsigned int cmd, char * io_buf_p, unsigned int n_of_data) Initiate tape transport operation. cmd - tape transport operation, see operation definition; io_buf_p - IO buffer for READ/WRITE operations; n_of_data - depends on operation: c. number of bytes to write for WRITE operations; d. size of IO buffer for READ operations e.
err - system error number chapi_tape_device_iface * ctrl Instance of tape transport controller (pointer). unsigned int transport_number Tape transport instance number. NOTE about implemented CHAPI tape controller and CHAPI tape transports. It was implemented 3 CHAPI tape transports: - CHAPI tape transport mapped to *.
Where: ctrl - pointer to CHAPI tape controller instance p_tape_i – place to put created CHAPI tape transport instance transport_number – CHAPI tape transport instance number Setup parameters pass to the CHAPI tape transport via setup(void * param, int arg) as a NULL TERMINATED string. For example: - to pass setup option to CHAPI tape transport mapped to *.mtd file we must call: tape[0]->setup(“somefile.mtd”, 0); - to pass setup option to CHAPI tape transport mapped to SCSI we must call: tape[7]->seup(“\\.
// Skip some tape records in backward direction TAPE_CMD_SKIP_RECORD_REV, // Skip some tape marks in backward direction TAPE_CMD_SKIP_MARK_REV, // Read one tape record in forward direction TAPE_CMD_READ, // Read one tape record in backward direction TAPE_CMD_READ_REV, // Reread one next tape record TAPE_CMD_REREAD_NEXT, // Reread one previous tape record TAPE_CMD_REREAD_PREV, // Write one tape record TAPE_CMD_WRITE, // Rewrite one tape record TAPE_CMD_REWRITE, // Set tape transport offline // Depends on imp
//Beginning of tape detected TAPE_STS_BOT = 0x0001 << 5, //End of recorded data detected, position lost TAPE_STS_EOD = 0x0001 << 6, }; Note: - it is recommended to check write protected status and online status by tape controller before command initiation and after command completion; - TAPE_CMD_STATUS command refreshes write protected status and online status in tape transport and returns TAPE_STS_OK, but they automatically refreshed in case of TAPE_STS_BTE respond to another commands; - TAPE_CMD_ON
}; Structure definition to containing current head’s position. chapi_disk_drive_iface * HDD[_MAX_DISK_DRIVE_NUMBER_]; Array of CHAPI disk drive pointers, instances of CHAPI disk drives. CHAPI_DISK_DRIVE_GEOM disk_geom[_MAX_DISK_DRIVE_NUMBER_ ]; Array of disk drive geometry. CHAPI_DISK_DRIVE_POS disk_pos[_MAX_DISK_DRIVE_NUMBER_ ]; Array of disk drive head's position.
status - disk drive status after read command completion (can be mixed), see status code definition in disk drive methods description; n_of_byte - number of bytes ACTUALLY transferred by READ operations; Rerurns: 0 – Success; virtual void get_sys_err( unsigned long err ) System error logging, also callback function, disk drive must calls disk controller’s callback get_sys_err(...
Constructor of CHAPI disk drive instance. *ctrl - disk drive controller instance (pointer); disk_number - current disk drive instance number; virtual void start() Start disk drive MUST be called after any setup functions. virtual void stop() Stop disk drive. virtual void setup(void * param, int arg) Setup parameters for disk drive, MUST be called before start().
Check if disk drive is write protected. Returns: true - disk drive is write protected; false - disk drive is not write protected; virtual unsigned _int64 capacity() Obtain disk drive capacity, return value valid after at once setup(...) calling only. Returns: Disk drive capacity in bytes. virtual void do_read(CHAPI_DISK_DRIVE_POS disk_pos, char * io_buf_p, unsigned int n_of_byte) Initiate READ operation on disk drive.
void debug_trace(unsigned char debug_level, const char *fmt, ...) Trace logging. debug_level - debug level *fmt - trace message void get_sys_err( unsigned long err ) System error logging. err - system error number chapi_disk_device_iface * ctrl Instance of disk drive controller (pointer). unsigned int disk_number Disk drive instance number. CHAPI_DISK_DRIVE_GEOM disk_geom; Current disk drive geometry. CHAPI_DISK_DRIVE_POS head_pos; Current head's position.
- CHAPI disk drive mapped to raw physical disk; To load implemented CHAPI disk drives at run-time you should: 1) Load dll by calling : hinst=::LoadLibrary(TEXT(“chapi_storage.
For example: to pass geometry to CHAPI disk drive we must do: … CHAPI_DISK_DRIVE_GEOM disk_geom; … disk_geom.cylinders_per_disk = 256*2; disk_geom.tracks_per_cylinder = 2; disk_geom.sectors_per_track = 40; disk_geom.bytes_per_sector = 256; HDD[1]->setup_geometry(disk_geom); … In implemented CHAPI disk controller and CHAPI disk drive used predefined options.
// Disk drive READ/WRITE length error DRIVE_STS_LE = 0x0001 << 6 }; Note: - DO NOT initiate NEXT disk drive command before PREVIOUS disk drive command completion; - When using raw physical drive and sector size of disk drive is being emulated is less than sector size on real physical drive, any READ or WRITE operations can be performed with number of bytes to read or write less or equal 32768.
6.CHAPI design examples Two CHAPI examples are provided with source code for the moment – LPV11 printer port and DLV11 serial line controller. More devices will be provided in the future release. 6.1 LPV11 Full functional QBUS LPV11 / UNIBUS LP11 printer port with ability to send printed data to the TCP/IP connection or local file on the disk. This device is supplied with HOSTprint utility which maybe used to print data to the default host machine printer.
6.3.1 General CHAPI device This set of templates represents general structure of CHAPI device w/o any specialization. It is intended to be used as the base for any CHAPI device when there is no specialized template appropriate for the category of implemented device. Use CHAPI device creation wizard to supply parameters for this kind of project and build compilable MS VC++ project. Below is the list of files belongs to this template: - chapi_general_tmp.
- chapi_serial_port_tmp.h – template for header file; - chapi_serial_port_msgid_tmp.h; - chapi_serial_port_tmp.vcproj – template for the project file. 6.3.4 CHAPI disk controller This set of templates represents proposed structure of disk controller. It is intended to be used as the base for any new CHAPI disk controller implementation.
6.3.6 CHAPI tape controller This set of templates represents proposed structure of tape controller. It is intended to be used as the base for any new CHAPI tape controller implementation. It is not mandatory to use these templates but they simplify development a lot and allow using already implemented tape containers like 1) Tape image file; 2) SCSI tape connected to the host system (\\.\SCSIl:m:k); 3) windows driver supported tape connected to the host system (\\.\TapeK) without any additional efforts.
and XXDP – these test packages are pretty different and they are using different test algorithms which facilitate bug hunting. Debug trace facility is described in details in sections (4.21).
7.Source code listings All CHAPI source code listings and programming examples as referred to in this document are provided in document 30-09-006 CHARON CHAPI source code listing.pdf. This document can be given by the written request.
8.Configuration file samples with CHAPI 8.1 Education configuration file # # # # # # # # # # Copyright (C) 1999-2006 Stromasys. All rights reserved. The software contained on this media is proprietary to and embodies the confidential technology of Software Resources International. Posession, use, duplication, or dissemination of the software and media is authorized only pursuant to a valid written license from Stromasys. # # # # # # # Sample configuration file for CHARON emulators.
# # You can specify that repeatetive messages should be filtered out using # 'log_repeat_filter' "on"/"off" option.
# # It is possible to load external PDP11 ROM if it is necessary # #set rom ext_rom="" # # Specify the size of RAM . Remember that the license key might # limit the maximum amount of memory.
#load virtual_serial_line/chserial OPA0 port=10003 # # Virtual serial line connection listening for the TCP/IP port # number 10003 on the host system. Specified program is started # automatically. # load virtual_serial_line/chserial OPA0 set OPA0 port=10003 application="opa0.ht" set uart line=OPA0 # # # # # # # # # # # # Configure optional RQDX3 storage controller (MSCP/QBUS). Handles disk images, disk drives, CD-ROM drives, magneto optical drives, floppy drives.
#load TUK50/TUK50 MUA #set MUA address=... #set MUA container[0]="..." #set MUA container[1]="..." #set MUA container[2]="..." #set MUA container[3]="..." # # Configuring the optional DELQA Ethernet adapters (QBUS). #. # # Load the optional DELQA/DESQA/DEQNA Ethernet adapter then load # a ndis5 packet port then associate these two devices as shown # below. # load DELQA/DEQNA XQA #load ndis5_chpack_port/chnetwrk XQA0 interface="...
#set TXA0 ip="xxx.xxx.xxx.xxx" rs_port=n #load physical_serial_line/chserial TXA0 line="COMn:" #load virtual_serial_line/chserial TXA0 port=10010 #load virtual_serial_line/chserial TXA0 #set TXA0 port=10010 application="txa0.ht" #set TXA line[0]=TXA0 #load np5210_serial_line/chserial TXA1 #set TXA1 ip="xxx.xxx.xxx.
#set TXA line[5]=TXA5 #load np5210_serial_line/chserial TXA6 #set TXA6 ip="xxx.xxx.xxx.xxx" rs_port=n #load physical_serial_line/chserial TXA6 line="COMn:" #load virtual_serial_line/chserial TXA6 port=10016 #load virtual_serial_line/chserial TXA6 #set TXA6 port=10016 application="txa6.ht" #set TXA line[6]=TXA6 #load np5210_serial_line/chserial TXA7 #set TXA7 ip="xxx.xxx.xxx.
#set TTA1 port=10111 application="tta1.ht" #set TTA line[1]=TTA1 #load np5210_serial_line/chserial TTA2 #set TTA2 ip="xxx.xxx.xxx.xxx" rs_port=n #load physical_serial_line/chserial TTA2 line="COMn:" #load virtual_serial_line/chserial TTA2 port=10112 #load virtual_serial_line/chserial TTA2 #set TTA2 port=10112 application="tta2.ht" #set TTA line[2]=TTA2 #load np5210_serial_line/chserial TXA3 #set TXA3 ip="xxx.xxx.xxx.
# LINE[4] IS CLIENT #set TXA line_dll[4]=chapi_serial line_cfg[4]=tcpip #set TXA line_param[4]="ip=192.168.1.1 port=10055" #-------------------------------------------------------------------# CHAPI DLV-11 serial line controller. It is possible to map its # line to three different kind of ports. # # chapi_serial is default value for line_dll when this option is # omitted; # tcpip is default for the line_cfg option when this option is # omitted.
# # # # # # # # # # adapter_instance - number of adapter instance to use if more than one adapter is installed in the host system (0 is default); adapter_options - options to be passed to adapter (no options are defined for the moment - empty string is default). Note that CHAPI_QBUS can be used both with QBUS and UNIBUS systems.
# possible for the moment); # # When default values for disk_dll/disk_cfg are satisfy user needs # just ommit these options and use disk_param only to specify disk image. # # This CHAPI device can be used both with QBUS and UNIBUS systems. # #load chapi DLA dll=chapi_rlv12.dll address=... vector=...
#set MSA0 tape_cfg[0]=driver tape_param[0]="\\.\TapeN" #-------------------------------------------------------------------# CHAPI DRV11-WA using TLC DCI-1100 board. # # Just uncomment the proper lines below to test this kind of CHAPI # device with particular configuration.
9.The SENSORAY 621 - DR11C/DRV11 adapter. An 'Eagle' PCB layout for a small connector adapter board can be provided.
10. The SENSORAY 621 - DRV11-WA adapter. An 'Eagle' PCB layout for a small connector adapter board can be provided.
Reader’s Comments We appreciate your comments, suggestions, criticism and updates of this manual. You can Email us your comments at: info@stromasys.com Please mention the document reference number: 30-016-040-001 If you found any errors, please list them with their page number.