Realtime Interface Co-Processor
C Language Support
User's Guide

Volume I - System Unit

Version 1.03.01 (August 1996)


Table of Contents

About This Guide

  • The Users of This Guide
  • How This Guide Is Organized
  • How to Use This Guide
  • Related Publications
  • Reference Publications
  • Chapter 1. Support for System Unit Tasks

  • Hardware Requirements
  • Software Requirements
  • Distributing Your Programs
  • Chapter 2. Installing C Language Support

  • Installation Requirements
  • Product Contents
  • Introduction to the C Language Support Program Files
  • Installation Instructions
  • Chapter 3. DOS C Language Interfaces

  • DOS Interrupt Handler
  • DOS Application Loader Utility
  • Assembly Interface Macros and Library Routines
  • DOS Interface Routines
  • C Language Compiler Interfaces
  • ICACMD
  • ICAFPARM
  • ICAINBUF
  • ICAINIT
  • ICALOC
  • ICANCMD
  • ICAOUTBUF
  • ICAPAG2P
  • ICAPAG2S
  • ICAPHY2P
  • ICAQINT
  • ICARBYTE
  • ICAREL
  • ICARSET
  • ICARSTR
  • ICARSV
  • ICASEG2P
  • ICASTAT
  • ICASTATX
  • ICAVRET
  • ICAVSET
  • ICAWBYTE
  • ICAWINDOW
  • ICAWSTR
  • DOS SYSTEM UNIT PEER SERVICES
  • ICAPEEROPEN
  • ICAPEERCLOSE
  • ICAPEERSEND
  • Chapter 4. OS/2 C Language Interfaces

  • OS/2 Device Driver
  • OS/2 Application Loader Utility
  • OS/2 Dynamic Link Routines
  • C Language Compiler Interfaces
  • ICADEVCHANGEPAGE
  • ICADEVGETINBUF
  • ICADEVGETPARMS
  • ICADEVGETEXTPARMS
  • ICADEVGETSECSTATUS
  • ICADEVGETVERSION
  • ICADEVINPUTBUFFER
  • ICADEVISSUECOMMAND
  • ICADEVNOTIFY
  • ICADEVOUTPUTBUFFER
  • ICADEVPRIMARYSTATUS
  • ICADEVPUTOUTBUF
  • ICADEVREADSTRING
  • ICADEVREGSEMAPHORE
  • ICADEVREMNOTIFY
  • ICADEVREMSEMAPHORE
  • ICADEVRESET
  • ICADEVSECSTATUS
  • ICADEVTASKFLUSH
  • ICADEVWINRELEASE
  • ICADEVWINRESNOWAIT
  • ICADEVWINRESWAIT
  • ICADEVWRITESTRING
  • OS/2 SYSTEM UNIT PEER SERVICES
  • ICADEVLOCK
  • ICADEVPEEROPEN
  • ICADEVPEERCLOSE
  • ICADEVPEERRECEIVE
  • ICADEVPEERRECEIVEDONE
  • ICADEVPEERSEND
  • ICADEVUNLOCK
  • Chapter 5. Writing System Unit Applications Tasks

  • Exchanging Data
  • Handling Interrupts With DOS Support
  • Handling Interrupts With OS/2 Support
  • Issuing Application Commands
  • Creating a DOS System Unit Application
  • Creating Mixed Model OS/2 V 2.X Applications
  • Appendix A. Sample Program

    Appendix B. Glossary


    About This Guide

    This guide, Volume I, provides technical information on the Realtime Interface Co-Processor C Language Support services that allow you to write system unit programs in C Language for communicating with the following co-processor adapters:

    The information in this volume supports the development of C programs that will use the application program interface of the Realtime Interface Co-Processor DOS Support or Operating System/2(1) (OS/2(1)) Support. This volume also provides information on installing the C Language Support product and describes the sample system unit program supplied with the C Language Support product.

    Volume II of this guide provides information for developing C tasks that will run under the control of the IBM Realtime Control Microcode. Volume II also describes the sample co-processor adapter programs supplied with the C Language Support product.

    Throughout this guide, the term "co-processor adapter" refers to any adapter in the Realtime Interface Co-Processor family of adapters listed above.


    The Users of This Guide

    This guide is intended for use by development programmers. To make full use of the Realtime Interface Co-Processor C Language Support, the programmer should understand the following:

    Knowledge of the IBM Macro Assembler/2(2) is recommended but not required.


    How This Guide Is Organized

    The user's guide for the IBM Realtime Interface Co-Processor C Language Support product is organized into two volumes:

    Volume I contains technical information on the C Language Support for the system unit and is organized as follows:

    Volume II contains technical information on the C Language Support for the co-processor adapter and is organized as follows:


    How to Use This Guide

    This guide should be used along with the technical reference and other appropriate documents for your co-processor adapter.

    The following conventions are used in this guide:


    Related Publications

    The following C Language Support guide is Volume II of this guide:

    Other related books in the Realtime Interface Co-Processor library include:


    Reference Publications

    You may need to use one or more of the following publications for reference with this guide:


    Chapter 1. Support for System Unit Tasks

    The Realtime Interface Co-Processor C Language Support is a productivity aid that allows programmers to develop code in the C Programming Language for the co-processor adapter or the system unit.

    C Language Support for the System Unit includes a set of program services that allow users to write system unit programs in C Language to interact with a co-processor adapter. This support is for programs using the application program interface of:

    The C Language Support for the system unit is described in this volume. (Volume II of this guide describes the C Language Support for the Co-Processor Adapter, which includes support for C tasks running under the control of Realtime Control Microcode.)

    Hardware Requirements

    The following are minimum hardware requirements for the Realtime Interface Co-Processor C Language Support:

    Although a printer is optional, we recommend that users have a printer when using this product.


    Software Requirements

    The following are minimum software requirements for the Realtime Interface Co-Processor C Language Support:


    Distributing Your Programs

    The Realtime Interface Co-Processor C Language Support program contains several object files. During compilation, some files from the C Language Support may be automatically combined with your program files. Permission is given to distribute C programs that have been compiled and linked using the C Language Support and which contain files or modules from the IBM Realtime Interface Co-Processor C Language Support. No royalty payment is due IBM when distributing such programs. In such cases, the copyright notices, if any, in the files and modules, must be reproduced and included in the files and modules of your program.


    The program files for the system unit support are:
      File           Description
    
      ICADECL.H      C declarations Include file for DOS
      ICASC.OBJ      C Interface object module for DOS -
                       small model
      ICAMC.OBJ      C Interface object module for DOS -
                       medium model
      ICALC.OBJ      C Interface object module for DOS -
                       large model
      ICACALLS.H     C Interface include file for OS/2
      HLLC.C         System unit sample program
      HLLC.EXE       System unit sample executable
                     program to run with HLLC.C
      ICADOS16.H     Provides declarations to allow for thunking mechanism
    
    The program files for the co-processor adapter support are:
      File            Description
    
      ICADECLT.H      Library declarations
      ICATSKS6.LIB    Small memory model library routines
                      (Microsoft C 6.0)
      ICATSKM6.LIB    Medium memory model library routines
                      (Microsoft C 6.0)
      ICATSKL6.LIB    Large/huge memory model library routines
                      (Microsoft C 6.0)
      ICATSKS7.LIB    Small memory model library routines
                      (Microsoft C++ and Visual C\C++)
      ICATSKM7.LIB    Meduim memory model library routines
                      (Microsoft C++ and Visual C\C++)
      ICATSKL7.LIB    Large/huge memory model library routines
                      (Microsoft C++ and Visual C\C++)
      ICAMS60S.LIB    Microsoft C V.6.0 small model startup
      ICAMS60M.LIB    Microsoft C V.6.0 medium model startup
      ICAMS60L.LIB    Microsoft C V.6.0 large/huge model startup
      ICAMS70S.LIB    Microsoft C\C++ V.7.00  small model startup
      ICAMS70M.LIB    Microsoft C\C++ V.7.00 medium model startup
      ICAMS70L.LIB    Microsoft C\C++ V.7.00 large/huge model startup
      ICAMS80S.LIB    Microsoft C small model startup
                     (Visual C\C++ Version 1.5)
      ICAMS80M.LIB    Microsoft C medium model startup
                     (Visual C\C++ Version 1.5)
      ICAMS80L.LIB    Microsoft C large/huge model startup
                     (Visual C\C++ Version 1.5)
      ICAC2S.LIB      IBM C/2 1.1 small model startup
      ICAC2M.LIB      IBM C/2 1.1 medium model startup
      ICAC2L.LIB      IBM C/2 1.1 large/huge model startup
      ICAHEADC.ASM    Assembler source for C task header
      ICAHEADC.OBJ    Assembled C task header
      ICACEH.COM      Error handling task
      ICACDEMO.C      Example task to compile, link and run
      ICACDISP.EXE    Utility to display results of ICACDEMO
      CHILDXMP.C      Example task for building peer tasks
      CHILDEMO.EXE    System unit program to run with CHILDXMP
      CHILDC.C        BuildChild() and BuildPeer()
      CHILDSUB.ASM    Unique command handler and interrupt
                        entry
      CHILDSUB.OBJ    Assembled CHILDSUB.ASM
      CHILDLIB.ASM    Subroutines used for building tasks
      CHILDLIB.OBJ    Assembled CHILDLIB.ASM
    

    The co-processor adapter support is described in Volume II.


    Installation Instructions

    Use the following procedures to install C Language Support:

    Copy the C Language Support program files into either the working directory containing the C task and system unit program source or the C Compiler subdirectories.

    In the latter case, copy the ICADECLT.H and ICADECL.H files into the INCLUDE subdirectory, and copy the ICA*.LIB library modules into the LIB subdirectory.

    Note:

    Realtime Interface Co-Processor C Language Support for the system unit is described in this volume. Realtime Interface Co-Processor C Language Support for the co-processor adapter is described in Volume II.

    Chapter 3. DOS C Language Interfaces

    This chapter is for programmers writing applications to run on the system unit using the application program interface of the Realtime Interface Co-Processor DOS Support. The information in this chapter should be used with other appropriate documents for your co-processor adapter.


    DOS Interrupt Handler

    The Interrupt Handler (ICAINTH), supplied with the Realtime Interface Co-Processor DOS Support product, is a resident DOS extension that handles the system unit side of the communication between the applications on the system unit and tasks on the co-processor adapter.

    The Interrupt Handler handles most of the details when communicating with co-processor adapter and presents a general interface to the system unit applications so that they can communicate with tasks running under Realtime Control Microcode.


    DOS Application Loader Utility

    The Application Loader (ICALOAD), supplied with the Realtime Interface Co-Processor DOS Support product, is a utility that is used to load the Realtime Control Microcode tasks from the system unit to the co-processor adapter. The application loader should be invoked to load Realtime Control Microcode and all tasks that run under Realtime Control Microcode. It loads both .EXE and .COM tasks on high- or low-memory boundaries.


    Assembly Interface Macros and Library Routines

    The Assembly Interface Macros and Library Routines are a set of functions that provide a standard method of communicating with the co-processor adapter. These functions provide an interface to the Interrupt Handler. System unit applications written in assembly language can use the Interrupt Handler directly or utilize these routines.


    DOS Interface Routines

    The routines supported by the DOS C Language Support for the System Unit are described in this volume. They consist of routines for the DOS Support Assembler Macros, routines for converting between segment and page addresses, and routines for reading from or writing to co-processor adapter memory.

    The file ICADECL.H contains the necessary declarations for the C Interface to the co-processor adapter. This file is to be included in the source of your C program. This file includes the declarations for the external function declarations for the interface routines in ICASC.OBJ, ICAMC.OBJ and ICALC.OBJ, depending on the C memory model used. Also included are the following data structure definitions that follow.

    typedef unsigned char ICABYTE ;
    
    struct ICAPARM {
            unsigned short iobase ;  /* Base I/O address              */
            ICABYTE lastentry ;      /* LAST indicator                */
            ICABYTE meg ;            /* Meg of shared storage window  */
            ICABYTE page8k ;         /* Page of shared storage window */
            ICABYTE maxtask ;        /* Largest task number           */
            ICABYTE maxpri ;         /* Largest priority value        */
            ICABYTE maxqueue ;       /* Largest queue number          */
            ICABYTE maxtime ;        /* Largest software timer number */
            ICABYTE cmp_degate2 ;    /* Ctrl-alt-del meg              */
            ICABYTE cmp_degate0 ;    /* Ctrl-alt-del address          */
            ICABYTE cmp_degate1 ;    /* Ctrl-alt-del address          */
            ICABYTE rsv1 ;           /* Reserved                      */
            ICABYTE rsv2 ;           /* Reserved                      */
            ICABYTE rsv3 ;           /* Reserved                      */
            ICABYTE rsv4 ;           /* Reserved                      */
            ICABYTE intlevel ;       /* Interrupt level               */
            ICABYTE pagesize ;       /* Page size code                */
            ICABYTE adapter ;        /* Adapter type definition       */
            ICABYTE eibid0 ;         /* ID of elec interf board 0     */
            ICABYTE eibid1 ;         /* ID of elec interf board 1     */
            ICABYTE physlotnum ;     /* Physical slot number          */
            ICABYTE clkopt ;         /* Clocking options, ports 0 & 1 */
            ICABYTE arblevel ;       /* Arbitration level (priority   */
            };
    
    Note: The value for clkopt is undefined for Realtime Interface Co-Processor Portmaster Adapter/A.
    struct ICABUFFER {
            ICABYTE page ;
            char resv;
            unsigned short offset ;
            unsigned short length ;
            };
    
    struct ICA_SEG_OFF {
            unsigned short SEGMENT ;
            unsigned short OFFSET ;
            };
    
    struct ICA_PAGE_OFF{
            ICABYTE PAGE ;
            char resv;
            unsigned short OFFSET ;
            };
    
    struct ICA_PRBSTRUCT {
        struct ICA_PRBSTRUCT far *QCHAINPTR;/* Pointer to queue chain. */
        unsigned char CMDRESP;              /* Command response code.  */
        unsigned char COMPCODE;             /* Completion Code.        */
        unsigned char PEEROPTNS;            /* Peer request option.    */
        unsigned char CMDOPTNS;             /* Command options.        */
        unsigned char TGTPROCID;            /* Target processor ID.    */
        unsigned char SRCPROCID;            /* Source processor ID.    */
        unsigned int TGTTASKID;             /* Target task ID.         */
        unsigned int SRCTASKID;             /* Source task ID.         */
        unsigned int REQBLKID;              /* Request block ID.       */
        unsigned int DATACOUNT;             /* Data byte count.        */
        unsigned int RSV1;                  /* Reserved; Must be zero. */
        union
           {
           struct
               {
               unsigned char TGTCARDID;
               unsigned char SRCCARDID;
               } movinfo;
           unsigned int dataval;
           } DATAVAL1;           /* Data value 1 or immediate data.    */
        unsigned long DATAADD1;  /* Target buffer addr or immed. data. */
        unsigned long DATAADD2;  /* Source buffer addr or immed. data. */
        unsigned long DATAADD3;  /* Data address or immediate data.    */
        unsigned char RSV2[8];   /* Reserved work area.                */
        };
    

    C Language Compiler Interfaces

    The C compiler Interfaces are in a library of interface routines for DOS that assist in communications with the co-processor adapter by applications written in C on the system unit. The interface modules consist of an object module and an include file (ICADECL.H). The include file contains declarations for access to the linked interface routines and structures used by those routines.

    You can include the file ICADECL.H with the following line at the beginning of your application program:

         #include "icadecl.h"
    
    The following is an example of compiling an application program using the Microsoft C 6.0 Optimizing Compiler:
        cl /Ax /c myprog.c
    
    The following is an example of compiling an application program using the IBM C/2(4) 1.1 Compiler:
        cc /Ax myprog,myprog,myprog,myprog;
    
    The "x" in the first option represents the memory model being used. The object module is ICASC.OBJ, ICAMC.OBJ or ICALC.OBJ, depending on the memory model used. Link this object module with the library ICAEMAC.LIB. The ICAEMAC.LIB library is provided in the IBM Realtime Interface Co-Processor DOS Support Version 1.03 package.

    The compiler options used for the Microsoft 6.0 compiler can be used the same way for the Microsoft C 7.0 and Microsoft C 8.0 compilers.

    The following is an example of linking a small model program to the C interfaces for DOS:

         link myprog.obj + icasc.obj,,,icaemac.lib
    
    Refer to the compiler documentation for other library files necessary for linking.

    The following declarations define parameter types used by the C Language interface routines for DOS and are declared in ICADECL.H. Error codes are passed back as function return values.


    ICACMD

    Purpose:

         ICACMD issues a command to a task on a co-processor adapter.
    
    Format:
    ICACMD (ICABYTE,      /* Co-processor adapter */
                          /* number               */
            ICABYTE,             /* Task number   */
            ICABYTE,             /* Command code  */
            ICABYTE *);          /* & task status */
    
    Remarks:

    The parameters for the command should be stored in the task's output buffer before the command is issued. The address of the task's output buffer can be found with the ICAOUTBUF interface routine. The data can then be written to the output buffer with either the ICAWBYTE or ICAWSTR interface routines.

    COPROCNUM      = Co-processor adapter number
    TASK           = Task number
    COMMAND        = Command code
    DATA           = Data to be written to task's
                     output buffer
    
    Returns:
    STATUS         = Task status if the task status was
                     invalid
    Function value =
            0x000  = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid co-processor adapter
                     task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0006 = Output buffer too small
            0x0007 = Invalid PC Select Byte
            0x0008 = Invalid primary status byte
            0x0009 = Command not accepted
    
    Example:
    #include "icadecl.h"
    ICABYTE coproc;
    ICABYTE tasknum;
    ICABYTE cmdcode;
    ICABYTE status;
    unsigned int error;
    
    error = ICACMD (coproc, tasknum, cmdcode, &status;);
    
    Related Topics:
     ICANCMD
    

    ICAFPARM

    Purpose:

    ICAFPARM returns information about the installed co-processor.
    
    Format:
    ICAFPARM (ICABYTE,     /* Co-processor adapter */
                           /* number               */
        struct ICAPARM *); /* & ICAPARM structure  */
    
    Remarks:

    The following co-processor adapter parameters are returned unless the error code is non-zero:

    Returns:
    ICAPARM    = parameters for requested co-processor
                 adapter number
    Function value =
        0x0000 = Normal return code
        0x0001 = Invalid co-processor adapter number
        0x0004 = Co-processor adapter inactive,
                 but parameters exist
    
    Example:
    #include "icadecl.h"
    ICABYTE coproc;
    struct ICAPARM parmstruct;
    unsigned int error;
    
    error = ICAFPARM(coproc, &parmstruct;);
    
    Related Topics:
         None
    

    ICAINBUF

    Purpose:

    ICAINBUF returns the offset, page pointer, and buffer size
             of the input buffer of a co-processor adapter task.
    
    Format:
    ICAINBUF (ICABYTE,    /* Co-processor adapter */
                          /* number               */
              ICABYTE,             /* Task number */
              struct ICABUFFER *); /* & ICABUFFER */
                                   /* structure   */
    
    Returns:
    PAGE           = Page of task's input buffer
    OFFSET         = Page offset of task's input
                     buffer
    LENGTH         = Byte size of task's input
                     buffer
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    ICABYTE coproc;
    ICABYTE tasknum;
    struct ICABUFFER bufstruct;
    unsigned int error;
    
    error = ICAINBUF(coproc, tasknum, &bufstruct;);
    
    Related Topics:
     ICAOUTBUF
    

    ICAINIT

    Purpose:

    ICAINIT initializes the data area used by C language
            interface routines.  This routine must be called
            before any other routines are called.
    
    Format:
    ICAINIT (void);
    
    Returns:
    Function value =
            0x0000 = Normal return code
            0x000A = No resident interrupt handler
            0x000B = Invalid interrupt handler version
    
    Example:
    #include "icadecl.h"
    unsigned int error;
    
    error = ICAINIT ();
    
    Related Topics:
         None
    

    ICALOC

    Purpose:

    ICALOC returns the segment of a co-processor adapter's
           memory window.
    
    Format:
    ICALOC (ICABYTE,        /* Co-processor adapter*/
                            /* number              */
       unsigned short far*);/* & Window segment    */
    
    Remarks:
    COPROCNUM      = Co-processor adapter number
    
    Returns:
    POINTER        = memory pointer to co-processor
                     adapter window
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    unsigned short winseg;
    unsigned int error;
    
    error = ICALOC (coproc, &winseg;);
    
    Related Topics:
         None
    

    ICANCMD

    Purpose:

    ICANCMD writes parameters to a task's output buffer, then
            issues a command to a task on a co-processor adapter.
    
    Format:
    ICANCMD (ICABYTE,     /* Co-processor adapter */
                          /* number               */
             ICABYTE,        /* Task number       */
             ICABYTE,        /* Command code      */
             char *,         /* & string          */
             ICABYTE *,      /* & task status     */
             unsigned short);/* Length of string  */
    
    Remarks:
    COPROCNUM      = Co-processor adapter number
    TASK           = Task number
    COMMAND        = Command code
    DATA           = Data to be written to task's
                     output buffer
    
    Returns:
    STATUS         = Task status if the task status
                     was invalid
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid co-processor adapter
                     task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0006 = Output buffer too small
            0x0007 = Invalid PC Select Byte
            0x0008 = Invalid primary status byte
            0x0009 = Command not accepted
    
    Example:
    #include "icadecl.h"
    ICABYTE coproc;
    ICABYTE tasknum;
    ICABYTE cmdcode;
    char string [10] = "ICANCMD..";
    ICABYTE status;
    unsigned int error;
    
    error = ICANCMD (tasknum, cmdcode, string,
                     &status;, 10);
    
    Related Topics:
         ICACMD
    

    ICAOUTBUF

    Purpose:

    ICAOUTBUF returns the offset, page pointer, and buffer
              size of the output buffer of a co-processor adapter task.
    
    Format:
    ICAOUTBUF (ICABYTE,   /* Co-processor adapter */
                          /* number               */
               ICABYTE,            /* Task number */
               struct ICABUFFER *);/* & ICABUFFER */
                                   /* structure   */
    
    Returns:
    PAGE           = Page of task's output buffer
    OFFSET         = Page offset of task's output
                     buffer
    LENGTH         = Byte size of task's output
                     buffer
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    ICABYTE tasknum;
    struct ICABUFFER bufstruct;
    unsigned int error;
    
    error = ICAOUTBUF (coproc, tasknum, &bufstruct;);
    
    Related Topics:
         ICAINBUF
    

    ICAPAG2P

    Purpose:

    ICAPAG2P converts a page address to a 32-bit physical address,
             relative to the current co-processor adapter shared storage
             window size.
    
    Format:
    unsigned int ICAPAG2P (ICABYTE,
                     /* Co-processor adapter number */
       struct ICA_PAGE_OFF *,/* Page:offset address */
       unsigned long *,      /* Physical address    */
       unsigned int *);      /* Current shared      */
                             /* storage window size */
    
                       Co-Processor Adapter Shared
        Page Size          Storage Window Size
    
          8KB                     1FFFh
         16KB                     3FFFh
         32KB                     7FFFh
         64KB                     FFFFh
    
    Returns:
    PHYSADDR       = translated physical address
    WINSIZE        = current window size
    
    Function value =
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter in
                     ICAPARM.PRM but not active
    
    Example:
    #include "icadecl.h"
    
    struct ICA_PAGE_OFF pgoffstruct;
    ICABYTE coproc;
    unsigned long physaddr;
    unsigned int winsize;
    unsigned int error;
    
    error = ICAPAG2P (coproc, &pgoffstruct;, &physaddr;,
                      &winsize;);
    
    Related Topics:
         ICAPHY2P
    

    ICAPAG2S

    Purpose:

    ICAPAG2S converts an address in co-processor adapter memory from a page
             address to a segment address.
    
    Format
    ICAPAG2S (struct ICA_PAGE_OFF, /* Page:offset */
                                   /* address     */
          struct ICA_SEG_OFF *,    /* & seg:offset*/
                                   /* address     */
          ICABYTE);/* Co-processor adapter number */
    
    Remarks:
    Ranges for the various page sizes are:
    
                              Page Range on
            Page Range on       All Other
    Page      Portmaster      Co-Processor
    Size      Adapter/A         Adapters       Offset Range
    
     8KB      0 to FFh          0 to 7Fh        0 to 1FFFh
    16KB      0 to 7Fh          0 to 3Fh        0 to 3FFFh
    32KB      0 to 3Fh          0 to 1Fh        0 to 7FFFh
    64KB      0 to 1Fh          0 to 0Fh        0 to FFFFh
    
    Note:
    On the Realtime Interface Co-Processor Portmaster Adapter/A adapter, this function converts the address assuming a one-to-one page mapping; for page:offset addresses greater than one megabyte, it returns an address-out-of-range error and a 32-bit physical address.
    Returns:
    SEGMENT        = Segment
    SEG_OFFSET     = Offset in segment
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid window size
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x000C = Address out of range
            0x001E = Invalid conversion page number
            0x001F = Invalid conversion page offset
    
    Example:
    #include "icadecl.h"
    
    struct ICA_PAGE_OFF pagoff;
    struct ICA_SEG_OFF segoff;
    ICABYTE coproc;
    unsigned int error;
    
    error = ICAPAG2S (pagoff, &segoff;, coproc);
    
    Related Topics:
         ICASEG2P
    

    ICAPHY2P

    Purpose:

    ICAPHY2P converts a co-processor 32-bit physical address
             to page address format.
    
    Format:
    ICAPHY2P (ICABYTE,/* Co-processor adapter number*/
        unsigned long,        /* Physical address to*/
                              /* translate          */
        struct ICA_PAGE_OFF *,/* Page:offset address*/
        unsigned int *);      /* & Current window   */
                              /* size               */
    
                       Co-Processor Adapter Shared
       Page Size           Storage Window Size
    
          8KB                     1FFFh
         16KB                     3FFFh
         32KB                     7FFFh
         64KB                     FFFFh
    
    Returns:
    ICA_PAG_OFF if no error
    Function value =
            0x0000 = No error
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter in
                     ICAPARM.PRM but not active
            0x000C = Address out of range
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    unsigned long physaddr;
    struct ICA_PAGE_OFF pagoff;
    unsigned int winsize;
    unsigned int error;
    
    error = ICAPHY2P (coproc, physaddr, &pagoff;,
                      &winsize;);
    
    Related Topics:
         ICAPAG2P
    

    ICAQINT

    Purpose:

    ICAQINT queries the interrupt flag for a task on a co-processor adapter.
    
    Format:
    ICAQINT (ICABYTE,      /* Co-processor adapter */
                           /* number               */
             ICABYTE,      /* Task number          */
             ICABYTE *);   /* & interrupt flag     */
    
    Remarks:

    The interface routine ICAVSET should be called before using this routine. After an interrupt flag is queried, it is cleared so that the same interrupt is not received twice.

    Returns:

    INTFLAG        = Boolean flag, TRUE = interrupt
                     has occurred
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0022 = ICAVSET must be done prior to
                     ICAQINT
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    ICABYTE tasknum;
    ICABYTE intflag;
    unsigned int error;
    
    error = ICAQINT (coproc, tasknum, &intflag;);
    
    Related Topics:
         ICAVSET
    

    ICARBYTE

    Purpose:

    ICARBYTE reads a byte from a co-processor adapter at a specific
             page and offset.
    
    Format:
    ICARBYTE (ICABYTE,    /* Co-processor adapter */
                          /* number               */
              ICABYTE,             /* Userid      */
              ICABYTE,             /* Page number */
              unsigned short,      /* Page offset */
              ICABYTE *);          /* & data byte */
    
    Remarks:

    Reserve the memory window with the ICARSV routine. ICARBYTE should be called with the same user ID as the one used in the ICARSV routine to reserve the window.

    Returns:

    Function value =
            0x0000 = Normal
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved by another user ID
            0x0020 = Invalid page offset
            0x0021 = Invalid page
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    ICABYTE userid;
    ICABYTE pgnum;
    unsigned short pgoff;
    ICABYTE databyte;
    unsigned int error;
    
    error = ICARBYTE(coproc, userid, pgnum, pgoff,
                     &databyte;);
    
    Related Topics:
         ICAWBYTE, ICARSV
    

    ICAREL

    Purpose:

    ICAREL releases use of a co-processor adapter page selector.
    
    Format:
    ICAREL (ICABYTE, /* Co-processor adapter number */
           ICABYTE);                      /* Userid */
    
    Remarks: ICAREL should be called to release the co-processor adapter page selector after the program is finished accessing co-processor adapter memory.

    Returns:

    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    ICABYTE userid;
    unsigned int error;
    
    error = ICAREL(coproc, userid);
    
    Related Topics:
         ICARSV
    

    ICARSET

    Purpose:

    ICARSET resets the co-processor adapter.
    
    Format:
    ICARSET (ICABYTE);    /* Co-processor adapter */
                          /* number               */
    
    Remarks:

    If the co-processor adapter does not successfully complete the power-on self-test, the function times out and returns an error.

    Returns:

    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    
    error = ICARSET(coproc);
    
    Related Topics:
         None
    

    ICARSTR

    Purpose:

    ICARSTR reads a memory block from a co-processor adapter
            at a specific page and offset.
    
    Format:
    ICARSTR (ICABYTE,/* Co-processor adapter number */
             ICABYTE,              /* Userid        */
             ICABYTE,              /* Page number   */
             unsigned short,       /* Page offset   */
             ICABYTE *,            /* & string      */
             unsigned short);      /* String length */
    
    Remarks:

    If the string crosses a page boundary, the ending characters are read from the next page. The memory window should be reserved with the ICARSV routine to reserve the window.

    Returns:

    DATA           = Data string
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved by another user ID
            0x0020 = Invalid page offset
            0x0021 = Invalid page
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    ICABYTE userid;
    unsigned short pagenum;
    unsigned short pageoff;
    ICABYTE strng[20];
    unsigned int error;
    
    error = ICARSTR(coproc, userid, pagenum, pageoff,
                    strng, 20);
    
    Related Topics: ICAWSTR

    ICARSV

    Purpose:

    ICARSV reserves use of a co-processor adapter
           page selector.
    
    Format:
    ICARSV (ICABYTE,/* Co-processor adapter number */
            ICABYTE);                    /* Userid */
    
    Remarks:

    The page selector should be reserved before attempting to access a co-processor adapter's memory.

    Returns:

    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc;
    ICABYTE userid;
    unsigned int error;
    
    error = ICARSV(coproc, userid);
    
    Related Topics:
         ICAREL
    

    ICASEG2P

    Purpose:

    ICASEG2P converts a segment address in co-processor adapter
             memory to the equivalent page address.
    
    Format:
    ICASEG2P (struct ICA_SEG_OFF,   /* Seg-offset   */
                                    /* address      */
              struct ICA_PAGE_OFF *,/* & Page-offset*/
                                    /* address      */
              ICABYTE);      /* Co-processor adapter*/
                             /* number              */
    
    Remarks:

    Ranges for the various page sizes are:

                              Page Range on
             Page Range on      All Other
    Page      Portmaster      Co-Processor
    Size      Adapter/A         Adapters       Offset Range
    
     8KB      0 to FFh          0 to 7Fh        0 to 1FFFh
    16KB      0 to 7Fh          0 to 3Fh        0 to 3FFFh
    32KB      0 to 3Fh          0 to 1Fh        0 to 7FFFh
    64KB      0 to 1Fh          0 to 0Fh        0 to FFFFh
    
    Note:
    On the Realtime Interface Co-Processor Portmaster Adapter/A adapter, this function converts the address assuming a one-to-one page mapping.
    Returns:
    PAGE           = Page number
    PAGE_OFFSET    = Offset in page
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0022 = Invalid segment offset
    
    Example:
    #include "icadecl.h"
    
    struct ICA_SEG_OFF segoff;
    struct ICA_PAG_OFF pagoff;
    ICABYTE coproc=0;
    unsigned int error;
    
    error = ICASEG2P(segoff, &pagoff;, coproc);
    
    Related Topics:
         ICAPAG2S
    

    ICASTAT

    Purpose:

    ICASTAT returns the primary status of a co-processor
            adapter task.
    
    Format:
    ICASTAT (ICABYTE,/* Co-processor adapter number */
             ICABYTE,              /* Task number   */
             ICABYTE *);           /* & Task status */
    
    Remarks:
    COPROCNUM      = Co-processor adapter number
    TASK           = Requested status owner
    
    Returns:
    STATUS         = Primary status of task
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    ICABYTE tasknum=1;
    ICABYTE taskstat;
    unsigned int error;
    
    error = ICASTAT(coproc, tasknum, &taskstat;);
    
    Related Topics:
         None
    

    ICASTATX

    Purpose:

    ICASTATX returns the offset, page pointer, and buffer size of the
             secondary status buffer of a co-processor adapter task.
    
    Format:
    ICASTATX (ICABYTE,   /* Co-processor adapter */
                         /* number               */
              ICABYTE,            /* Task number */
              struct ICABUFFER *);/* & ICABUFFER */
                                  /* structure   */
    
    Returns:
    PAGE           = Page of task's status buffer
    OFFSET         = Page offset of task's status
                     buffer
    LENGTH         = Byte size of task's status
                     buffer
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0002 = Invalid task number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    ICABYTE tasknum=1;
    struct ICABUFFER bufstruct;
    unsigned int error;
    
    error = ICASTATX(coproc, tasknum, &bufstruct;);
    
    Related Topics:
         None
    

    ICAVRET

    Purpose:

    ICAVRET returns all interrupt vectors acquired via the
    
    ICAVSET interface routine.  This routine should be called
            when the application is finished with the interrupt flags.
    
    Format:
    ICAVRET (ICABYTE);    /* Co-processor adapter */
    
    Returns:
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    unsigned int error;
    
    error = ICAVRET(coproc);
    
    Related Topics:
         ICAVSET
    

    ICAVSET

    Purpose:

    ICAVSET sets up the interrupt jump vector for all tasks
            on a co-processor adapter that interrupt the
            computer.  It also sets up the interrupt bit table for the
            specified co-processor adapter.
    
    Format:
    ICAVSET (ICABYTE);    /* Co-processor adapter */
    
    Remarks:

    Memory is allocated for MAXTASK vectors. This routine should be called before using the ICAQINT interface routine.

    Returns:

    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    unsigned int error;
    
    error = ICAVSET(coproc);
    
    Related Topics:
         ICAQINT, ICAVRET
    

    ICAWBYTE

    Purpose:

    ICAWBYTE writes a byte to the co-processor adapter
             at a specific page and offset.
    
    Format:
    ICAWBYTE (ICABYTE,    /* Co-processor adapter */
                          /* number               */
              ICABYTE,             /* Userid      */
              ICABYTE,             /* Page number */
              unsigned short,      /* Page offset */
              ICABYTE);            /* Data byte   */
    
    Remarks:

    The memory window should be reserved with the ICARSV routine before ICAWBYTE is called. ICAWBYTE should be called with the same user ID that was used in the ICARSV routine to reserve the window.

    Returns:

    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved by another user ID
            0x0020 = Invalid page offset
            0x0021 = Invalid page
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    ICABYTE userid=0;
    ICABYTE pagenum=1;
    unsigned short pageoff=0x1F;
    ICABYTE databyte=1;
    
    error = ICAWBYTE(coproc, userid, pagenum,
                     pageoff, databyte);
    
    Related Topics:
         ICARBYTE, ICARSV
    

    ICAWINDOW

    Purpose:

    ICAWINDOW changes the co-processor adapter page
              selector to point to a specific co-processor adapter
              storage page.  The page selector should already be
              reserved with the same user ID.
    
    Format:
    ICAWINDOW (ICABYTE,  /* Co-processor adapter */
                         /* number               */
               ICABYTE,        /* Page number    */
               ICABYTE;        /* Userid         */
               ICABYTE *);     /* & old CPU page */
    
    Returns:
    OLD_PAGE       = Old CPU page value
    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    ICABYTE pagenum=1;
    ICABYTE userid=0;
    ICABYTE oldpg;
    unsigned int error;
    
    error = ICAWINDOW(coproc, pagenum, userid, &oldpg;);
    
    Related Topics:
         None
    

    ICAWSTR

    Purpose:

    ICAWSTR writes a string to the co-processor adapter at a
            specific page and offset.
    
    Format:
    ICAWSTR (ICABYTE,/* Co-processor adapter number */
             ICABYTE,                /* Userid      */
             ICABYTE,                /* Page number */
             unsigned short,         /* Page offset */
             ICABYTE *,              /* & string    */
             unsigned short);        /* Length      */
    
    Remarks:

    If the string crosses a page boundary, the ending characters are written to the next page. The memory window should be reserved with the ICARSV routine before ICAWSTR is called. ICAWSTR should be called with the same user ID that was used in the ICARSV routine to reserve the window.

    Returns:

    Function value =
            0x0000 = Normal return code
            0x0001 = Invalid co-processor adapter
                     number
            0x0004 = Co-processor adapter inactive,
                     but parameters exist
            0x0005 = CPU page selector already
                     reserved by another user ID
            0x0020 = Invalid page offset
            0x0021 = Invalid page
    
    Example:
    #include "icadecl.h"
    
    ICABYTE coproc=0;
    ICABYTE userid=0;
    ICABYTE pagenum=1;
    unsigned short pageoff=0x1F;
    ICABYTE strng[10];
    unsigned short strlen=10;
    unsigned int error;
    
    error = ICAWSTR(coproc, userid, pagenum, pageoff,
                    strng, strlen);
    
    Related Topics:
         ICARSTR
    

    DOS SYSTEM UNIT PEER SERVICES

    The peer services provide a means for tasks to pass information among Realtime Interface Co-Processor Portmaster Adapter/A adapters and the system unit.

    The following section describes the peer services in DOS system unit support. Refer to the IBM Realtime Interface Co-Processor DOS Support Version 1.03 User's Guide for more information on peer services.


    ICAPEEROPEN

    Purpose:

    ICAPEEROPEN establishes an application as a peer task within the
                processor. The application provides a command handler
                routine that is called upon receipt of a peer command,
                and a peer handle is returned to identify the task.
    
    Format:
    int ICAPEEROPEN (unsigned int *);                /* Peer handle */
    void (far *)(struct ICA_PRBSTRUCT far *),
    
    Returns:
    PEERHANDLE from DOS interrupt handler
    Function value =
            0x000D = Peer handle not available
    
    Example:
    #include "icadecl.h"
    
    extern void far * peercmdhndler (struct
                        ICA_PRBSTRUCT far *);
    unsigned int peerhandle;
    unsigned int errcode;
    
    errcode = ICAPEEROPEN(&peerhandle;, peercmdhndler);
    
    Related Topics:
         ICAPEERCLOSE, ICAPEERSEND
    

    ICAPEERCLOSE

    Purpose:

    ICAPEERCLOSE returns a peer handle to the
                 system and prevents further reception of peer request blocks.
    
    Format:
    int ICAPEERCLOSE (unsigned int);                  /* Peer handle */
    
    Returns:
    Function value =
            0x000E = Unknown PeerHandle
    
    Example:
    #include "icadecl.h"
    
    unsigned int peerhandle;
    unsigned int errcode;
    
    errcode = ICAPEERCLOSE(peerhandle);
    
    Related Topics:
        ICAPEEROPEN, ICAPEERSEND
    

    ICAPEERSEND

    Purpose:

    ICAPEERSEND sends a peer request block to another peer task.
    
    Format:
    int ICAPEERSEND (struct ICA_PRBSTRUCT *);    /* Address of peer */
                                /* request block   */
    
    Remarks:
    REQPTR         = Address of peer request block
    
    Returns:
    Function value =
            0x0009 = Command not accepted
    
    Example:
    #include "icadecl.h"
    
    struct ICA_PRBSTRUCT reqblk;
    unsigned int errcode;
    
    errcode = ICAPEERSEND(&reqblk;);
    
    Related Topics:
         ICAPEEROPEN, ICAPEERCLOSE
    

    Chapter 4. OS/2 C Language Interfaces

    This chapter is for programmers writing applications to run on the system unit, using the application program interface of the Realtime Interface Co-Processor OS/2 Support. The information in this chapter should be used with other appropriate documents for your co-processor adapter.

    The Operating System/2 (OS/2) C Language Support for the System Unit is a collection of libraries of routines used to communicate with the co-processor adapter. The libraries provide routines for initialization, issuing commands, accessing co-processor adapter memory, and accessing co-processor adapter and task parameters.


    OS/2 Device Driver

    The OS/2 device driver (ICARICIO.SYS), supplied with the Realtime Interface Co-Processor OS/2 Support product, provides a software interface to the co-processor adapter through the Generic IOCtl interfaces or through dynamic link routines. It handles interrupts from the co-processor adapter and determines the task and which co-processor adapter contains the task that interrupted the system and signals the appropriate system unit processes. It reads the parameter file and configures the co-processor adapter accordingly.


    OS/2 Application Loader Utility

    The OS/2 application loader utility (ICALDRIC), supplied with the Realtime Interface Co-Processor OS/2 Support product, is a utility that is used to load the Realtime Control Microcode tasks from the system unit to the co-processor adapter. The application loader should be invoked to load Realtime Control Microcode and all tasks that run under the Realtime Control Microcode


    OS/2 Dynamic Link Routines

    Dynamic link routines provide a programming interface for system unit programs to the device driver and any installed co-processor adapters. They can be used for accessing co-processor adapter memory or interacting with co-processor adapter tasks.

    The dynamic link routines are defined in two files, ICARICDL.LIB and ICARICDL.DLL which are part of the IBM Realtime Interface Co-Processor OS/2 Support. ICARICDL.LIB contains link information; it should be linked with system unit programs that call the dynamic link routines. ICARICDL.DLL contains the dynamic link routine code. Insert the directory name where the file is located in the list of directories assigned to the LIBPATH variable in CONFIG.SYS so that OS/2 can find the code at run time.


    C Language Compiler Interfaces

    The C Language Compiler Interface consists of an include file, ICACALLS.H, which gives access to the dynamic link routines that come with the Realtime Interface Co-Processor OS/2 Support. The include file contains structure and library routine declarations that let an OS/2 application access the ICARICIO.SYS device driver and the co-processor adapter.

    User code should include the file ICACALLS.H and OS2.H (from the OS/2 Toolkit). Put the following lines in the source file of the system unit program:

         #include "os2.h"
         #include "icacalls.h" 
    
    When the IBM using C Set\2 compiler, it is necessary to include the header file "ICADOS1G.6" in the program: #include "ICADOS1G.6"

    Any memory model can be used in the user application. During the link step, the dynamic link routine library ICARICDL.LIB should be linked to the user's object module along with the standard C libraries. The following is one example of compiling and linking a C program to the C dynamic link routines. The parameters will vary, depending on the environment associated with installing the C compiler and OS/2:

         cc cprog;
         link cprog,,,slibcep os2 icaricdl;
    
    The following declarations define parameter types used by the C dynamic link routines. The "pascal" keyword in the C dynamic link routine declarations tell the compiler that the dynamic link routines follow the Pascal, not C, stack parameter passing standards.
    struct ICABufAddr { /* Input, Output, Secondary Status buffer addr */
            unsigned int    Length;    /* Byte length of buffer        */
            unsigned int    Offset;    /* Page offset of buffer        */
            unsigned char   Page;      /* Page of buffer               */
            };
    
    struct ICAParm {
            unsigned int    IOAddr;    /* Base I/O address             */
            unsigned char   Rsv1;      /* LAST indicator               */
            unsigned char   Meg;       /* Meg of shared storage window */
            unsigned char   Page;      /* Page of shared storage window*/
            unsigned char   MaxTask;   /* Largest task number          */
            unsigned char   MaxPri;    /* Largest priority value       */
            unsigned char   MaxQueue;  /* Largest queue number         */
            unsigned char   Maxtimer;  /* Largest software timer number*/
            unsigned char   CADHigh;   /* High byte of reset address   */
            unsigned int    CADLow;    /* Low word of reset address    */
            unsigned long   Rsv2;      /* Reserved                     */
            unsigned char   IntLevel;  /* Interrupt level              */
            unsigned int    Rsv3;      /* Reserved                     */
            unsigned char   PageSize;  /* Page size code               */
            };
    
    struct ICAExtParm {
            unsigned char   AdapterCode; /* Adapter type               */
            unsigned char   PhySlotNum;  /* Physical slot number       */
            unsigned char   EIBID0;    /* ID of elec interf board 0    */
            unsigned char   EIBID1;    /* ID of elec interf board 1    */
            unsigned char   ClkOpt;    /* Clocking options, ports 0 & 1*/
            unsigned char   ArbLevel;  /* Arbitration level (priority) */
            unsigned char   Rsv1;      /* Reserved 1                   */
            unsigned char   Rsv2;      /* Reserved 2                   */
            unsigned char   Rsv3;      /* Reserved 3                   */
            unsigned char   Rsv4;      /* Reserved 4                   */
            };
    
    struct ICAVersion {
            unsigned char   MinCode;   /* Version minor code           */
            unsigned char   MajCode;   /* Version major code           */
            };
    
    struct ICAPrbstruct {
            struct ICAPrbstruct far *QCHAINPTR;/* Pointer to queue chain.*/
            unsigned char CMDRESP;        /* Command response code.      */
            unsigned char COMPCODE;       /* Completion code.            */
            unsigned char PEEROPTNS;      /* Peer request option.        */
            unsigned char CMDOPTNS;       /* Command options.            */
            unsigned char TGTPROCID;      /* Target processor ID.        */
            unsigned char SRCPROCID;      /* Source processor ID.        */
            unsigned int TGTTASKID;       /* Target task ID.             */
            unsigned int SRCTASKID;       /* Source task ID.             */
            unsigned int REQBLKID;        /* Request block ID.           */
            unsigned int DATACOUNT;       /* Data byte count.            */
            unsigned int RSV1;            /* Reserved.  Must be 0.       */
            union
               {
               struct
                   {
                   unsigned char TGTCARDID;
                   unsigned char SRCCARDID;
                   } movinfo;
               unsigned int dataval;
               } DATAVAL1;          /* Data value 1 or immediate data.   */
            unsigned long DATAADD1; /* Target buffer addr or immed. data.*/
            unsigned long DATAADD2  /* Source buffer addr or immed. data.*/
            unsigned long DATAADD3; /* Data address or immediate data.   */
            unsigned char RSV2[8];  /* Reserved work area.               */
        };
    

    ICADEVCHANGEPAGE

    Purpose:

    ICADEVCHANGEPAGE changes the shared storage window to point to a
                     different page of co-processor adapter memory.
    
    Format:
    unsigned far pascal ICADEVCHANGEPAGE (
       HFILE,                      /* Device handle  */
       unsigned char, /* Co-processor adapter number */
       unsigned char, /* New CPU page register value */
       unsigned char far *);       /* & Old CPU page */
                                   /* register value */
    
    Remarks:

    The ICADEVCHANGEPAGE function can only be called by applications that have already reserved the shared storage window of the given co-processor adapter.

    Returns:

    OLD_PAGE       = Old page value returned
    Function value =
            0x0000 = No Error
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF07 = ERROR_ICA_INVALID_PAGE
            0xFF0A = ERROR_ICA_WIN_RESERVED
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc;
    unsigned char newcpu;
    unsigned char oldcpu;
    unsigned int error;
    
    error = ICADEVCHANGEPAGE(DevHandle, coproc, newcpu,
                             &oldcpu;);
    
    Related Topics:
         ICADEVWINRESWAIT, ICADEVWINRESNOWAIT, ICADEVWINRELEASE
    

    ICADEVGETINBUF

    Purpose:

    ICADEVGETINBUF reads the contents of a task's input buffer.
    
    Format:
    unsigned far pascal ICADEVGETINBUF (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       unsigned char far *, /* & destination buffer */
       unsigned far *);     /* & length of buffer   */
                            /* to read              */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
            0xFF0C = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc;
    unsigned char tasknum;
    unsigned char destbuf[1024];
    unsigned *buflen;
    unsigned int error;
    
    buflen = 1024;
    error = ICADEVGETINBUF(DevHandle, coproc, tasknum,
                           destbuf, &buflen;);
    
    Related Topics:
         ICADEVPUTOUTBUF, ICADEVGETSECSTATUS, ICADEVOUTBUF,
         ICADEVINBUF, ICADEVSECSTATUS
    

    ICADEVGETPARMS

    Purpose:

    ICADEVGETPARMS gets the configuration parameters
                   for a given co-processor adapter.
    
    Format:
    unsigned far pascal ICADEVGETPARMS (
      HFILE,                /* Device handle        */
      unsigned char,        /* Co-processor adapter */
                            /* number               */
      struct ICAParm far *);/* & Parameter buffer   */
    
    Remarks:

    The ICADEVGETPARMS function returns a 20-byte record containing the configuration parameters for the given co-processor adapter. Verify that there is enough space to receive the configuration parameters.

    Returns:

    Co-processor adapter parameters listed in the ICAParm structure.
    
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    struct ICAParm parms;
    HFILE DevHandle;
    unsigned char coproc;
    unsigned int error;
    
    error = ICADEVGETPARMS(DevHandle, coproc, &parms;);
    
    Related Topics:
         ICADEVGETEXTPARMS
    

    ICADEVGETEXTPARMS

    Purpose:

    ICADEVGETEXTPARMS gets the extended configuration parameters for a
                      given co-processor adapter.
    
    Format:
    unsigned far pascal ICADEVGETEXTPARMS (
      HFILE,               /* Device handle        */
      unsigned char,       /* Co-processor adapter */
                           /* number               */
      unsigned char,       /* Buffer length        */
      struct ICAExtParm far *);/* & Extended       */
                               /* parameter buffer */
    
    Remarks:

    The ICADEVGETEXTPARMS function returns a record containing the extended configuration parameters for the given co-processor adapter. Verify that there is enough space to receive the configuration parameters.

    Returns:

    Co-processor adapter parameters listed in ICAExtParm.
    
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc;
    unsigned char buflen = sizeof(struct ICAExtParm);
    struct ICAExtParm extparms;
    unsigned int error;
    
    error = ICADEVGETEXTPARMS(DevHandle, coproc,
                              buflen, &extparms;);
    
    Related Topics:
         ICADEVGETPARMS
    

    ICADEVGETSECSTATUS

    Purpose:

    ICADEVGETSECSTATUS reads the contents of a task's secondary status
                       buffer.
    
    Format:
    unsigned far pascal ICADEVGETSECSTATUS (
      HFILE,               /* Device handle        */
      unsigned char,       /* Co-processor adapter */
                           /* number               */
      unsigned char,       /* Task number          */
      unsigned char far *, /* & Destination buffer */
      unsigned far *,      /* & Length of buffer   */
                           /* to read              */
      unsigned char);      /* Status flag byte     */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
            0xFF0C = ERROR_ICA_STATUS_NOT_READY
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc, tasknum;
    unsigned char buffer [100];
    unsigned char buflen = 100;
    unsigned char stat = 0x01;
    unsigned int error;
    
    error = ICADEVGETSECSTATUS(DevHandle, coproc,
                  tasknum, buffer, &buflen;, stat);
    
    Related Topics:
         ICADEVGETINBUF, ICADEVPUTOUTBUF, ICADEVINBUF,
         ICADEVOUTBUF, ICADEVSECSTATUS
    

    ICADEVGETVERSION

    Purpose:

    ICADEVGETVERSION returns the version of the device driver.
    
    Format:
    unsigned far pascal ICADEVGETVERSION (
      HFILE,                   /* Device handle       */
      struct ICAVersion far *);/* & Extended parameter*/
                               /* buffer              */
    
    Returns:

    No error codes are returned by this function.

    Example:

    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    struct ICAVersion ver;
    
    ICADEVGETVERSION(DevHandle, &ver;);
    
    Related Topics:
         ICADEVGETPARMS, ICADEVGETEXTPARMS
    

    ICADEVINPUTBUFFER

    Purpose:

    ICADEVINPUTBUFFER reads the address of a task's input buffer from
                      the task's Buffer Control Block.
    
    Format:
    unsigned far pascal ICADEVINPUTBUFFER (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       struct ICABufAddr far *);/* & Address        */
                                /* structure        */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc;
    unsigned char tasknum;
    struct ICABufAddr inbuf;
    unsigned int error;
    
    error = ICADEVINPUTBUFFER(DevHandle, coproc,
                              tasknum, &inbuf;);
    
    Related Topics:
         ICADEVOUTPUTBUFFER, ICADEVSECSTATUS, ICADEVOUTBUF,
         ICADEVGETINBUF, ICADEVPUTOUTBUF
    

    ICADEVISSUECOMMAND

    Purpose:

    ICADEVISSUECOMMAND issues a command with parameters to a task.
    
    Format:
    unsigned far pascal ICADEVISSUECOMMAND (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       unsigned char,       /* Command code         */
       unsigned char far *, /* & Source buffer      */
       unsigned,            /* Length of buffer to  */
                            /* write                */
       unsigned);           /* Max milliseconds to  */
                            /* wait                 */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
            0xFF0B = ERROR_ICA_TIMEOUT
            0xFF11 = ERROR_ICA_BAD_PCSELECT
            0xFF12 = ERROR_CMD_REJECTED
            0xFF14 = ERROR_ICA_OB_TOO_SHORT
            0xFF1C = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc;
    unsigned char tasknum;
    unsigned char cmd;
    unsigned char parmbuf[10];
    unsigned int parmlen = 10;
    unsigned int waitlen = 100;
    unsigned int error;
    
    error = ICADEVISSUECOMMAND(DevHandle, coproc,
            tasknum, cmd, parmbuf, parmlen, waitlen);
    
    Related Topics:
         ICADEVPRIMARYSTATUS
    

    ICADEVNOTIFY

    Purpose:

    ICADEVNOTIFY registers a semaphore with the device driver for
                 notification of special events.
    
    Format:
    unsigned far pascal ICADEVNOTIFY (
       HFILE,              /* Device handle        */
       unsigned char,      /* Co-processor adapter */
                           /* number               */
       unsigned char,      /* Control byte         */
       HSEM);              /* Semaphore ID         */
    
    Remarks:

    The Semaphore parameter is a handle returned by the DosCreateSem OS/2 function. The semaphore should be made non-exclusive by the DosCreateSem call.

    The control byte indicates the events for which the semaphore should be registered. A value of 0x80 means the semaphore should be registered for initialize commands issued to RCM on the given co-processor adapter.

    Returns:

    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF0D = ERROR_ICA_INVALID_CONTROL
            0xFF15 = ERROR_ICA_SEM_FULL
            0xFF1D = ERROR_ICA_BAD_SEMAPHORE
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned notifyctrl = 0x80;
    HSEM semhan;
    unsigned int error;
    
    bufptr = (unsigned char far *) buffer;
    error = ICADEVNOTIFY(DevHandle, coproc, notifyctrl,
                         semhan);
    
    Related Topics:
         ICADEVREMNOTIFY
    

    ICADEVOUTPUTBUFFER

    Purpose:

    ICADEVOUTPUTBUFFER reads the address of a task's output buffer from
                       the task's buffer control block.
    
    Format:
    unsigned far pascal ICADEVOUTPUTBUFFER (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       struct ICABufAddr far *);/* & Address        */
                                /* structure        */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
            0xFF1C = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned char tasknum = 2;
    struct ICABufAddr outbuf;
    unsigned int error;
    
    error = ICADEVOUTPUTBUFFER(DevHandle, coproc,
                               tasknum, &outbuf;);
    
    Related Topics:
         ICADEVINPUTBUFFER, ICADEVSECSTATUS, ICADEVPUTOUTBUF,
         ICADEVGETSECSTATUS, ICADEVGETINBUF
    

    ICADEVPRIMARYSTATUS

    Purpose:

    ICADEVPRIMARYSTATUS reads the primary status byte for a given task.
    
    Format:
    unsigned far pascal ICADEVPRIMARYSTATUS (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       unsigned char far *);/* & Returned primary   */
                            /* status               */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROC_ICA_INVALID_TASK_STATUS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned char tasknum = 0;
    unsigned char psb;
    unsigned int error;
    
    error = ICADEVPRIMARYSTATUS(DevHandle, coproc,
                                tasknum, &psb;);
    
    Related Topics:
         None
    

    ICADEVPUTOUTBUF

    Purpose:

    ICADEVPUTOUTBUF writes a buffer to the given task's output buffer.
    
    Format:
    unsigned far pascal ICADEVPUTOUTBUF (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       unsigned char far *, /* & source buffer      */
       unsigned far *);     /* Length of buffer     */
                            /* to write             */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned char tasknum = 2;
    unsigned char buffer [10];
    unsigned int buflen = 10;
    unsigned int error;
    
    error = ICADEVPUTOUTBUF(DevHandle, coproc, tasknum,
                            buffer, &buflen;);
    
    Related Topics:
         ICADEVGETINBUF, ICADEVGETSECSTATUS, ICADEVSECSTATUS,
         ICADEVINPUTBUFFER, ICADEVOUTPUTBUFFER.
    

    ICADEVREADSTRING

    Purpose:

    ICADEVREADSTRING reads a given co-processor adapter's
                     memory into a system unit buffer.
    
    Format:
    unsigned far pascal ICADEVREADSTRING (
       HFILE,           /* Device handle            */
       unsigned char,   /* Co-processor adapter     */
                        /* number                   */
       unsigned,        /* Length of buffer to read */
       unsigned,        /* Address segment or page  */
       unsigned,        /* Address offset           */
       unsigned char,   /* Address format byte      */
                        /*   0x00FF=page:offset     */
                        /*   0x0000=segment:offset  */
                        /*   0x0001=32-bit physical */
                                    address
       unsigned char far *);/* & Destination buffer */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF07 = ERROR_ICA_INVALID_PAGE
            0xFF08 = ERROR_ICA_INVALID_OFFSET
            0xFF09 = ERROR_ICA_INVALID_FORMAT
            0xFF1C = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned int buflen = 100;
    unsigned int addrpage = 0;
    unsigned int addroffset = 0x440;
    unsigned char buffer [100];
    unsigned char addrformat = 0xFF;
    unsigned int error;
    
    error = ICADEVREADSTRING(DevHandle, coproc, buflen,
               addrpage, addroffset, addrformat, buffer);
    
    Related Topics:
         ICADEVWRITESTRING
    

    ICADEVREGSEMAPHORE

    Purpose:

    ICADEVREGSEMAPHORE registers a semaphore with the device driver.
    
    Format:
    unsigned far pascal ICADEVREGSEMAPHORE (
       HFILE,             /* Device handle        */
       unsigned char,     /* Co-processor adapter */
                          /* number               */
       unsigned char,     /* Task number          */
       HSEM);             /* Semaphore ID         */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
            0xFF15 = ERROR_ICA_SEM_FULL
            0xFF1D = ERROR_ICA_BAD_SEMAPHORE
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned char tasknum = 0;
    HSEM semhan;
    unsigned int error;
    
    error = ICADEVREGSEMAPHORE(DevHandle, coproc,
                               tasknum, semhan);
    
    Related Topics:
         ICADEVREMSEMAPHORE
    

    ICADEVREMNOTIFY

    Purpose:

    ICADEVREMNOTIFY removes a semaphore from the device
                    driver list for notification of special events.
    
    Format:
    unsigned far pascal ICADEVREMNOTIFY (
       HFILE,             /* Device handle        */
       unsigned char,     /* Co-processor adapter */
                          /* number               */
       unsigned char,     /* Control byte         */
       HSEM);             /* Semaphore ID         */
    
    Remarks:

    The control byte indicates the events for which the semaphore should be registered. A value of 0x80 means the semaphore should be registered for initialize commands issued to RCM on the given co-processor adapter.

    Returns:

    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF0D = ERROR_ICA_INVALID_CONTROL
            0xFF1D = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned char notifyctrl = 0x80;
    HSEM semhan;
    unsigned int error;
    
    error = ICADEVREMNOTIFY(DevHandle, coproc,
                            notifyctrl, semhan);
    
    Related Topics:
         ICADEVNOTIFY
    

    ICADEVREMSEMAPHORE

    Purpose:

    ICADEVREMSEMAPHORE removes a semaphore from the device
                       driver's list of registered semaphores.
    
    Format:
    unsigned far pascal ICADEVREMSEMAPHORE (
       HFILE,            /* Device handle        */
       unsigned char,    /* Co-processor adapter */
                         /* number               */
       unsigned char,    /* Task number          */
       HSEM);            /* Semaphore ID         */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
            0xFF1D = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned char tasknum = 3;
    HSEM semhan;
    unsigned int error;
    
    error = ICADEVREMSEMAPHORE(DevHandle, coproc,
                               tasknum, semhan);
    
    Related Topics:
         ICADEVREGSEMAPHORE
    

    ICADEVRESET

    Purpose:

    ICADEVRESET issues a hardware reset to the given co-processor adapter.
                The Realtime Control Microcode and all other tasks are unloaded.
                The co-processor adapter also goes through its power-on self-test.
    
    Format:
    unsigned far pascal ICADEVRESET (
       HFILE,             /* Device handle        */
       unsigned char);    /* Co-processor adapter */
                          /* number               */
    
    Returns:
    Function value =
            0x0000 = No Error
            0xFF05 = ERROR_ICA_INVALID_COPROC
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned int error;
    
    error = ICADEVRESET(DevHandle, coproc);
    
    Related Topics:
         None
    

    ICADEVSECSTATUS

    Purpose:

    ICADEVSECSTATUS reads the address of a task's secondary status
                    buffer from the task's buffer control block.
    
    Format:
    unsigned far pascal ICADEVSECSTATUS (
       HFILE,               /* Device handle        */
       unsigned char,       /* Co-processor adapter */
                            /* number               */
       unsigned char,       /* Task number          */
       struct ICABufAddr far *); /* & Address       */
                                 /* structure       */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF06 = ERROR_ICA_INVALID_TASK_STATUS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned char tasknum = 0;
    struct ICABufAddr statbuf;
    unsigned int error;
    
    error = ICADEVSECSTATUS(DevHandle, coproc, tasknum,
                            &statbuf;);
    
    Related Topics:
         ICADEVINPUTBUFFER, ICADEVOUTPUTBUFFER, ICADEVPUTOUTBUF
         ICADEVGETSECSTATUS, ICADEVGETINBUF
    

    ICADEVTASKFLUSH

    Purpose:

    ICADEVTASKFLUSH removes any window requests by the calling process,
                    releases any co-processor adapter windows owned
                    by the calling process, and de-registers any
                    semaphores registered with the device driver by the
                    calling process.
    
    Format:
    unsigned far pascal ICADEVTASKFLUSH (
            HFILE);        /* Device driver handle */
    
    Remarks

    This function can be used in an application exit routine to release resources before terminating the process.

    Returns:

    No error codes are returned by this routine.

    Example:

    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned int error;
    
    error = ICADEVTASKFLUSH(DevHandle);
    
    Related Topics:
         None
    

    ICADEVWINRELEASE

    Purpose:

    ICADEVWINRELEASE releases ownership of a co-processor adapter shared
                     storage window.
    
    Format:
    unsigned far pascal ICADEVWINRELEASE (
       HFILE,              /* Device handle        */
       unsigned char);     /* Co-processor adapter */
                           /* number               */
    
    Returns:
    Function value =
            0x0000 = No Error
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF0A = ERROR_ICA_WIN_NOT_OWNED
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned int error;
    
    error = ICADEVWINRELEASE(DevHandle, coproc);
    
    Related Topics:
         ICADEVWINRESWAIT, ICADEVWINRESNOWAIT
    

    ICADEVWINRESNOWAIT

    Purpose:

    ICADEVWINRESNOWAIT requests ownership of a co-processor
                       adapter shared storage window.
                       The call returns a value that specifies if the
                       window is already owned.
    
    Format:
    unsigned far pascal ICADEVWINRESNOWAIT (
       HFILE,                       /* Device handle*/
       unsigned char, /* Co-processor adapter number*/
       unsigned char far * far *,
                      /* 32-bit address  of window  */
       PPID,          /* & Process ID of owner, if  */
                      /* reserved                   */
       PTID);         /* & Thread ID of owner, if   */
                      /* reserved                   */
    
    Returns:
    Function value =
            0x0000 = No Error
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF0A = ERROR_ICA_WIN_NOT OWNED
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned char far *windowptr;
    PPID pid;
    PTID tid;
    unsigned int error;
    
    error = ICADEVWINRESNOWAIT(DevHandle, coproc,
                           &windowptr;, &pid;, &tid;);
    
    Related Topics:
         ICADEVWINRESWAIT, ICADEVWINRELEASE
    

    ICADEVWINRESWAIT

    Purpose:

    ICADEVWINRESWAIT requests ownership of a co-processor adapter shared
                     storage window.  The process is blocked if the window
                     is already owned.
    
    Format:
    unsigned far pascal ICADEVWINRESWAIT (
       HFILE,                       /* Device handle */
       unsigned char, /* Co-processor adapter number */
       unsigned char far * far *, /* & Window address*/
       unsigned long);            /* Time-out in     */
                                  /* milliseconds    */
    
    Returns:
    Function value =
            0x0000 = No Error
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF0B = ERROR_ICA_TIMEOUT
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 0;
    unsigned char far *winptr;
    unsigned long timeout = 1000;
    unsigned int error;
    
    error = ICADEVWINRESWAIT(DevHandle, coproc, &winptr;,
                             timeout);
    
    Related Topics:
         ICADEVWINRESNOWAIT, ICADEVWINRELEASE
    

    ICADEVWRITESTRING

    Purpose:

    ICADEVWRITESTRING writes a system unit buffer to co-processor
                      adapter memory.
    
    Format:
    unsigned far pascal ICADEVWRITESTRING (
       HFILE,           /* Device handle            */
       unsigned char,   /* Co-processor adapter     */
                        /* number                   */
       unsigned,        /* Length of buffer to write*/
       unsigned,        /* Address segment or page  */
       unsigned,        /* Address offset           */
       unsigned char,   /* Address format byte      */
                        /*   0x00FF=page:offset     */
                        /*   0x0000=segment:offset  */
                        /*   0x0001=32-bit physical */
                        /*          address         */
       unsigned char far *);/* & Source buffer      */
    
    Returns:
    Function value =
            0xFF05 = ERROR_ICA_INVALID_COPROC
            0xFF07 = ERROR_ICA_INVALID_PAGE
            0xFF08 = ERROR_ICA_INVALID_OFFSET
            0xFF09 = ERROR_ICA_INVALID_FORMAT
            0xFF1C = ERROR_ICA_BAD_ADDRESS
    
    Note: For Realtime Interface Co-Processor Portmaster Adapter/A,
          logical segment:offset addresses are converted to
          page:offset addresses assuming a direct memory mapping.
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char coproc = 1;
    unsigned int buflen = 200;
    unsigned int seg = 0x1000;
    unsigned int off = 0;
    unsigned char addrformat = 0;
    unsigned char buffer [200];
    unsigned int error;
    
    error = ICADEVWRITESTRING(DevHandle, coproc, buflen,
                            seg, off, addrformat, buffer);
    
    Related Topics:
         ICADEVREADSTRING
    

    OS/2 SYSTEM UNIT PEER SERVICES

    The peer services provide a means for tasks to pass information among Realtime Interface Co-Processor Portmaster Adapter/A adapters and the system unit.

    The following section describes the peer services in OS/2 system unit support. Refer to the IBM Realtime Interface Co-Processor OS/2 Support User's Guide for more information on peer services.


    ICADEVLOCK

    Purpose:

    ICADEVLOCK locks a segment and obtains its physical address;
               the locked memory can then be used for bus master
               transfers via the peer services.
    
    Format:
    unsigned far pascal ICADEVLOCK (
       HFILE,                /* Device handle      */
       unsigned int,         /* Selector to lock   */
       unsigned long far *,  /* & Physical address */
       unsigned long far *); /* & Lock handle      */
    
    Remarks:

    The ICADEVLOCK routine is only required when using the peer services to transfer data via the Realtime Interface Co-Processor Portmaster Adapter/A bus master channels.

    Returns:

    Function value =
            0xFF1C = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned char buffer [1024];
    unsigned char far *bufptr;
    unsigned long physaddr;
    unsigned long lockhandle;
    unsigned int error;
    
    bufptr = (unsigned char far *) buffer;
    error = ICADEVLOCK(DevHandle, FP_SEG (bufptr),
                       &physaddr;, &lockhandle;);
    
    Related Topics:
         ICADEVUNLOCK
    

    ICADEVPEEROPEN

    Purpose:

    ICADEVPEEROPEN establishes an application as a peer task within
                   the system unit.
    
    Format:
    unsigned far pascal ICADEVPEEROPEN (
       HFILE,                /* Device handler */
       unsigned int,         /* Buffer size    */
       unsigned int far *);  /* Peer handle    */
    
    Remarks:

    ICADEVPEEROPEN allocates a block of memory and a semaphore for a peer task. The semaphore and memory are then passed to the driver to manage incoming peer requests.

    Returns:

    Function value =
            0xFF16 = ERROR_ICA_NO_PEER_HAND
            0xFF1E = ERROR_NOT_ENOUGH_MEMORY
            0xFF22 = ERROR_TOO_MANY_SEMAPHORES
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned int BuffSize;
    unsigned int PeerHandle;
    unsigned int error;
    
    BuffSize = 1024;
    error = ICADEVPEEROPEN(DevHandle, BuffSize,
                           &PeerHandle;);
    
    Related Topics:
         ICADEVPEERSEND, ICADEVPEERCLOSE, ICADEVPEERRECEIVE,
         ICADEVPEERRECEIVEDONE
    

    ICADEVPEERCLOSE

    Purpose:

    ICADEVPEERCLOSE returns a peer handle to the system and
                    prevents further reception of peer request blocks.
    
    Format:
    unsigned far pascal ICADEVPEERCLOSE (
       HFILE,              /* Device handle    */
       unsigned int,       /* Peer handle      */
       unsigned int);      /* Disposition code */
    
    Remarks:

    A disposition code is provided to determine the handling of any unprocessed peer request blocks.

    Returns:

    Disposition codes =
               0x0000 = DISP_PURGE
               0x0001 = DISP_FAIL
    Function value    =
               0xFF20 = ERROR_ICA_UNKNOWN_PEER
               0xFF1F = ERROR_ICA_UNKNOWN_DISPOSITION
               0xFF18 = ERROR_ICA_REQS_REMAIN
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned int PeerHandle;
    unsigned int DispCode;
    unsigned int error;
    
    DispCode= 0;
    error = ICADEVPEERCLOSE(DevHandle, PeerHandle,
                            DispCode);
    
    Related Topics:
         ICADEVPEERSEND, ICADEVPEEROPEN,ICADEVPEERRECEIVE,
         ICADEVPEERRECEIVEDONE
    

    ICADEVPEERRECEIVE

    Purpose:

    ICADEVPEERRECEIVE receives peer request
                           blocks from the fixed queue.
    
    Format:
    unsigned far pascal ICADEVPEERRECEIVE (
       unsigned int,                   /* Peer handle*/
       unsigned lon,;                  /* Time out   */
       struct ICAPrbstruct far * far *,/* Request    */
       unsigned int far *);      /* Count of request */
                                 /* blocks           */
    
    Remarks:

    The ICADEVPEERRECEIVE routine returns a pointer to a list of peer request blocks and a count of request blocks in the list.

    If a time-out is specified and no peer request blocks are available, the semaphore created by ICADEVPEEROPEN is used to block the thread.

    REQUEST    = pointer to a list of peer request
                 blocks
    REQCOUNT   = count of request blocks in the list
    TIMEOUT    = 0  Causes ICADEVPEERRECEIVE to return
                    immediately with an error if no
                    peer request blocks are available
                    to receive.
                -1  Wait forever
                 n  Number of milliseconds to wait for
                    a peer request block; must be
                    greater than 0.
    
    Returns:
    Function value =
            0xFF0B = ERROR_ICA_TIMEOUT
            0xFF17 = ERROR_BAD_HANDLE
            0xFF19 = ERROR_ICA_NO_REQS
            0xFF1A = ERROR_RCV_SEQ_ERR
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    unsigned int PeerHandle;
    unsigned long timeout;
    struct ICAPrbstruct far * request;
    unsigned int reqblkcnt;
    unsigned int error;
    
    error = ICADEVPEERRECEIVE(PeerHandle, timeout,
                              &request;, &reqblkcnt;);
    
    Related Topics:
         ICADEVPEERRECEIVEDONE, ICADEVPEEROPEN, ICADEVPEERCLOSE,
         ICADEVPEERSEND
    

    ICADEVPEERRECEIVEDONE

    Purpose:

    ICADEVPEERRECEIVEDONE indicates that the peer processor task
                          (thread) is done with the peer request blocks
                          received on the previous ICADEVPEERRECEIVE.
    
    Format:
    extern unsigned far pascal ICADEVPEERRECEIVEDONE (
       unsigned int);        /* Peer handle */
    
    Remarks:

    ICADEVPEERRECEIVEDONE must be issued after every ICADEVPEERRECEIVE call to free the storage of the received peer request blocks.

    Returns:

    Function value =
            0xFF17 = ERROR_ICA_BAD_HANDLE
            0xFF1A = ERROR_RCV_SEQ_ERR
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    unsigned int PeerHandle;
    unsigned int errcode;
    
    errcode = ICADEVPEERRECEIVEDONE(PeerHandle);
    
    Related Topics:
         ICADEVPEERRECEIVE, ICADEVPEEROPEN, ICADEVPEERCLOSE,
         ICADEVPEERSEND
    

    ICADEVPEERSEND

    Purpose:

    ICADEVPEERSEND sends a peer request block to another peer task.
    
    Format:
    unsigned far pascal ICADEVPEERSEND (
       HFILE,                      /* Device handle */
       struct ICAPrbstruct far *); /* Request       */
    
    Returns:
    Function value =
            0xFF1C = ERROR_ICA_BAD_ADDRESS
            0xFF1E = ERROR_ICA_NOT_ENOUGH_MEMORY
            0xFF21 = ERROR_ICA_BAD_PARM
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    struct ICAPrbstruct Request;
    unsigned int error;
    
    error = ICADEVPEERSEND(DevHandle, &Request;);
    
    Related Topics:
         ICADEVPEEROPEN, ICADEVPEERCLOSE, ICADEVPEERRECEIVE,
         ICADEVPEERRECEIVEDONE
    

    ICADEVUNLOCK

    Purpose:

    ICADEVUNLOCK unlocks a segment previously locked with ICADEVLOCK.
    
    Format:
    unsigned far pascal ICADEVUNLOCK (
         HFILE,          /* Device handle         */
         unsigned long); /* Lock handle to unlock */
    
    Returns:
    Function value =
            0xFF1C = ERROR_ICA_BAD_ADDRESS
    
    Example:
    #include "os2.h"
    #include "icacalls.h"
    
    HFILE DevHandle;
    unsigned long lockhandle;
    unsigned int error;
    
    error = ICADEVUNLOCK(DevHandle, lockhandle);
    
    Related Topics:
         ICADEVLOCK
    

    Chapter 5. Writing System Unit Applications Tasks

    System unit applications perform three basic operations when communicating with co-processor adapter tasks:


    Exchanging Data

    System unit applications transfer data to and from the co-processor adapter, usually through the shared storage window. This window is an unused contiguous ROM or RAM area in the system unit. (Unused means that no RAM or ROM from another adapter is installed in the RAM or ROM selected.) On the Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport, and Realtime Interface Co-Processor Multiport Adapter, Model 2, the window size is always 8KB. On the Realtime Interface Co-Processor Multiport/2, X.25 Interface Co-Processor/2, X.25 Interface Co-Processor, and Realtime Interface Co-Processor Portmaster Adapter/A, the window size can be configured to 8KB, 16KB, 32KB, or 64KB.

    Shared Storage Window: The DOS Interrupt Handler or the OS/2 Device Driver initializes the co-processor adapter to establish the shared storage window. Once the co-processor adapter has set up the shared storage window, all memory accesses to addresses in the window are mapped into co-processor adapter storage. For the Realtime Interface Co-Processor Multiport/2, the DOS Interrupt Handler or OS/2 Device Driver first checks the configuration parameters file and then checks the system POS registers. If the two are different, the interrupt handler/device driver assumes the values in the POS registers.

    Once the shared storage window is configured on the co-processor adapter, system unit applications can access the shared storage. System unit applications can be written with the address of the start of the window hard coded or as a start parameter. A more flexible way is to use either the Assembly Interface (for assembly language programs) or the C Language Interface (for programs written in C language). The ICALOC routine reads a configuration register on the co-processor adapter and returns the shared storage window segment. OS/2 applications can use the ICADEVWINRESWAIT or ICADEVWINRESNOWAIT dynamic link routines to obtain the address of the window segment.

    CPU Page Register: When the start address of the shared storage window is known to a system unit application, all that remains to be done to access co-processor adapter storage is to select the correct page. The system unit application can now access all of co-processor adapter storage (in blocks the size of a page) by altering the value of the CPU page register.

    The formula for determining what physical co-processor adapter address the system unit application will access is:

         co-processor adapter physical address =
         (page_value * page_size) + offset_into_window
    
    There are two ways to change the CPU page register value: use an (I/O) write directly to the CPU page register or the ICAWINDOW assembly or high-level support routine. The base I/O address of the co-processor adapter must be known in order to write directly to the CPU page register.

    The first way to alter the CPU page value is to write the page number directly to the co-processor adapter CPU page register. The address of this register is the base address plus 5. System unit applications can determine the base I/O address by using ICAFPARM, a routine used to return a pointer to a logical co-processor adapter's configuration parameter record (stored in the DOS Interrupt Handler or the OS/2 Device Driver).

    The second way to alter the CPU page value is to use the ICAWINDOW routine in DOS or the OS/2 ICADEVCHANGEPAGE dynamic link routine. The previous method requires some up-front calculations; this method does not. Once the I/O address is known, changing the CPU page register can be done efficiently. ICAWINDOW requires no up-front work and adheres to reserve/ release standard, which can be required in a multitasking environment.

    The base address of the shared storage window (stored in the co-processor adapter location register) is a static address determined at system configuration time. It is configured when the DOS Interrupt Handler or the OS/2 Device Driver is loaded. The CPU page is a dynamic entity that frequently changes whenever a different page of co-processor adapter storage needs to be accessed. The offset into the shared storage window must never equal or exceed the page size. When this happens, co-processor adapter storage is no longer being accessed.

    Where to Read and Write Data: The next step in exchanging data with a Realtime Control Microcode task is to write or read data to or from co-processor adapter storage. Each task running under the Realtime Control Microcode is assigned a Buffer Control Block (BCB). The BCB contains the address and length of the task buffer to be used in system unit application/Realtime Control Microcode task communication. The task maintains the BCB to contain current pointers. The normal operation is to have the system unit application examine a task's BCB and read or write accordingly.

    There are two ways to obtain the pointers in a BCB: calculate the address and access the BCB directly or use one of the support routines (ICAINBUF, ICAOUTBUF, or ICASTATX in DOS, and ICADEVINPUTBUFFER, ICADEVOUTPUTBUFFER, or ICADEVSECSTATUS in OS/2).

    To access the BCBs directly, the address must be known. All BCBs reside in page 0 (zero) of co-processor adapter storage. A pointer to the first BCB is found in the Interface Block (IB), which is also in page 0. Because task BCBs are 16 bytes and the BCBs are in order of increasing task number, the address formula of a BCB is:

         BCB address in page 0 = BCB_start_address + (task_# * 16)
    
    After this offset is calculated and the CPU page register is changed to page 0, the BCB can be accessed at this offset into the shared storage window. Pointers and lengths to the input buffer, output buffer, and secondary status can be extracted from this BCB.

    The second and recommended way to get this information is to use the DOS Support routines or OS/2 dynamic link routines mentioned above. These routines have the standard interface shared among the other support routines. They take the logical co-processor adapter number and task number as input and return the page, offset, and length of the requested buffer. As with all of the other support routines, error checking is performed.

    Once the page, offset, and length of a buffer are known, the CPU page register must be altered. The buffer can be accessed at the given offset into the shared storage window. System unit applications should examine the length field to avoid overwriting a buffer.

    Applications should also ensure that no read or write crosses a page boundary. Any offset greater than or equal to the page size indicates that a page boundary has been crossed. When this happens, the CPU page must be incremented and the offset returned to 0. The DOS Support routines ICARSTRNG and ICAWSTRNG and the OS/2 dynamic link routines ICADEVREADSTRING and ICADEVWRITESTRING support reading and writing across page boundaries.

    Data Interlock: System unit applications and the Realtime Control Microcode tasks should establish some form of data interlock. For example, when a Realtime Control Microcode task presents a data buffer to a system unit application, there is a need for the task to know when the system unit application is finished processing the buffer.

    Conversely, when the system unit application writes data into a task's buffer, the system unit application must have some indication that the buffer is either free, busy, or in the process of being changed. The Realtime Control Microcode supports this interlock with the Primary Status byte and the Freebuffer command. The Primary Status byte of a task can be examined in the same two ways as the BCB. The DOS Support routine for this is ICASTAT. For OS/2 Support, the dynamic link routine is ICADEVGETPRIMARYSTATUS.


    Handling Interrupts With DOS Support

    A DOS-supported interrupt can be accomplished through:

    Communication Interlock: The Realtime Interface Co-Processor DOS Support initiates data exchanges and commands via interrupts. The system unit application can interrupt a Realtime Control Microcode task and a Realtime Control Microcode task can interrupt a system unit application.

    To interrupt a task on the co-processor adapter, write the task number into the PC select byte of the Interface Block and then write a 09h to the pointer register.

    A DOS system unit application can also interrupt a Realtime Control Microcode task by using either the ICACMD or ICANCMD macro, or the high-level language support routine. The routine places a command in the task's BCB and interrupts the task's command handler. Refer to "Application Commands" for more information on issuing commands to tasks.

    To obtain the pointer register address, add 2 to the base I/O address of the co-processor adapter.

    A system unit application can receive interrupts from a co-processor adapter task in two ways:

    The interrupt handler receives all interrupts from all co-processor adapters. It takes care of the housekeeping associated with shared hardware interrupts, such as issuing an EOI, issuing a shared interrupt global rearm, and so on. The co-processor adapter interrupt handler has a table of jump vectors (one for each task on every installed co-processor adapter) that it uses to vector into system unit application code. System unit applications acquire these vectors by task number and get control when these tasks interrupt the system unit. When the system unit application is finished processing the interrupt, it should jump on a return vector that is supplied when the original vector is acquired. The interrupt handler supports multiple tasks on multiple co-processor adapters vectoring to multiple system unit applications.

    Also, many system unit applications can share the same interrupt vector (that is, for the same Realtime Control Microcode task).

    Polled Method: The easiest way to manage the interrupts coming from co-processor adapters is to use the polled method. The DOS Support routine ICAVSET is invoked to establish an interrupt service routine for a given number of tasks. This routine sets up a poll flag for each task, which the system unit application can query using the DOS Support routine ICAQINT. The system unit application then must wait for the interrupt by polling a flag until it reaches the correct state. The advantage of this method is that it does not require the system unit application writer to write an interrupt handler because ICAVSET creates the DOS Support internal interrupt service routine to manage the flags and ICAQINT polls these flags. Polling is the only method supported by DOS C Language Support.

    Vectored Method: A more efficient method of handling interrupts is to have the interrupt handler vector directly to the system unit application code. The three basic steps are: acquiring the interrupt vector, handling the interrupt, and returning from the interrupt.

    1. Acquiring the interrupt vector--The interrupt vector can be acquired in two different ways. One way is to acquire the vector directly from the interrupt handler via INT 7Fh. The recommended way is to use the ICAVSETM Assembly Interface routine, which acquires the vector, points it to your application's service interrupt routine, and saves the return vector.

    2. Handling the interrupt--The service interrupt routine must save and restore all modified processor registers and the CPU page register. The best place to save this information is on the current stack or on the interrupt service routine's own stack.

      When control is passed to the the system unit applications interrupt service routine, the Interrupt Handler has already set up a stack for it.

      This stack only has enough space to save one complete set of registers. If any more stack space is required, the system unit application's service interrupt routine must establish its own stack. If any other DOS Support routine is used within the application's service interrupt routine, a new stack must be established because these routines make extensive use of the stack.

      Another important factor when control is passed to the application's service interrupt routine is that a nonspecific EOI has already been issued and interrupts are enabled. However, these service interrupt routines cannot be re-entered until a level-specific global rearm is issued by the interrupt handler. This is done after all system unit application service interrupt handlers for a given task have finished processing. In other words, system unit application interrupt service routines cannot be re-entered by any task on any co-processor adapter sharing the same hardware interrupt level. If different tasks on multiple co-processor adapters on unique hardware interrupt levels share the same system unit application interrupt servicer, the routine can be re-entered.

    3. Returning from the interrupt--If the vector was acquired via ICAVSETM, the ICARET routine must be used. All modified processor registers and the CPU page register must be restored before this routine is used. If the vector was acquired directly from the interrupt handler, the application's service interrupt routine should exit by executing a JUMP FAR on the return vector.

      When the system unit application finishes using the interrupt handler jump vector, it must return every acquired vector before the program terminates. This should be done when using the polled method or the vectored interrupt method. The routines to do this are ICAVRET (for the polled method return) and ICAVRETM (for the vectored method return). The vectors must be returned in last-acquired, first-returned order. This order requirement applies within a given system unit application and between totally separate system unit applications.

      For example, assume that a system unit has one co-processor adapter installed but has two applications that are to be interrupted by task X. Suppose application A acquires task X's vector and then terminates but remains resident (a DOS extension). Application B, a transient program, now runs and also acquires the vector for task X. Application A cannot return its vector until application B does so.


    Handling Interrupts With OS/2 Support

    An OS/2 Support interrupt can be accomplished through the use of semaphores.

    Semaphores: Semaphores are signal mechanisms that synchronize system unit applications and co-processor adapter tasks. They are created by the application program and are used by the device driver to notify the system unit programs of task interrupts.

    To monitor task interrupts with a semaphore, a task should:

    Monitoring Task Interrupts with Semaphores: A simple method for monitoring interrupts from a co-processor adapter in the OS/2 environment is via a separate thread (unit of execution). The thread creates and registers semaphores as previously outlined. The thread can then use DosSemSetWait or DosSemSet and DosSemWait to wait for a co-processor adapter to interrupt. When an interrupt occurs, the device driver clears the semaphore, and the thread gains control. The thread can then handle the interrupt directly, set a flag, or signal another thread or process. The thread then sets the semaphore and waits for the next interrupt. The thread can also monitor multiple interrupts by calling DosMuxSemWait.

    The interrupt monitoring thread must have a higher priority than the rest of the application to ensure that interrupts are handled promptly.

    Also, multiple interrupts in rapid succession may occur before the interrupt monitoring thread gains control. In this case, the device driver could clear the semaphore multiple times before the monitoring thread processes the interrupt. This problem can be avoided by using the primary or secondary status fields to synchronize system unit applications with co-processor adapter tasks.


    Issuing Application Commands

    Commands from system unit applications to co-processor adapter tasks exchange data and interrupt communication.

    The DOS Support routine used to issue commands is ICACMD. For OS/2, the Dynamic Link routine used to issue commands is ICADEVISSUECOMMAND. These routines have some requirements and features to keep in mind.

    For instance, applications and tasks must observe and update the task's primary status byte. Specifically, the busy, output buffer busy, loaded, and initialized bits must be updated.

    If a task is busy or not loaded and not initialized, the routine returns with an error. If data is to be written to a task's output buffer and the output buffer busy bit is set, an error is returned (although this bit is not checked when no data is to be written). The task receives an interrupt via its command handler when a command is issued to it.

    The command routine does not wait for an interrupt after the command has been issued. It only polls to ensure that the Realtime Control Microcode has accepted the command. (All commands are directed to tasks via the Realtime Control Microcode.) Writing data over page boundaries is supported and extensive error checking is provided.

    In DOS, if ICACMD is used from a vectored interrupt service routine, some retry logic may be necessary. Specifically, when ICACMD returns with an invalid status error, retry logic might solve the problem. This is not true for all ICACMD errors. In the case where an application is issuing a command to a task (using ICACMD or other means) when a vectored interrupt service routine is entered, a problem may exist. If the PC select byte is not FFh or FEh (stable interlock states) and the interrupt service routine invokes ICACMD, an error occurs. In this case, infinite retry logic can result in a deadlock situation. Use extreme care when calling ICACMD from a vectored interrupt service routine.


    Creating a DOS System Unit Application

    This section shows how to get started programming system unit applications.

    Assembly Language System Unit Applications

    GROUPing Macros: Certain configuration routines must be invoked before any other routines are used. The first of these routines helps establish the structure of the assembly language program. If the application is to have one common code and data segment (such as in all .COM files and some .EXE files), the DEFCOMGROUP macro must be used. This macro performs the necessary grouping between the application's own code and data segments and the system unit support routines.

    If code and data segments are to be separate (as in most .EXE files), DEFCGROUP and DEFDGROUP must be used. These macros group application and system unit DOS Support code and data segments, respectively. All system unit applications using the co-processor adapter support routines must use at least one of these macros.

    The system unit application must contain an ASSUME statement for specific segments as a result of the group macros. In a file with separate code and data segments, CGROUP must be assumed for the code segment and DGROUP must be assumed for the data segment. The stack and extra segments can be assumed normally. In a file with common code and data segments, COMGROUP ASSUME statements must be included for both the code segment and the data segment.

    Initialize Macros: The other required macros are ICAMACDATA and ICAINIT. ICAMACDATA is a set of data declarations that must be in the data segment of an .EXE file and in the data area of a .COM file. ICAMACDATA contains is no executable code. ICAINIT is a macro used to initialize the other macros. It must be issued before any of the other executable macros (that is, all macros other than the grouping macros and the ICAMACDATA macro). Unlike ICAMACDATA, ICAINIT must be executed. ICAINIT expects one of two parameters. These are EMAC and CMAC. For .EXE applications that are linked with ICAEMAC.LIB, use the EMAC option. For .COM applications that are linked with ICACMAC.LIB, use the CMAC option. EMAC forces a FAR linkage between co-processor adapter support routines, and CMAC forces a NEAR linkage.

    If many source files are separately assembled and linked, make sure that the data declarations in ICAMACDATA are not duplicated by choosing one file as the main module. This file should have the standard ICAMACDATA macro with no options and ICAINIT. All of the other modules are then treated as auxiliary modules and must contain an ICAMACDATA with one of the two options. The presence of an ICAMACDATA option signals that this is an auxiliary module. The EMAC option should be used for .EXE files, and the CMAC option should be used for .COM files. The EMAC option forces all co-processor adapter support external references to be FAR and the CMAC option forces all co-processor adapter support external references to be NEAR. Finally, auxiliary modules should not issue ICAINIT, except in the case where the main module contains no executable code. In this case, ICAINIT should be issued in the first auxiliary module with executable code.

    Once the procedural details are completed, the code becomes specific to the application.

    Restrictions for Assembly Interface Macros: There are some restrictions when using the assembly interface macros. For example, the value in the ASSUME statement for the data segment must be current when a macro is invoked because some assembly interface macros use data and expect the data segment to be the one in the ASSUME statement. The only exception to this is ICACMD, which requires that DS:BX point to a data buffer to be written to a Realtime Control Microcode task's output buffer. In this case, there are no restrictions on DS. This can be helpful when system unit applications acquire storage blocks from the operating system to serve as local buffers to hold the Realtime Control Microcode task parameters.

    Some system unit applications may need to determine the end of the load module after the application has been linked with either ICAEMAC.LIB or ICACMAC.LIB. This can be done by using application segment names that alphabetically precede $$ZSEG and assemble using the /A option, which is the default MASM option. This ensures that $$ZSEG is the last segment in the load module. The $$ZSEG contains only the label $END, that can be referenced to determine the last offset in the load module. This can be useful when trying to return unused storage. System unit applications must take care not to return storage that contains routines from either ICAEMAC.LIB or ICACMAC.LIB because unpredictable results will occur.


    Creating Mixed Model OS/2 V 2.X Applications

    When using the IBM C Set/2 compiler to create OS/2 and mixed model applications, it is necessary to add the following #include statement in the program:

                        #include icados16.h
    
    It is also necessary to include the following #define statement for proper compiling:
                        #define RIC_OS220
    
    The following is an example of compiling an application with C Set/2:
                        icc /C+ myprog.c
    
    The following is an example of linking an application with Set/2:
             link386 /NOE /BASE:65536 myprog.obj,,,os2386+icaricd1+dde4sbs
    
    Note: Multithreaded applications are compiled with the /Gm+ option and
          linked with the dde4mbs library.
          Refer to the IBM C Set/2 compiler documentation for further
          compiling and linking options.
    

    Appendix A. Sample Program

    The Realtime Interface Co-Processor C Language Support Version 1.03 product provides a DOS system unit sample program that can be used as a learning tool.

    The sample program hllc.c is a C system unit program that sends a command to a task and allows variable parameters to be passed to the task.

    Once the Realtime Interface Co-Processor C Language Support files are installed, enter the appropriate pair of commands to compile and link the sample program:

    Microsoft C 6.0 Optimizing Compiler:
    
        cl /AS /G1 /c hllc.c
    
        link hllc+icasc.obj,,,icaemac.lib+slibca;
    
    IBM C/2 1.1 Compiler:
    
        cc /AS /G1 hllc;
    
        link hllc+icasc.obj,,,icaemac.lib+slibcar;
    
    These two commands generate an executable system unit program, hllc.exe, that sends commands to any task that is loaded on the co-processor adapter. Enter the following command to execute the sample system unit program:
        hllc    [...]
    
    The sample program should then display the following message:
            Command issued.  Task status = xx
    
    Where xx is the task's primary status.

    Appendix B. Glossary

    This glossary defines some terms relevant to the product environment and abbreviations used in the text.

    ASCII
    American Standard Code for Information Interchange.

    asynchronous error
    An error that can occur at any time. Three asynchronous errors are defined as level 1 errors: parity error; opcode error; and watchdog timer error.

    BCB
    Buffer control block.

    binary synchronous communications (BSC)
    A uniform procedure, using a standardized set of control characters and control character sequences for synchronous transmission of binary-coded data between stations.

    BIOS
    Basic input/output system.

    child task
    A task that is built by another task (called the parent task). The child task resides in storage owned by the parent task. When a parent task is stopped or unloaded, all child tasks built by that parent task are also unloaded.

    CIO
    Counter/Timer and Parallel I/O Unit

    co-processor adapter
    Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport, Realtime Interface Co-Processor Multiport/2, X.25 Interface Co-Processor/2, Realtime Interface Co-Processor Portmaster Adapter/A, or Realtime Interface Co-Processor Multiport Adapter, Model 2, X.25 Interface Co-Processor

    dispatch cycle
    task switch that makes new task the currently executing task.

    DMA
    Direct memory access.

    DOS
    Disk Operating System.

    DTR
    Data Terminal Ready line control signal.

    DUSCC
    Dual Universal Serial Communications Controller.

    EBCDIC
    Extended Binary-Coded Decimal Interchange Code.

    EIB
    Electrical interface board, which can support one or more of several physical interfaces such as RS-232 and RS-422.

    EOI
    End of interrupt.

    FCC
    Federal Communications Commission.

    IB
    Interface block.

    modem
    A device that allows computers to exchange information over telephone lines.

    NSEOI
    Non-specific end of interrupt.

    operating system
    A program or set of programs that supervises the execution of user programs by the computer.

    parent task
    A task that builds a child task while executing on the co-processor adapter.

    peer task
    Any task that has equal standing with other tasks.

    PIC
    Programmable Interrupt Controller.

    PROM
    Programmable Read Only Memory.

    PROM Services
    System services provided in PROM and invoked through interrupt vectors between INT 0xA0 and 0xCC.

    RAM
    Random access memory.

    Realtime Control Microcode
    The operating software that controls tasks running on the co-processor adapter. It is defined as task 0.

    ROM
    Read Only Memory.

    RTS
    Request to send line control signal.

    SCC
    Serial Communications Controller (USART).

    SDLC
    Synchronous Data Link Control.

    Software timer
    Software resource of the Realtime Control Microcode used to notify a task that the minimum requested timeout has occurred. For more information, see your co-processor adapter's Technical Reference.

    SVC
    Supervisor Call.

    SVI
    Supervisor Interrupt.

    Synchronous Data Link Control (SDLC)
    A protocol for management of data transfer over a data link.

    synchronous transmission
    (1) Data transmission in which the time of occurrence of each signal representing a bit is related to a fixed time frame. (2) Data transmission in which the sending and receiving devices are operating continuously at substantially the same frequency, and are maintained, by means of correction, in a desired phase relationship.

    task
    A .COM or .EXE program with an appropriate task header that executes on the co-processor adapter.

    TCB
    Task control block.

    TCBTAB
    Task control block table.

    transmission
    (1) The sending of data from one place for reception elsewhere. (2) In ASCII and data communications, a series of characters including headings and text. (3) The dispatching of a signal, message, or other form of intelligence by wire, radio, telephone, or other means. (4) One or more blocks or messages. For BSC and start-stop devices, a transmission is terminated by an EOT character. (5) Synonymous with data transmission.

    USART
    Universal Synchronous/Asynchronous Receiver/Transmitter (for example, SCC and DUSCC)

    Footnotes:

    (1) * IBM, Operating System/2, and OS/2 are trademarks
    of International Business Machines Corporation
    in the U.S.A. and other countries.

    (2) * Macro Assembler/2 is a trademark of International
    Business Machines Corporation in the U.S.A. and
    other countries.

    (3) ** Microsoft is a trademark of Microsoft Corporation.

    (4) * C/2 is a trademark of International Business Machines
    Corporation in the U.S.A. and other countries.  

    Last modified: March 25, 1999