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

Volume II - Co-Processor Adapter

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 Co-Processor Adapter Tasks

  • Hardware Requirements
  • Software Requirements
  • Distributing Your Programs
  • Product Contents
  • Functional Overview of C Tasks
  • General Task Structure
  • Passing Parameters to a Co-Processor Adapter Task
  • Disabling Peer Services
  • Allocation of Variables
  • Task Header
  • Segments and Groups in C Tasks
  • Command Handler and Prologue Library Modules
  • Sharing C Language Support Functions
  • Realtime Control Microcode Resources
  • Classes of Routines
  • Chapter 2. Include File and Data Structures

  • Common Type Definitions Used by Support Functions
  • Common Structures Used by Support Functions
  • Chapter 3. Other Coding Considerations

  • Usable Standard C Functions
  • Interrupt Handlers
  • Hardware Interrupt Handlers
  • Software Interrupt Handlers
  • Building Other Tasks
  • Child Tasks
  • Peer Tasks
  • Debugging C Tasks
  • Error-Handling Task
  • Chapter 4. Using the Co-Processor Adapter Support

  • Compiling Instructions
  • Microsoft C 6.0 Optimizing Compiler
  • IBM C/2 1.1 Compiler
  • Microsoft C/C++ V7.0 and Visual C/C++ V1.5 Compilers
  • Linking Instructions
  • Microsoft C 6.0 Optimizing Compiler
  • IBM C/2 1.1 Compiler
  • Microsoft C/C++ V7.0 and Visual C/C++ V1.5 Compilers
  • Chapter 5. Library Routines

  • atoe
  • bcb_cmd_r
  • bcb_ib_r
  • bcb_ib_w
  • bcb_init
  • bcb_ob_r
  • bcb_ob_w
  • bcb_st_r
  • bcb_st_w
  • cantime
  • cioreg
  • ciotimer
  • cli
  • dacwrite
  • dhook_exit
  • dhook_ntry
  • dispreempt
  • dmaconec
  • dmareg
  • dmastart
  • dmastop
  • dmaxlate
  • emm2page
  • emm2phys
  • enpreempt
  • estat_r
  • estat_w
  • etoa
  • extstcl
  • extstco
  • extstqu
  • ftime
  • get_baseid
  • get_call_addr
  • getextid
  • get_int_cnt
  • get_next_avail
  • get_pgfrm
  • get_ptrs
  • get_res_cnt
  • get_task
  • halfrate
  • hook_exit
  • hook_ntry
  • inbuf_r
  • inbuf_w
  • initpri
  • int_exit
  • int_ntry
  • map_emm
  • map_physpg
  • nseoi
  • outbuf_r
  • outbuf_w
  • page2seg
  • pag2segc
  • pdmareg
  • peer_req
  • phys2page
  • poppgmap
  • postcd_r
  • posti
  • psb_and
  • psb_or
  • psb_r
  • psb_w
  • pushpgmap
  • readcio
  • resumei
  • ringaddl
  • ringadds
  • ringreml
  • ringrems
  • rtsdtr
  • sccreg
  • sccrst
  • seg2page
  • seg2phys
  • setclockopt
  • set_time
  • sfw_chn
  • sfw_exit
  • sti
  • svcalloc
  • svcasap
  • svcbuild
  • svccantm
  • svcdeall
  • svcinitc
  • svcintrq
  • svcpost
  • svcprdic
  • svcqryfs
  • svcrdvec
  • svcrsume
  • svcsspnd
  • svcstart
  • svcstop
  • svctimer
  • svctres
  • svcunld
  • svcwait
  • time
  • unallocpgcnt
  • u_q_add
  • u_q_addp
  • u_q_rcv
  • u_q_rem
  • writecio
  • xmitcntl
  • Appendix A. Sample Programs

  • Sample Program 1
  • Sample Program 2
  • Glossary


    About This Guide

    This guide, Volume II, provides technical information on the Realtime Interface Co-Processor C Language Support services that allow you to develop tasks in the C Language for communicating with the following co-processor adapters:

    The information in this volume supports the development of C tasks that runs under the control of IBM Realtime Control Microcode. This volume also describes the sample co-processor adapter programs supplied with the C Language Support product.

    Volume I of this guide provides information for developing 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. Volume I also contains information on installing the C Language Support product and describes the sample system unit program 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 other technical documents for your co-processor adapter.

    The following conventions are used in this guide:


    Related Publications

    The following C Language Support guide is Volume I 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 Co-Processor Adapter 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.

    The C Language Support for the Co-Processor Adapter includes a set of program services that enable C programs to be compiled to run as tasks, under the control of Realtime Control Microcode, on the co-processor adapter. These services are described in this volume. (Volume I of this guide describes the C Language Support for the System Unit, which includes support for C programs that will use the application program interface of DOS Support or OS/2 Support.)


    Hardware Requirements

    The following are minimum hardware requirements for 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 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.


    Product Contents

    The C Language Support product consists of program files.

    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     Medium 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 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
      ICACALLS.H      Include file of OS/2 dynamic link routine
                      C declarations
      ICADOS16.H      Provides declarations to allow for thunking
                      mechanism
    
    The system unit support is described in Volume I.

    Functional Overview of C Tasks

    General Task Structure

    The structure of C tasks is similar to system unit C applications. The differences are mandated by the different operating environments--the Realtime Control Microcode as compared to the IBM Disk Operating System (DOS) or the Operating System/2 (OS/2). C tasks must have a task header at the beginning of the task load module; system unit C tasks do not. In addition, C tasks issue commands to the Realtime Control Microcode, rather than DOS or OS/2, as in system unit C tasks.

    Passing Parameters to a Co-Processor Adapter Task

    Parameters may be passed to a task when the task is being loaded. The task receives the parameters in its main function through the standard C parameters, argc and argv.

    Following is an example of passing parameters from the command line to a task being loaded in DOS:

        icaload 0 taskname.exe 1 (ABC 123 "XYZ 456"
    
    Following is an example of passing parameters from the command line to a task being loaded in OS/2:
        icaldric 0 taskname.exe 1 (ABC 123 "XYZ 456"
    
    The application loader (ICALOAD or ICALDRIC) puts the task name into argv[0] in upper case, and then puts the remaining parameters in order in the array. (ICALOAD is the application loader utility supplied with the Realtime Interface Co-Processor DOS Support product, and ICALDRIC is the application loader utility supplied with the Realtime Interface Co-Processor OS/2 Support product.)

    The task might look like the following:

        #include icadeclt.h
        #include string.h
        #include stdio.h
    
        main(argc,argv)
          int argc;          /* Number of parameters being    */
                             /* passed = 4.                   */
          char *argv[];      /* Array of strings being passed */
                             /* as parameters:                */
                             /*     argv[0] = TASKNAME.EXE    */
                             /*     argv[1] = ABC             */
                             /*     argv[2] = 123             */
                             /*     argv[3] = XYZ 456         */
    
       {
    
                 /* ------------------- */
                 /*     User code       */
                 /* ------------------- */
    
       } /* End main routine */
    
    For more information on the argc and argv C parameters, see the compiler language reference.

    Disabling Peer Services

    Realtime Control Microcode 2.01 allows you to disable peer services by specifying an optional parameter of 1 (one) when loading Realtime Control Microcode. This conserves base memory.

    Example:
    
            icaload 0 icarcm.com 0 (1
    

    Allocation of Variables

    Variables are defined in the same manner as a C language system unit application. The only restriction on declarations applies to resource request blocks. Request blocks must be declared globally and must be initialized at the time of declaration. This guarantees that the request block is located in the task header segment, as required by Realtime Control Microcode. Resource request blocks should be defined before other global data and must have at least the first three fields initialized--the forward and backward pointers, and the request block type. The following is an example of a vector request block declaration:

            struct vrbstruct vectreq1 = { 0, 0, 0x01 };
    

    Task Header

    The task header is stored in the file icaheadc.obj and contains definitions and initial values for the task header fields. As stated previously, the task header must be first in the task load module. This can be done by linking the header to the compiled task code. The thstruct structure defines the fields of the task header; the get_ptrs function can be used to get a pointer to the task header field.

    The source for the task header is stored in the icaheadc.asm file. The task header field values can be modified in the source if desired. The header file can then be re-assembled with the /S option, which indicates to the assembler and linker that the segments should stay in the order that they are specified.

    When upgrading to a new level of C Language support, if you have customized the task header in the icaheadc.asm file, it must be replaced by the latest level task header with your modifications. The modified header should then be re-assembled using the /S option and re-linked to the compiled task code.

    Segments and Groups in C Tasks

    For Realtime Control Microcode, the order of segments in C tasks is different from a comparable system unit program. The data precedes the code in C tasks so that the task header fields can be accessed as data. This also permits resource request blocks to be allocated in the same segment as the task header.

    The following table shows the order of segments in C tasks, from low storage to high storage:

      Segment    Group    Segment
      Name       Name     Type       Remarks
    ====================================================================
      HEADER     DGROUP   HEADDATA   Task header
    
      NULL       DGROUP   BEGDATA    Segment for null pointer
                                     checks (not used)
    
      _DATA      DGROUP   DATA       Static initialized variables
    
      xxxxx      DGROUP   DATA       Other data segments (large
                                     and huge memory models)
    
      CONST      DGROUP   DATA       Read-only constants
    
      c_common   DGROUP   DATA       Uninitialized global variables
    
      _BSS       DGROUP   DATA       Uninitialized static variables
    
      STACK      DGROUP   DATA       Stack segment
    
      _TEXT      IGROUP   CODE       Code segment
    
      xxxxx      IGROUP   CODE       Other code segments (medium,
                                     large, and huge memory models)
    

    Command Handler and Prologue Library Modules

    The __cmdent routine handles command interrupts from the system unit for the task. The task header command vector points to this module. When _cmdent is entered from the Realtime Control Microcode, the C task is posted with a post code of tn02h, where tn is the C task's task number and 02h is the post code for a command post. If the user wishes to install a new command handler, the command handler must have the public name __cmdent, and be in a library that is searched before the Realtime Interface Co-Processor C Language Support libraries. The new command handler can also be specified on the object module line of the LINK input. The new command handler should post the task with the command post, and should turn off the output buffer busy, busy, and error bits in the task's primary status byte.

    The default command handler, __cmdent, rejects all incoming peer request blocks. To write a command handler that handles peer request blocks, write a _cmdhand routine with the following declaration and link the routine ahead of the Realtime Interface Co-Processor C Language Support libraries.

    void _cmdhand (PRBCount , PRBPtr)
         unsigned int PRBCount;
         struct prbstruct for * PRBPtr;
      {
    
    
          /* -------------------- */
          /* Command handler code */
          /* -------------------- */
    
    
      }
    
    The default command handler, __cmdent, posts the task on a normal command interrupt and passes peer request blocks to the _cmdhand routine. The default _cmdhand routine in the libraries rejects all peer request blocks.

    The crt0 module is responsible for task setup. A modified crt0 is provided to replace the standard setup routine in the C compiler. This module is responsible for setting up and maintaining the operating environment for the task. Several routines called by icacrt0 are different. The setenvp routine is no longer called because it is a DOS-dependent routine. The nullchk routine has been removed because fields in the task header (at offset 0) can change during task execution and can invalidate the check. The chkstk routine has been modified so that a task is suspended if the stack overflows. Users may write their own stack checking routines, following the conventions described in the C compiler reference manual.

    Command handlers may not be shared by more than one task.

    Sharing C Language Support Functions

    When code is executed by more than one task, the code is referred to as "shared code."

    A common configuration where shared code occurs is within a software interrupt handler that is called by multiple tasks. Another shared code configuration is where one task provides dynamically linked entry points that are called by multiple tasks.

    To avoid unpredictable results and data corruption, special consideration must be taken when using the C Language Support functions in shared code. These special considerations also apply to interrupt handler code. To enable the use of some of the C Language Support routines in shared code, the ICA_SHARED parameter must be set. This causes the C Language Support shared routines to be used. These routines resolve addressability to task structures using the currently executing task number. The shared routines may not be used within interrupt handlers.

    The command line parameter "ICA_SHARED" may be set by using the /D compile option at compile time. The shared option is chosen for the large model of C Language with packed structures. For example:

              cc /AL /Zp /DICA_SHARED ctask;
    
    ICA_SHARED may also be set within the code by using the #define directive before including the ICADECLT.H include file. For example:
              #define ICA_SHARED
              #include icadeclt.h
    
    Sharing code is only possible when compiling tasks in the large model of C Language. The C Language Support functions cannot be shared in small or medium models.

    Each routine can be classified as to whether or not it can be shared and whether or not it can be called from an interrupt handler:

                         Can Routine         Call Routine from
                         be Shared?          Interrupt Handler?
    =====================================================================
      atoe                   Yes                     Yes
      bcb_cmd_r              Yes*                    Yes**
      bcb_ib_r               Yes*                    Yes**
      bcb_ib_w               Yes*                    Yes**
      bcb_init               Yes*                    Yes**
      bcb_ob_r               Yes*                    Yes**
      bcb_ob_w               Yes*                    Yes**
      bcb_st_r               Yes*                    Yes**
      bcb_st_w               Yes*                    Yes**
      cantime                Yes                     Yes
      cioreg                 Yes                     Yes
      ciotimer               Yes                     Yes
      cli                    Yes                     Yes
      clr_pf                 Yes*                    Yes**
      convtptr               Yes                     Yes
      dacread                Yes                     Yes
      dacwrite               Yes                     Yes
      dhook_exit             No                      Yes
      dhook_ntry             No                      Yes
      dispreempt             Yes                     No
      dmaconec               Yes                     Yes
      dmareg                 Yes                     Yes
      dmastart               Yes                     Yes
      dmastop                Yes                     Yes
      dmaxlate               Yes                     Yes
      emm2page               Yes                     Yes
      emm2phys               Yes                     Yes
      enpreempt              Yes                     No
      estat_r                Yes*                    Yes**
      estat_w                Yes*                    Yes**
      etoa                   Yes                     Yes
      extstcl                Yes                     Yes
      extstco                Yes                     Yes
      extstqu                Yes                     Yes
      ftime                  Yes                     Yes
      get_call_addr          Yes                     Yes
      get_int_cnt            Yes                     Yes
      get_next_avail         Yes                     Yes
      get_pgfrm              Yes                     Yes
      get_ptrs               Yes*                    Yes**
      get_res_count          Yes                     Yes
      get_task               Yes                     Yes
      halfrate               Yes                     Yes
      hookexit               No                      Yes
      hookntry               No                      Yes
      inbuf_r                Yes*                    Yes**
      inbuf_w                Yes*                    Yes**
      initpri                Yes*                    Yes**
      int_exit               No                      Yes
      int_ntry               No                      Yes
      map_emm                Yes                     Yes
      map_physpg             Yes                     Yes
      nseoi                  Yes                     Yes
      outbuf_r               Yes*                    Yes**
      outbuf_w               Yes*                    Yes**
      pag2segc               Yes                     Yes
      page2seg               Yes                     Yes
      pdmareg                Yes                     Yes
      phys2page              Yes                     Yes
      poppgmap               Yes                     Yes
      postcd_r               Yes*                    Yes**
      posti                  Yes                     Yes
      psb_and                Yes*                    Yes**
      psb_or                 Yes*                    Yes**
      psb_r                  Yes*                    Yes**
      psb_w                  Yes*                    Yes**
      pushpgmap              Yes                     Yes
      readcio                Yes                     Yes
      resumei                Yes                     Yes
      ringaddl               Yes                     Yes
      ringadds               Yes                     Yes
      ringreml               Yes                     Yes
      ringrems               Yes                     Yes
      rtsdtr                 Yes                     Yes
      sccreg                 Yes                     Yes
      sccrst                 Yes                     Yes
      seg2page               Yes                     Yes
      seg2phys               Yes                     Yes
      set_time               Yes                     Yes
      setclockopt            Yes                     Yes
      sfw_chn                No                      No***
      sfw_exit               No                      No***
      sti                    Yes                     Yes
      svcalloc               Yes                     No
      svcasap                Yes                     No
      svcbuild               Yes*                    No
      svccantm               Yes                     No
      svcdeall               Yes                     No
      svcinitc               Yes                     No
      svcintrq               Yes                     No
      svcpost                Yes                     No
      svcprdic               Yes                     No
      svcqryfs               Yes                     No
      svcrdvec               Yes                     No
      svcrsume               Yes                     No
      svcsspnd               Yes                     No
      svcstart               Yes                     No
      svcstop                Yes                     No
      svctimer               Yes                     No
      svctres                Yes                     No
      svcunld                Yes                     No
      svcwait                Yes*                    No
      time                   Yes                     Yes
      u_q_add                Yes                     Yes
      u_q_add_p              Yes                     Yes
      u_q_rcv                Yes                     Yes
      u_q_rem                Yes                     Yes
      unallocpgcnt           Yes                     Yes
      writecio               Yes                     Yes
      xmitcntl               Yes                     Yes
    
        *ICA_SHARED option must be used
       **ICA_SHARED option cannot be used
      ***Can only be called from software interrupt handler
    
    Some interrupt-related functions set up access to a task's DGROUP. These functions which cannot be shared are:
       dhook_exit      Used by dispatch extended services
       dhook_ntry      Used by dispatch extended services
       hookexit        Used by non-dispatch extended services
       hookntry        Used by non-dispatch extended services
       int_ntry        Enter a hardware interrupt handler
       int_ exit       Exit a hardware interrupt handler
       sfw_chn         Software interrupt handler chaining support
       sfw_exit        Exit a software interrupt handler
       _cmd_ent        Task command handler
    

    Realtime Control Microcode Resources

    For information on Realtime Control Microcode resources, refer to your co-processor adapter Technical Reference document.

    Classes of Routines

    Supervisor Call (SVC) Functions

    The SVC functions provide an interface to the Realtime Control Microcode supervisor calls. An important difference between the SVC functions and the other functions is that SVC functions cause a dispatch cycle to occur, while the other functions do not necessarily cause a dispatch cycle. In addition, SVC functions may not be called from a hardware interrupt handler.

    The following functions provide an interface to the supervisor calls:

      Function    Description
    ==================================================================
      svcalloc    Allocate a resource
      svcasap     Cause a dispatch cycle to occur
      svcbuild    Simulate a task load from the system unit
      svccantm    Cancel a timer
      svcdeall    Deallocate a resource
      svcinitc    Signal initialization complete
      svcintrq    Interrupt system unit from requesting task
      svcpost     Post a task
      svcprdic    Start a periodic timer
      svcqryfs    Query free storage
      svcrdvec    Read an interrupt vector
      svcrsume    Resume a task
      svcsspnd    Suspend a task
      svcstart    Start a task
      svcstop     Remove a task's TCB from TCBTAB
      svctimer    Start a timer
      svctres     Terminate task but remain resident
      svcunld     Unload a task
      svcwait     Put task into wait mode
    
    The SVC functions return a common set of error codes to facilitate error handling:
      Code     Condition
    =============================================================
      0x0000   Normal operation, no error
      0x0004   EIB not present
      0x0005   Access denied
      0x0006   Port interface mismatch
      0x0007   Communication controller mismatch
      0x0008   Insufficient storage
      0x0009   Interrupt busy because previous interrupt
                was not accepted by the system unit
      0x000A   No response from system unit after
                interrupt was requested
      0x000C   Requested operation previously performed
      0x0013   Invalid data
      0x0014   Invalid task number
      0x0015   Invalid timer number
      0x0016   Invalid queue number
      0x0018   Invalid port number
      0x001A   Insufficient expanded memory pages
      0x001C   Requested access not available
    

    PROM Services Functions

    The programmable read only memory (PROM) services functions provide an interface to the PROM Services modules. These functions do not cause a dispatch cycle to occur.

    The PROM Services interface routines must be used with care, as none of the routines verify that the caller is the owner of the device affected.

    The following functions provide an interface to the PROM Services modules:

      Function    Description
    =================================================================
      atoe        Convert ASCII to EBCDIC
      cioreg      CIO register support
      ciotimer    CIO timer support
      convtptr    Return pointer to EBCDIC-ASCII tables
      dacread     Reads appropriate DAC registers
      dacwrite    Writes appropriate DAC registers
      dmaconec    Connect DMA
      dmareg      Read/write DMA registers
      dmastart    Set up and start DMA
      dmastop     Stop DMA
      dmaxlate    Translate logical to physical address
      etoa        Convert EBCDIC to ASCII
      pdmareg     Reads/Writes registers of DMA/peripheral
                   interface controller channel
      ringaddl    Add element to ring (inter-segment)
      ringadds    Add element to ring (intra-segment)
      ringreml    Remove element from ring (inter-segment)
      ringrems    Remove element from ring (intra-segment)
      sccreg      Read/write SCC registers
      sccrst      Reset SCC port
      seg2phys    Convert segment:offset into translated
                   physical address
      phys2page   Convert 32-bit physical address into
                   page:offset
    

    Supervisor Interrupt (SVI) Functions

    The supervisor interrupt (SVI) functions provide an interface to the Realtime Control Microcode service interrupts. These calls do not necessarily cause a dispatch cycle to occur. A preemptive dispatch cycle may be caused by posti if a higher priority task is posted or by enpreempt if a higher priority task is posted while preemption is disabled. SVI functions may be called from a hardware interrupt handler.

    Following is a list of the supervisor interrupt functions:

      Function        Description
    ===================================================================
      cantime         Cancel a timer
      dispreempt      Disable preemption
      enpreempt       Enable preemption
      extstcl         Clear external/status interrupts
      extstco         Enable/disable external/status
                       interrupt inputs
      extstqu         Query port's external/status inputs
      get_call_addr   Get callable address
      get_int_cnt     Get interrupt count
      get_next_avail  Get next available resource
      get_res_count   Get resource count
      get_task        Return task number of current task
                       in execution
      halfrate        Enable/disable half rate select
      page2seg        Translate page to segment address
      pag2segc        Translate page to segment address
      posti           Post a task
      readcio         Read CIO port data register
      resumei         Resume a task
      rtsdtr          Control RTS and DTR outputs for a port
      seg2page        Translate segment to page address
      setclockopt     Set DCE or DTE clocking
      set_time        Set system time
      u_q_add         Add an element to a user queue
      u_q_add_p       Add an element to a user queue
                       (32-bit physical address)
      u_q_rcv         Receive user queue element
      u_q_rem         Remove user queue element
      writecio        Write CIO port data register
      xmitcntl        Enable/disable transmit function
    

    Expanded Memory Supervisor Interrupts

    The expanded memory manager support described in the following supervisor interrupts is valid for Realtime Interface Co-Processor Portmaster Adapter/A adapters only.

    The term "expanded memory page frame" refers to the 80186 logical address (segment:offset) where the pages of expanded memory are mapped so that they can be addressed by the 80186.

    Realtime Control Microcode 2.01 uses the unused PROM (programmable read only memory) address space (between 960KB and PROM) as the expanded memory page frame and preserves the mapping of expanded memory pages across dispatch cycles.

    The typical steps an application performs to use expanded memory are:

    1. Use the get_pgfrm SVI to get the address and size of the expanded memory page frame and verify the presence of expanded memory.
    2. Allocate expanded memory via the Expanded Memory Pages Resource Block and svcalloc.
    3. For 80186 access to expanded memory pages, use the map_emm SVI to map a page into the expanded memory page frame.
    4. For DMA access to the expanded memory pages, convert the logical 80186 buffer addresses in the page frame to a physical address via PROM Services and Realtime Control Microcode SVIs.
    5. For access to expanded memory from interrupt handlers, use the pushpgmap and poppgmap expanded memory page map functions to preserve the page mapping.
    6. When finished with expanded memory, use the map_emm SVI to unmap the memory and return via the svcdeall.

    Following is a list of the expanded memory supervisor interrupt functions:

     Function      Description
    ==================================================================
     get_pgfrm     Gets logical segment address and number of
                     page in emm page frame.
     unallocpgcnt  Returns the number of emm support pages.
     map_emm       Maps or unmaps logical emm pages to a page
                     frame page.
     map_physpg    Maps or unmaps physical emm pages to a page
                     frame page.
     emm2phys      Converts an EMM handle, logical page number
                     and offset to a 32-bit physical address.
     emm2page      Converts EMM handle, logical page number
                     and offset to a 32-bit physical
                     page:offset address.
     pushpgmap     Saves the memory mapping context when an
                     interrupt occurs.
     poppgmap      Restores the expanded memory manager support
                     page frame mapping.
    

    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. Using peer services, tasks can communicate with local tasks on the same Realtime Interface Co-Processor Portmaster Adapter/A, remote tasks on a peer Realtime Interface Co-Processor Portmaster Adapter/A, or applications in the system unit. For compatibility, the buffer control block (BCB) command-passing mechanism is preserved, but the peer services provide a more powerful means of passing commands and data.

    The Peer Request SVI, peer_req, is used to pass the messages between tasks/processors. Information concerning the peer request is passed in the prbstruct request block. Realtime Control Microcode 2.01 supports a set of commands via peer requests as listed in the Realtime Interface Co-Processor Firmware Technical Reference, Volume III. The commands and data passed among application tasks are defined by the user.

    Realtime Control Microcode 2.01 allows you to disable peer services by specifying an optional parameter of 1 (one) when loading Realtime Control Microcode. This conserves base memory.

    Example:    icaload 0 icarcm.com 0 (1
    
    Refer to the Realtime Interface Co-Processor DOS Support User's Guide or the Realtime Interface Co-Processor OS/2 Support User's Guide for more information.

    Miscellaneous Functions

    The miscellaneous functions do not correspond with any Realtime Control Microcode functions. They provide support that is easily written in assembler tasks but is more difficult to write in C tasks. This support includes reading and writing the buffer control block, changing the task's primary status byte, time functions, hook services, and entry to and exit from interrupt handlers. These miscellaneous functions do not cause a dispatch cycle to occur.

    The miscellaneous functions are:

     Function     Description
    ==============================================================
     bcb_cmd_r    Read BCB command field
     bcb_ib_r     Read BCB input buffer fields
     bcb_ib_w     Write BCB input buffer fields
     bcb_init     Initialize BCB
     bcb_ob_r     Read BCB output buffer fields
     bcb_ob_w     Write BCB output buffer fields
     bcb_st_r     Read BCB status buffer fields
     bcb_st_w     Write BCB status buffer fields
     cli          Disable interrupts
     clr_pf       Clear task's TCB posted flag
     dhook_exit   Used by dispatch extended services
     dhook_ntry   Used by dispatch extended services
     estat_r      Read task's extended status buffer
     estat_w      Write task's extended status buffer
     ftime        Returns elapsed time since 01/01/70.
     get_ptrs     Get pointers to task's control blocks
     hookexit     Used by non-dispatch extended services
     hookntry     Used by non-dispatch extended services
     inbuf_r      Read task's input buffer
     inbuf_w      Write task's input buffer
     initpri      Initialize task's priority
     int_exit     Exit a hardware interrupt handler
     int_ntry     Enter an interrupt handler
     nseoi        Perform a non-specific EOI to the 80186
                   Programmable Interrupt Controller (PIC)
     outbuf_r     Read task's output buffer
     outbuf_w     Write task's output buffer
     postcd_r     Read task's TCB post code
     psb_and      Perform logical AND with primary status
     psb_or       Perform logical OR with primary status
     psb_r        Read primary status
     psb_w        Write primary status
     sfw_chn      Software interrupt chain support
     sfw_exit     Exit a software interrupt handler
     sti          Enable interrupts
     time         Return elapsed seconds since 01/01/70
    

    Chapter 2. Include File and Data Structures

    The include file icadeclt.h contains the data and code declarations for the Realtime Interface Co-Processor C Language Support for the co-processor adapter. The following table shows the names and descriptions of the major data declarations:

      STRUCTURE         Description
    =================================================================
      bcbstruct         Buffer control block
      call_addr_struct  Callable address structure
      cbptr             Structure of control block pointers
      ciorbstruct       CIO request block
      cprbstruct        Communication port request block
      dhookenv          Dispatch extended service hooks
                          register structure
      drbstruct         DMA request block
      emmrbstruct       Expanded memory pages resource block
      hookenv           Non-dispatch extended service hooks
                          pointer structure
      hookparms         Non-dispatch extended service hooks
                          parm structure
      hookrbstruct      Extended service hooks resource block
      hookregs          Non-dispatch extended service hooks
                          register structure
      htrbstruct        Hardware timer request block
      ibstruct          Interface block
      intenv            Interrupt saved register structure
      offpage           Offset and page structure
      offseg            Offset and segment structure
      pdmaregstruct     DMA/peripheral interface controller
                          request block
      prbstruct         Peer request block
      psbstruct         Primary status byte
      qrbstruct         Queue request block
      res_cnt_struct    Resource count structure
      rs232rbstruct     RS-232 request block
      rs422rbstruct     RS-422 request block
      sccrbstruct       SCC request block
      sibstruct         Supplemental interface block
      srbstruct         Storage request block
      tcbstruct         Task control block
      thstruct          Task header
      trbstruct         Software timer request block
      urbstruct         SCC-CIO request block
      vrbstruct         Vector request block
    

    Common Type Definitions Used by Support Functions

    There are some type definitions in ICADECLT.H that are used by various structures and functions.

       typedef void (far *VECTOR)(void); /* 32-bit vector        */
    
       define ICAENTRY cdecl  /* Declare function to be FAR call */
    

    Common Structures Used by Support Functions

    There are a number of common structures that are used by many of the C Language Support functions for the co-processor adapter. These structures are described in this section. Note that the /Zp compiler option must be used to ensure that these structures are correctly generated by the compiler. Any structure element with the name of RSVx should never be referenced to allow for future compatibility (x is any number).

    BCB Structure

    The following structure is a model of the buffer control block (BCB):

    struct bcbstruct
      {
       unsigned char CMD;     /* Command byte                    */
       unsigned int STLEN;    /* Length of external status field */
       unsigned int ESTOFF;   /* Offset of external status field */
       unsigned char STPG;    /* Page number of external status  */
       unsigned int IBLEN;    /* Length of input buffer          */
       unsigned int IBOFF;    /* Offset of input buffer          */
       unsigned char IBPG;    /* Page number of input buffer     */
       unsigned int OBLEN;    /* Length of output buffer         */
       unsigned int OBOFF;    /* Offset of output buffer         */
       unsigned char OBPG;    /* Page number of output buffer    */
       };
    

    Pointers to Task's Control Block Structures

    struct cbptr
      {
       struct ibstruct far *IBPTR;   /* Points to the interface  */
                                     /* block                    */
       struct tcbstruct far *TCBPTR; /* Points to the task's TCB */
       struct bcbstruct far *BCBPTR; /* Points to the task's BCB */
       struct thstruct far *THEADPTR;/* Points to the task's     */
                                     /* header                   */
       };
    

    Callable Address Structure

    The callable address structure contains the addresses of selected routines for Realtime Control Microcode Version 2.01.

    struct call_addr_struct
      {
       unsigned char COUNT;          /* Number of routines in   */
                                     /* this structure.         */
       unsigned char RESV;           /* Reserved for future use;*/
                                     /* must be 0               */
       VECTOR        ADD_BLOCK;      /* Far address of RCM ADD  */
                                     /* BLOCK routine.          */
       VECTOR        REMOVE_BLOCK;   /* Far address of RCM      */
                                     /* REMOVE BLOCK routine.   */
       VECTOR        TSKNUMCHK;      /* Far address of RCM      */
                                     /* TSKNUMCHK routine.      */
       VECTOR        GET_MAIN;       /* Far address of RCM      */
                                     /* GET_MAIN routine.       */
       VECTOR        AIMINT;         /* Far address of RCM      */
                                     /* AIMINT routine.         */
       VECTOR        START_TIMER;    /* Far address of RCM      */
                                     /* START_TIMER routine.    */
       VECTOR        EXTINTENTRY;    /* Far address of          */
                                     /* EXTERNAL_INT routine    */
       VECTOR        EXTINTEXIT;     /* Far address of          */
                                     /* PREEMPTCD routine       */
       unsigned int (far *PEERTOUT)(void);
                                     /* Far address of          */
                                     /* peer timeout routine    */
       VECTOR        QUEUEPROC;      /* Far address of          */
                                     /* QUEUE_PROC routine      */
       VECTOR        DEQUEUEPROC;    /* Far address of          */
                                     /* DEQUEUE_PROC routine    */
       VECTOR        CHANGEUSERREG;  /* Far address of          */
                                     /* CHANGE_REG routine      */
       unsigned int  (ICAFAR *TIB_TRIPTIME) (void);
       };
    

    Dispatch Extended Service Hooks Pointer Structure

    Following is the register structure for dispatch extended service hooks; it is used in Realtime Control Microcode Version 2.01 only.

    struct dhookenv
      {
       struct tcbstruct far *TCBNEXT; /* Pointer to next TCB in */
                                      /* the dispatch queue     */
       struct tcbstruct far *TCBPREV; /* Pointer to previous TCB*/
                                      /* in the dispatch queue  */
       };
    

    DMA Request Block

    This is a model of the direct memory access (DMA) request block. It is used to request and return 80186 DMA channels only.

    For the Realtime Interface Co-Processor Portmaster Adapter/A or the Realtime Interface Co-Processor Multiport Adapter, Model 2, the DMAs can only address 80186 logical memory and can no longer be connected to the communications controllers. The communication port request block can be used to allocate a communication controller and DMA channel.

    struct drbstruct
      {
       unsigned int   NEXT;    /* Offset of next request block. */
       unsigned int   PREV;    /* Offset of the previous block. */
       unsigned char  DRBID;   /* Block descriptor; must con-   */
                               /* tain 04h before use in SVC.   */
       unsigned char  DMANUM;  /* DMA channel requested; zero   */
                               /* for channel 0 or one for      */
                               /* channel 1.                    */
       unsigned char  TSKNUM;  /* This task's task number.      */
       unsigned char  ZEROREQ; /* This byte must contain zero.  */
       VECTOR         TCVECT;  /* 32-bit interrupt vector for   */
                               /* DMA terminal count interrupt. */
       unsigned int   DMAADDR; /* Base address of DMA channel;  */
                               /* set by Realtime Control       */
                               /* Microcode                     */
       };
    

    DMA/Peripheral Interface Communications Controller Request Block

    This is a model of the DMA/Peripheral Interface Communications Controller request block. It is used to request and return direct memory access (DMA)/Peripheral Interface Communications channels in Realtime Control Microcode Version 2.01 only.

    struct pdmaregstruct
      {
       unsigned int ccw;       /* Channel control word          */
       unsigned long target;   /* Target address                */
       unsigned char char2;    /* Character matching byte       */
       unsigned char char1;    /* Character matching byte       */
       unsigned int ioaddr;    /* I/O address                   */
       unsigned int count;     /* Transfer count                */
       unsigned long listptr;  /* List address pointer          */
       };
    

    Expanded Memory Pages Resource Block

    This is a model of the expanded memory pages resource block, which is used to allocate 16KB pages from expanded memory in Realtime Control Microcode Version 2.01 only.

    struct emmrbstruct
      {
       unsigned int NEXT;     /* Pointer to next block in list; */
                              /* set by RCM.                    */
       unsigned int PREV;     /* Pointer to previous block in   */
                              /* list; set by RCM.              */
       unsigned char EMMRBID; /* Block descriptor; must contain */
                              /* 0Dh before use in an SVC.      */
       unsigned char EMCONT;  /* Contiguous pages flag--        */
                              /*  00h = pages can be scattered  */
                              /*  01h = pages must be contiguous*/
       unsigned char EMMTASK; /* Owner task number of this block*/
       unsigned char RSV1;    /* Reserved for future use; must  */
                              /* be 0.                          */
       unsigned int EMMPAGES; /* Number of 16KB expanded memory */
                              /* pages requested.               */
       unsigned int EMMHANDLE /* EMM handle for allocated pages;*/
                              /* set by RCM.                    */
       unsigned int RSV2;     /* Reserved for future use; must  */
                              /* be 0.                          */
       };
    

    Extended Service Hooks Resource Block

    This structure may be used to allocate one or more hooks into any Realtime Control Microcode Version 2.01 service or the dispatch cycle. Any number of tasks can request the same hook.

    Refer to the Realtime Interface Co-Processor Firmware Technical Reference for a detailed explanation of this request block for Realtime Control Microcode Version 2.01 only.

    struct hookrbstruct
      {
       unsigned int NEXT;      /* Pointer to next block in list;  */
                               /* set by RCM.                     */
       unsigned int PREV;      /* Pointer to previous block in    */
                               /* list; set by RCM.               */
       unsigned char HOOKRBID; /* Block descriptor; must contain  */
                               /* 0Eh before use in an SVC.       */
       unsigned char HTYPE;    /* Type of hook; set by requestor. */
       unsigned char TSKNUM;   /* Owner task number of this block;*/
                               /* set by requestor.               */
       unsigned char RSV1;     /* Reserved for future use; must   */
                               /* be 0.                           */
       unsigned char HNUM;     /* Hook number requested; set by   */
                               /* requestor.                      */
       unsigned char HACCAT;   /* Access category of hook; set    */
                               /* by requestor.                   */
       unsigned int RSV2;      /* Reserved for future use; must   */
                               /* be 0.                           */
       VECTOR        USERRTN;  /* Address of user routine; set    */
                               /* by requestor.                   */
       VECTOR        NORMEXIT; /* Normal exit; set by RCM.        */
       VECTOR        QUICKEXIT;/* Quick exit; set by RCM.         */
       unsigned long RSV3;     /* Reserved for RCM use.           */
       unsigned long RSV4;     /* Reserved for RCM use.           */
        };
    

    Non-Dispatch Extended Service Hooks Parameter Structure

    Following is the parameter structure for non-dispatch extended service hooks for Realtime Control Microcode Version 2.01 only:

    struct hookparms
      {
       unsigned int BP;           /* Saved BP register            */
       struct tcbstruct far *TCB; /* Far pointer to caller's TCB  */
       unsigned int PREREQ;       /* Preemption request           */
       unsigned int HWINTCNT;     /* Depth of hardware interrupts */
                                  /* (0 = no hardware interrupt)  */
       unsigned int BX;           /* Saved BX register            */
       unsigned int SI;           /* Saved SI register            */
       unsigned int DS;           /* Saved DS register            */
       unsigned int ES;           /* Saved ES register            */
       };
    

    Non-Dispatch Extended Service Hooks Register Structure

    Following is the register structure for non-dispatch extended service hooks for Realtime Control Microcode Version 2.01 only:

    struct hookregs
      {
       unsigned int    AX;
       unsigned int    CX;
       unsigned int    DX;
       unsigned int    DI;
       unsigned int    FLAGS;
       };
    

    Non-Dispatch Extended Service Hooks Pointer Structure

    Following is the pointer structure for non-dispatch extended service hooks for Realtime Control Microcode Version 2.01 only:

    struct hookenv
      {
       struct hookparms far *hp;
       struct hookregs  far *hr;
       };
    

    Hardware Timer Request Block

    This is a model of the hardware timer request block, which is used to request and return hardware timers. Under Realtime Control Microcode Version 2.01, additional timers on any additional CIOs as defined in the EIB ROM can be allocated via this resource block. Realtime Control Microcode Version 2.01 uses one additional hardware timer for internal bus master command time-outs and to provide a time-of-day service.

    struct htrbstruct
      {
       unsigned int   NEXT;   /* Offset of next request block.   */
       unsigned int   PREV;   /* Offset of the previous block.   */
       unsigned char  HTRBID; /* Block descriptor; must contain  */
                              /* 06h before use in an SVC.       */
       unsigned char  TIMNUM; /* Hardware timer number 0 or 1.   */
       unsigned char  TSKNUM; /* Owner task number of this block.*/
       unsigned char  ZEROREQ;/* This byte must contain 0.       */
       VECTOR         HTVECT; /* 32-bit interrupt vector for     */
                              /* hardware timer interrupt.       */
       unsigned int HTADDR;  ;/* Base address of the hardware    */
                              /* timer; set by RCM.              */
       unsigned int HWRELINT; /* Hardware timer release          */
                              /* interrupt; set by RCM.          */
       };
    

    IB Structure

    This is a model of interface block (IB) structure; no field in it should be modified by a user task. It contains information describing the current status of the co-processor adapter.

    struct ibstruct
      {
       unsigned char  PCSEL;        /* PC select byte                */
       unsigned char  INTID;        /* Interrupt ID byte             */
       unsigned char  SUPVID;       /* ID of the control program     */
       unsigned char  RICID;        /* ID of this co-processor       */
                                    /* adapter                       */
       unsigned char  MAXTASK;      /* Highest possible task number  */
       unsigned char  MAXPRI;       /* Lowest possible priority      */
       unsigned char  MAXQUE;       /* Highest possible queue number */
       unsigned char  MAXTIME;      /* Highest possible timer number */
       unsigned int far *TCBTABPTR; /* 32-bit pointer to TCB table   */
       unsigned int far *PRILPTR;   /* 32-bit pointer to priority lst*/
       unsigned long  STORPTR;      /* Free storage list anchor      */
       unsigned int RSVD0;          /* Reserved word                 */
       unsigned long  HCD;          /* HCD                           */
       unsigned int   BCBPTR;       /* 16-bit offset of BCB array    */
       unsigned int far *TSKTABPTR; /* 32-bit pointer to task table  */
       unsigned int far *QUETPTR;   /* 32-bit pointer to queue table */
       unsigned int far *TIMPTR;    /* 32-bit ptr to timer table     */
       unsigned long  EXTHCD;       /* Extended HCD                  */
       unsigned int   EXTSTORSIZ;   /* Total number of 16KB pages of */
                                    /* storage on the co-processor   */
                                    /* adapter                       */
       unsigned int RSVD1;          /* Reserved word                 */
       unsigned long  RSVD2;        /* Reserved double word          */
       struct sibstruct far *SIBPTR;/* Pointer to supplemental IB    */
       unsigned int   STORSIZ;/* Number of RAM paragraphs below 960KB*/
       unsigned char  DB0ID;        /* Interface board 0 ID          */
       unsigned char  DB1ID;        /* Interface board 1 ID          */
       unsigned char  RCPSTAT;      /* RCM primary status            */
       };
    

    Peer Request Block

    This is a model of the peer request block. Explanation of the fields in the peer request block can be found in the Realtime Interface Co-Processor Firmware Technical Reference, Volume III.

    struct prbstruct
      {
      struct prbstruct far *QCHAINPTR;/* Pointer to queue chain; set   */
                                  /*    by requestor.                  */
      unsigned char CMDRESP;      /* Command/response code.            */
      unsigned char COMPCODE;     /* Completion code; set by RCM 2.01. */
      unsigned char PEEROPTNS;    /* Peer request option; set by       */
                                  /* requestor.                        */
      unsigned char CMDOPTNS;     /* Option flags; set by requestor.   */
      unsigned char TGTPROCID;    /* Target processor ID; set by       */
                                  /* requestor.                        */
      unsigned char SRCPROCID;    /* Source processor ID; set by       */
                                  /* RCM 2.01.                         */
      unsigned int TGTTASKID;     /* Target task ID; set by requestor. */
      unsigned int SRCTASKID;     /* Source task ID; set by requestor. */
      unsigned int REQBLKID;      /* Request Block ID; set by RCM 2.01.*/
      unsigned int DATACOUNT;     /* Data byte count; set by           */
                                  /* requestor.                        */
      unsigned int RSV1;          /* Reserved; must be 0.              */
      union
         {
         struct
             {
             unsigned char TGTCARDID; /* Target processor ID of the    */
                                      /* request; set by requestor.    */
             unsigned char SRCCARDID; /* Source processor ID; set by   */
                                      /* RCM 2.01.                     */
             } movinfo;
         unsigned int dataval;
         } DATAVAL1;           /* Data value 1 or immediate data;      */
                               /* set by requestor.                    */
      unsigned long DATAADD1;  /* Target buffer addr or immediate data;*/
                               /* set by requestor.                    */
      unsigned long DATAADD2;  /* Source buffer addr or immediate data;*/
                               /* set by requestor.                    */
      unsigned long DATAADD3;  /* Data address or immediate data;      */
                               /* set by requestor.                    */
      unsigned char RSV2[8];   /* Reserved work area.                  */
      };
    

    Interrupt Saved Register Structure

    This is a means for receiving parameters in an interrupt handler. A pointer to this structure is returned by the int_ntry routine so that interrupt handlers can examine the register contents.

    struct intenv
      {
       unsigned int ES;                      /* Saved ES register*/
       unsigned int DS;                      /*       DS         */
       unsigned int DI;                      /*       DI         */
       unsigned int SI;                      /*       SI         */
       unsigned int RSVD001;                 /* Reserved word    */
       unsigned int RSVD002;                 /* Reserved word    */
       unsigned int BX;                      /* Saved BX register*/
       unsigned int DX;                      /*       DX         */
       unsigned int CX;                      /*       CX         */
       unsigned int AX;                      /*       AX         */
       unsigned int INTRET;                /* Int. return addr.*/
       unsigned int BP_S;     /* Saved BP register - small model */
       unsigned int BP_MLH;/* Saved BP register - med/large/huge */
                              /* models                          */
       };
    

    Offset and Page Structure

    struct offpage
      {
       unsigned int OFFSET;           /*  16-bit offset value */
       unsigned char PAGE;            /*  8-bit page value    */
       };
    

    Offset and Segment Structure

    struct offseg
      {
       unsigned int   OFFSET;
       unsigned int   SEGMENT;
       };
    

    Primary Status Structure

    The following is a model of a primary status byte:

    struct psbstruct
      {
       unsigned LOADED  : 1;  /* task loaded bit               */
       unsigned INITZD  : 1;  /* task initialized bit          */
       unsigned RESTART : 1;  /* restart request bit           */
       unsigned WATCHDOG: 1;  /* watchdog timer active bit     */
                              /*  (only defined for RCM)       */
       unsigned ERROR   : 1;  /* error status bit              */
       unsigned ESTATS  : 1;  /* external status available bit */
       unsigned OBUFBZ  : 1;  /* output buffer busy bit        */
       unsigned TBUSY   : 1;  /* task busy bit                 */
       };
    

    User Queue Request Block

    The following is a model of the Queue Request Block which is used to request and return user queues:

    struct qrbstruct
      {
       unsigned int   NEXT;   /* Offset of next request block.  */
       unsigned int   PREV;   /* Offset of the previous block.  */
       unsigned char  QRBID;  /* Block descriptor; must contain */
                              /* 05h before use in an SVC.      */
       unsigned char  QUENUM; /* Queue number requested (0 -    */
                              /* MAXQUEUE.                      */
       unsigned char  TSKNUM; /* This task's task number.       */
       unsigned char  ZEROREQ;/* This byte must contain 0.      */
       };
    

    Supplemental Interface Block

    The supplemental interface block is an extension of the interface block and can be located via the pointer in the interface block.

    struct sibstruct
      {
       unsigned char SIBLEN;    /* Length of supplemental inter-*/
                                /* face block; set by RCM.      */
       unsigned char COPROCTYPE;/* Set by RCM.                  */
       unsigned char PATVER;    /* RCM patch level; set by RCM. */
       unsigned char MINVER;    /* RCM minor version code; set  */
                                /* by RCM.                      */
       unsigned char MAJVER;    /* RCM major version code; set  */
                                /* by RCM.                      */
       };
    

    Resource Count Structure

    The resource count structure contains a list of hardware and software resources for Realtime Control Microcode Version 2.01.

    struct res_cnt_struct
      {
       unsigned char COUNT;     /* Number of resource types     */
       unsigned char HWTIMER;   /* Number of hardware timers    */
       unsigned char SCCPORT;   /* Number of SCC ports          */
       unsigned char CIOPORT;   /* Number of CIO ports          */
       unsigned char SWTIMER;   /* Number of SW timers          */
       unsigned char USERQ;     /* Number of user queues        */
       unsigned char TASK;      /* Number of tasks              */
       unsigned char DMA;       /* Number of 80186 DMA channels */
       };
    

    Storage Request Block

    This is a model of the storage request block, which is used to request and return storage blocks in multiples of 16-byte paragraphs. It can only be used to allocate 80186 addressable memory (memory below 960KB).

    struct srbstruct
      {
       unsigned int   NEXT;   /* Offset of next request block;  */
                              /* set by RCM.                    */
       unsigned int   PREV;   /* Offset of the previous block;  */
                              /* set by RCM.                    */
       unsigned char  SRBID;  /* Block descriptor; must contain */
                              /* 02h before use in an SVC.      */
       unsigned char  HILO;   /* A value of 0 indicates that    */
                              /* the search for the block is to */
                              /* start in low storage.  When re-*/
                              /* turning a partial block, a 0   */
                              /* value means to return the lower*/
                              /* portion of the block.          */
       unsigned char  TSKNUM; /* This task's task number.       */
       unsigned char  ZEROREQ;/* This byte must contain 0.      */
       unsigned int   BOUND;  /* Requested storage boundary.    */
                              /* Must be even power of 2.       */
       unsigned int   SRSIZE; /* Requested size, in paragraphs. */
       unsigned int   SRSEG;  /* Segment location of storage    */
                              /* block; set by RCM.             */
       unsigned int   RETAMT; /* Amount of block to return.     */
       };
    

    TCB Structure

    The following structure is a model of the task control block (TCB). The only item that the task should ever modify is the posted flag (postf).

    struct tcbstruct
      {
       unsigned int  NEXT;       /* Offset of next TCB in queue */
       unsigned int  PREV;       /* Offset of the previous TCB  */
       unsigned char TSKN;       /* Task number for this TCB    */
       unsigned char TPRI;       /* Priority of the task        */
       unsigned char RETC;       /* Return code from RCM        */
       unsigned char STB;        /* Task's state byte           */
       unsigned int  PSTCD;      /* Task's post code            */
       unsigned char POSTF;      /* Posted flag                 */
       unsigned char PARENT;     /* Parent task number          */
       VECTOR        CVECT;      /* Command vector              */
       unsigned int  SSEG;       /* Task's stack segment        */
       unsigned int  SPTR;       /* Task's stack pointer        */
       };
    

    SCC and CIO Request Block

    This is a model of the serial communications controller (SCC) and counter/timer and parallel I/O unit (CIO) request block (URB). It is used to request and return a SCC-CIO port pair.

    This service is supported in Realtime Control Microcode Version 1.51 and earlier only; it is not supported in Realtime Control Microcode Version 2.01.

    struct urbstruct
      {
       unsigned int   NEXT;   /* Offset of next request block.  */
       unsigned int   PREV;   /* Offset of previous request     */
                              /* block.                         */
       unsigned char  URBID;  /* Block descriptor; must contain */
                              /* 03h before use in an SVC.      */
       unsigned char  SCCNUM; /* SCC channel requested (0 for   */
                              /* port A or 1 for port B).       */
       unsigned char  TSKNUM; /* This task's task number.       */
       unsigned char  ZEROREQ;/* This byte must contain 0.      */
       VECTOR         TXVECT; /* 32-bit pointer to SCC TX       */
                              /* interrupt handler.             */
       VECTOR         RXVECT; /* 32-bit pointer to SCC RX       */
                              /* interrupt handler.             */
       VECTOR         SCVECT; /* 32-bit pointer to SCC special  */
                              /* receive condition interrupt    */
                              /* handler.                       */
       VECTOR         EXVECT; /* 32-bit pointer to SCC external */
                              /* status interrupt handler.      */
       VECTOR         CIO0;   /* 32-bit pointer to CIO bit 0    */
                              /* interrupt handler.             */
       VECTOR         CIO1;   /* 32-bit pointer to CIO bit 1    */
                              /* interrupt handler.             */
       VECTOR         CIO2;   /* 32-bit pointer to CIO bit 2    */
                              /* interrupt handler.             */
       VECTOR         CIO3;   /* 32-bit pointer to CIO bit 3    */
                              /* interrupt handler.             */
       VECTOR         CIO4;   /* 32-bit pointer to CIO bit 4    */
                              /* interrupt handler.             */
       VECTOR         CIO5;   /* 32-bit pointer to CIO bit 5    */
                              /* interrupt handler.             */
       VECTOR         CIO6;   /* 32-bit pointer to CIO bit 6    */
                              /* interrupt handler.             */
       unsigned int   SCCB;   /* Base I/O address of the SCC    */
                              /* channel; set by RCM.           */
       unsigned int   CIOB;   /* Address of the CIO data        */
                              /* register; set by RCM.          */
       };
    

    Task Header Structure

    The following structure is a model of the task header:

    struct thstruct
      {
       unsigned long  LMODL;     /* Load module length          */
       unsigned char  TASK;      /* Task number                 */
       unsigned char  ZERO1;     /* Must be 0                   */
       unsigned int   TSKID;     /* User defined task id (0=RCM)*/
       unsigned char  PRIRTY;    /* Task priority               */
       unsigned char  ZERO2;     /* Must be 0                   */
       VECTOR         CMDPTR;    /* Command handler vector      */
       VECTOR         INITPTR;   /* Initial entry point vector  */
       unsigned int   DSEG;      /* Initial data segment value  */
       unsigned int   SSEG;      /* Initial stack segment value */
       unsigned int   SPTR;      /* Initial stack pointer value */
       unsigned int   RBPTR;     /* Request block pointer       */
       unsigned int   EXTOFF;    /* Offset of any extension     */
       };
    

    Software Timer Request Block

    Following is a model of the software timer request block, which is used to request and return software timers.

    struct trbstruct
      {
       unsigned int   NEXT;   /* Offset of next request block.  */
       unsigned int   PREV;   /* Offset of previous request     */
                              /* block.                         */
       unsigned char  TRBID;  /* Block descriptor; must contain */
                              /* 07h before use in an SVC.      */
       unsigned char  TIMNUM; /* Software timer number (0 -     */
                              /* MAXTIME).                      */
       unsigned char  TSKNUM; /* This task's task number.       */
       unsigned char  ZEROREQ;/* This byte must contain 0.      */
       };
    

    RS-232 Port Request Block (rs232rbstruct)

    The rs232rbstruct structure defines the format of an RS-232 request block. Structures of this type should be declared globally and initialized in the declaration statement.

    This resource block is supported in Realtime Control Microcode Version 1.51 or earlier only; the communications port resource block should be used with Realtime Control Microcode Version 2.01.

    struct rs232rbstruct
      {
       unsigned int  NEXT;     /* Offset of next request block. */
       unsigned int  PREV;     /* Offset of the previous block. */
       unsigned char RS232ID;  /* Block descriptor must contain */
                               /* 08h before use in an SVC.     */
       unsigned char RS232NUM; /* RS-232 port requested.        */
       unsigned char TSKNUM;   /* This task's task number.      */
       unsigned char ZEROREQ;  /* This byte must be 0.          */
       VECTOR        TXVECT;   /* 32-bit pointer to SCC TX      */
                               /* interrupt handler.            */
       VECTOR        RXVECT;   /* 32-bit pointer to SCC RX      */
                               /* interrupt handler.            */
       VECTOR        SCVECT;   /* 32-bit pointer to SCC special */
                               /* receive condition interrupt   */
                               /* handler.                      */
       VECTOR        EXVECT;   /* 32-bit pointer to SCC external*/
                               /* status interrupt handler.     */
       unsigned int  SCCB;     /* Base I/O address of the SCC   */
                               /* channel; set by RCM.          */
       };
    

    RS-422 Port Request Block (rs422rbstruct)

    The rs422rbstruct structure defines the format of an RS-422 request block. Structures of this type should be declared globally and initialized in the declaration statement.

    This resource block is supported in Realtime Control Microcode Version 1.51 or earlier only; the communications port resource block should be used with Realtime Control Microcode Version 2.01.

    struct rs422rbstruct
      {
       unsigned int  NEXT;     /* Offset of next request block. */
       unsigned int  PREV;     /* Offset of the previous block. */
       unsigned char RS422ID;  /* Block descriptor must contain */
                               /* 0Bh before use in an SVC.     */
       unsigned char RS422NUM; /* RS-422 port requested.        */
       unsigned char TSKNUM;   /* This task's task number.      */
       unsigned char ZEROREQ;  /* This byte must be 0.          */
       VECTOR        TXVECT;   /* 32-bit pointer to SCC TX      */
                               /* interrupt handler.            */
       VECTOR        RXVECT;   /* 32-bit pointer to SCC RX      */
                               /* interrupt handler.            */
       VECTOR        SCVECT;   /* 32-bit pointer to SCC special */
                               /* receive condition interrupt   */
                               /* handler.                      */
       VECTOR        EXVECT;   /* 32-bit pointer to SCC external*/
                               /* status interrupt handler.     */
       unsigned int  SCCB;     /* Base I/O address of the SCC   */
                               /* channel; set by RCM.          */
       };
    

    Communication Port Request Block

    The communication port request block structure defines the format of a communication port request block for Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2. Structures of this type should be declared globally and initialized in the declaration statement. This structure may be used for Zilog SCC and Signetics DUSCC ports in Realtime Control Microcode Version 2.01.

    struct cprbstruct
      {
       unsigned int  NEXT;     /* Offset of next request block. */
       unsigned int  PREV;     /* Offset of previous block.     */
       unsigned char CPRBID;   /* Block descriptor; must contain*/
                               /* 0Ch before use in an SVC.     */
       unsigned char CPNUM;    /* Communication port requested. */
       unsigned char TSKNUM;   /* This task's task number.      */
       unsigned char ZEROREQ;  /* This byte must be 0.          */
       VECTOR        TXVECT;   /* 32-bit pointer to SCC Tx      */
                               /* interrupt handler.            */
       VECTOR        RXVECT;   /* 32-bit pointer to SCC Rx      */
                               /* interrupt handler.            */
       VECTOR        SCVECT;   /* 32-bit pointer to SCC error   */
                               /* interrupt handler.            */
       VECTOR        EXVECT;   /* 32-bit pointer to SCC External*/
                               /* or Counter/Timer status       */
                               /* interrupt handler.            */
       unsigned int  SCCBASE;  /* Base I/O address of the SCC   */
                               /* channel; set by RCM.          */
       unsigned int  SCCRELINT;/* SCC release interrupt address;*/
                               /* set by RCM.                   */
       unsigned int  RXDMABASE;/* Receive DMA register base     */
                               /* address; set by RCM.          */
       unsigned int  TXDMABASE;/* Transmit DMA register base    */
                               /* address; set by RCM.          */
       unsigned int  RXDMAISR; /* Receive DMA DISR              */
                               /* address; set by RCM.          */
       unsigned int  TXDMAISR; /* Transmit DMA DISR address;    */
                               /* set by RCM.                   */
       VECTOR        RXDMAVEC; /* Receive DMA interrupt vector. */
       VECTOR        TXDMAVEC; /* Transmit DMA interrupt vector */
       unsigned char PORTTYPE; /* Port interface type. Requested*/
                               /* by user; returned by RCM.     */
       unsigned char SCCTYPE;  /* Communication controller type.*/
       };
    
             PORTTYPE = Port interface type
    
                        00h = RS-232
                        01h = RS-422
                        02h = V.35
                        03h = X.21
                        04h-FDh = reserved
                        FEh = Unknown
                        FFh = reserved, see text that follows
    
             SCCTYPE =  Communications controller type
                        00h = Zilog SCC
                        01h = Signetics DUSCC
                        02h-FDh = Reserved
                        FEh = Unknown
                        FFh = Reserved, see text that follows
    
    When allocating a communications port, the task must specify the block descriptor, port number, task number, and the SCC and DMA interrupt routines. The base address for the related hardware is provided upon allocation. Two additional fields, PORTTYPE and SCCTYPE, can be requested in the resource block. In the simplest case, these fields are set to indicate the type of interface and communications controller of the allocated port. These fields can also be used to specify the type of port desired, and an error is returned if the requested port does not have the desired characteristics. PORTTYPE and SCCTYPE of the port is always be returned.

    The user can request that the port be allocated only if the port meets the desired characteristics. For instance, if the SCCTYPE is 00h on input to the svcalloc call, the port is allocated only if the communications controller for the port is a Zilog SCC; otherwise, an error is returned. If the SCCTYPE is specified as FFh on input to the svcalloc call, Realtime Control Microcode Version 2.01 does not check the SCC type, but returns the information to indicate what type of communications controller is installed on that port.

    Similarly, the user may request that the port only be allocated if a specific physical interface is installed by specifying a requested value for the PORTTYPE field. This powerful feature takes advantage of information in the EIB ROM and allows an application task to request a port only if it meets the desired specifications.

    For some of the Signetics DUSCC registers that share bits between ports, the task needs to know which port of the DUSCC was assigned. Assignment of DUSCC port A is always to even-numbered ports and DUSCC port B is always to odd-numbered ports. Note that the CIO release interrupt address is not returned with the communications port resource block. An application should use the Logical Control Line Support routines to manage signals on the CIO.

    Vector Request Block

    This is a model of the vector request block, which is used to request and return software interrupt vectors. Refer to your co-processor adapter's technical reference document for a list of valid software interrupt vectors.

    struct vrbstruct
      {
       unsigned int   NEXT;   /* Offset of next request block.  */
       unsigned int   PREV;   /* Offset of the previous block.  */
       unsigned char VRBID;   /* Block descriptor; must contain */
                              /* 01h before use in an SVC.      */
       unsigned char VECTNUM; /* Requested vector number.       */
       unsigned char TSKNUM;  /* This task's task number.       */
       unsigned char ZEROREQ; /* This byte must contain 0.      */
       VECTOR        NEWVECT; /* New value for the vector.      */
       VECTOR        OLDVECT; /* Old value for the vector.      */
       VECTOR        ORIVECT; /* Original value of the vector.  */
       unsigned char FILL[8]; /* Reserved area; used by RCM.    */
       };
    

    SCC Port Request Block

    The sccrbstruct structure defines the format of a serial communications controller (SCC) port request block. This resource block can be used to allocate a single Zilog SCC or Signetics DUSCC. The preferred method for allocating a port on the Realtime Interface Co-Processor Portmaster Adapter/A is via the Communication Port Resource Block (0Ch), but this resource block allows just the communication port to be allocated. Structures of this type should be declared globally and initialized in the declaration statement.

    The DMA is not allocated with the SCC. To receive the DMA channels for an SCC port, the communications port resource block, cprbstruct, must be used.

    struct sccrbstruct
      {
       unsigned int  NEXT;     /* Offset of next request block. */
       unsigned int  PREV;     /* Offset of the previous block. */
       unsigned char SCCID;    /* Block descriptor must contain */
                               /* 09h before use in an SVC.     */
       unsigned char SCCNUM:   /* SCC port number requested.    */
       unsigned char TSKNUM;   /* This task's task number.      */
       unsigned char ZEROREQ;  /* This byte must be 0.          */
       VECTOR        TXVECT;   /* 32-bit pointer to SCC TX      */
                               /* interrupt handler.            */
       VECTOR        RXVECT;   /* 32-bit pointer to SCC RX      */
                               /* interrupt handler.            */
       VECTOR        SCVECT;   /* 32-bit pointer to SCC special */
                               /* receive condition interrupt   */
                               /* handler.                      */
       VECTOR        EXVECT;   /* 32-bit pointer to SCC external*/
                               /* status interrupt handler.     */
       unsigned int  SCCB;     /* Base I/O address of the SCC   */
                               /* channel; set by RCM.          */
       unsigned int SCCRELINT; /* SCC release interrupt address;*/
                               /* set by RCM.                   */
       };
    

    CIO Port Request Block

    The ciorbstruct structure defines the format of a counter/timer and parallel I/O unit (CIO) port request block.

    This resource block can be used to allocate a single CIO port. The preferred method for allocating a port on Realtime Interface Co-Processor Portmaster Adapter/A is via the communication port resource block as described previously, but this resource block allows a single CIO port to be allocated. See your co-processor adapter's technical reference document for the mapping between CIO port numbers and physical CIO ports.

    Structures of this type should be declared globally and initialized in the declaration statement.

    When allocating port C of a CIO, the interrupt vector field of the CIO port resource block has no meaning.

    struct ciorbstruct
      {
       unsigned int  NEXT;     /* Offset of next request block. */
       unsigned int  PREV;     /* Offset of the previous block. */
       unsigned char CIOID:    /* Block descriptor must contain */
                               /* 0Ah before use in an SVC.     */
       unsigned char CIONUM;   /* CIO port requested.           */
       unsigned char TSKNUM;   /* This task's task number.      */
       unsigned char ZEROREQ;  /* This byte must be 0.          */
       VECTOR        CIOINT;   /* 32-bit pointer to CIO         */
                               /* interrupt handler.            */
       unsigned int  CIOB;     /* I/O address of the CIO data   */
                               /* register; set by RCM.         */
       unsigned int  CIORELINT;/* CIO release interrupt address;*/
                               /* set by RCM.                   */
       };
    

    Chapter 3. Other Coding Considerations


    Usable Standard C Functions

    Many of the standard C library routines are not available in the co-processor adapter environment because they use system unit operating system services. The following is a list of some of the routines that can be used in C tasks:

         abs          isalnum       qsort          strncpy
         asctime      isascii       rand           strnicmp
         atof         iscntrl       _roti          strnset
         atoi         isxdigit      _rotr          strpbrk
         atol         itoa          segread        strrchr
         bdos         ldiv          _splitpath     strrev
         bsearch      lfind         sprintf        strset
         ctime        localtime     srand          strspn
         difftime     lsearch       strcat         strstr
         _disable     ltoa          strchr         _strtime
         div          _makepath     strcmp         strtod
         ecvt         max           strcmpi        strtok
         _enable      memccpy       strcpy         strtol
         fcvt         memchr        strcspn        strtoul
         FP_OFF       memcmp        _strdate       strupr
         FP_SEG       memcpy        strdup         swab
         ftime        memicmp       _strerror      time
         gcvt         memmove       strerror       toascii
         gmtime       memset        stricmp        _toupper
         inp          min           strlen         _tolower
         intdos       mktime        strlwr         ultoa
         intdosx      movedata      strncat        va_arg
         int86        outp          strncmp        va_start
         int86x
    
    The following math routines may be used if the user writes a matherr routine to handle errors from the math functions. The matherr routine can be as simple as a null function, if the user so desires. The matherr routine is described in more detail in the C compiler reference manual.
         acos         cosh            fmsbintoieee   pow
         asin         dieeetomsbin    _fpresent      sin
         atan         dmsbintoieee    frexp          sinh
         atan2        exp             hypot          sqrt
         bessel       fabs            ldexp          tan
         cabs         fieeetomsbin    log            tanh
         ceil         floor           log10
         cos          fmod            modf
    
    The following routines may be used, but the requests are directed to the co-processor adapter and the Realtime Control Microcode rather than to the system unit processor and DOS or OS/2:
         bdos          intdos        int86x        segread
         ftime         intdosx       outpw         time
         inpw          int86
    

    Interrupt Handlers

    The Realtime Interface Co-Processor C Language Support provides the means for writing interrupt handlers in C language. These interrupt handlers may be used to service both hardware and software interrupts. Hardware interrupts consist of SCC, CIO, DMA, software timers, or hardware timer interrupts; software interrupts are generally received by way of user-requested software interrupt vectors.

    The following comments apply to all interrupt handlers:

    Hardware Interrupt Handlers

    Software and hardware interrupt handlers have their own set of routines for entry and exit. Hardware interrupt handlers should use the routines int_ntry and int_exit for entry and exit. The int_ntry function saves the machine environment and returns a pointer to the register save area. The register save area has the format defined by the intenv structure. The following is an example of a hardware interrupt handler:

       void far hardware_int_handler ()
       {
        struct intenv far *regs;
    
        regs = int_ntry ();/* Call to "int_ntry" must be first */
    
                     /* ------------------------ */
                     /* Code to handle interrupt */
                     /* ------------------------ */
    
        int_exit();        /* Call to "int_exit" must be last  */
        }
    
    The following comments apply to hardware interrupt handlers:

    Software Interrupt Handlers

    Software interrupt handlers should use the functions int_ntry, sfw_chn, and sfw_exit. The sfw_chn is a function unique to software interrupt handlers. First, it checks the intended task number of the interrupt. If the interrupt is intended for the current task, control is returned to the interrupt handler. If the interrupt is not intended for the current task, control is passed on to the next owner of the interrupt through the OLDVECT field in the interrupt vector request block. The sfw_exit function restores the registers and passes control to either the next owner of the interrupt vector or to the Realtime Control Microcode, depending on the value of the quick parameter. The interrupt vector request block pointer passed to sfw_chn and sfw_exit should be the address of the vector request block used to acquire the interrupt vector.

    The following is an example of a software interrupt handler:

    void far software_interrupt_handler()
    {
     struct intenv far *regs;
    
      regs = int_ntry();            /* Save environment; get */
                                    /* pointer to registers. */
    
      sfw_chn (&vec;_req_block);     /* Jump to next owner of */
                                    /* vector if this task   */
                                    /* isn't supposed to get */
                                    /* the interrupt.        */
    
                 /* --------------------------------- */
                 /* Code to handle software interrupt */
                 /* --------------------------------- */
    
      sfw_exit(0,&vec;_req_block);   /* Exit handler, passing */
                                    /* control to the next   */
                                    /* owner of the vector.  */
      }
    
    The following comments apply to software interrupt handlers:

    Building Other Tasks

    Tasks may be created with the svcbuild function, which simulates a task load from the system unit. The new task may be created as a peer task outside the building task or as a child task within the building task. Once a task is built, the task should be started with the svcstart function.

    Each task that is built requires its own unique command handler (__cmdent) and interrupt entry call (int_ntry, dhook_ntry, or hook_ntry). A set of these routines is provided in the file, childsub.asm. In this file, the command handler is called __cmdent2, and the interrupt entry routine is called int_ntry2. For a second built task, the childsub.asm file should be copied, and the labels should be changed so that they are unique (for instance, __cmdent3 and int_ntry3). Each copy of the childsub.asm file should be assembled and linked into the task. It is mandatory that each child task use its version of the command handler and interrupt entry call.

    Users who write code to build C tasks should have a complete understanding of C segments and groups; this information can be found in the C compiler manual. Building tasks from C tasks has restrictions imposed by the C compiler. The svcbuild function is provided for C tasks, but it may be simpler to build tasks in assembly language.

    Child Tasks

    The BuildChild() routine is provided in the file childc.c for building child tasks. In BuildChild(), the task header is first initialized. The svcbuild() function is then called with the task header pointer and a null value for the storage request block; no storage request block is required for building child tasks. (Remember that the task header must start on a paragraph boundary.) A child task has its code, data, and stack within the building (parent) task's load module, however the child task may not access the parent's global variables. The stack area for the child task should directly follow the child's task header. In addition, stack checking should be disabled in child task code because the child task's is located before the end of the parent's data area.

    A child task may not build other tasks. When the parent (building) task is stopped, all its child tasks are unloaded.

    Peer Tasks

    The BuildPeer() routine is provided in the file childc.c for building peer tasks. In BuildPeer(), the storage is first allocated for the new task. BuildPeer() assumes that the two tasks share their code; therefore, space is only required for the data and the stack. If separate copies of the code are desired, space should be allocated for the entire task module (the size is in the LMODL field of the task header). The data area is then copied into the new peer task's data area.

    Next, BuildPeer() fills in the task header fields in the allocated memory block. The size of the allocated memory block should be stored in the LMODL field of the new header. The svcbuild() function is called to notify Realtime Control Microcode of the new task. The building task's data should be copied into the new peer task's data area. Finally, the task should be started with the svcstart() function.

    Note:

    In the large memory model, the built task has its own base data segment but it shares the building task's extra data segments. Multiple data segments are implemented in the C compiler by keeping a base data segment in DS and saving pointers to the other data segments in the base data segment. Because the C Language Support does not know where these pointers are, and cannot modify them to point into the new task, they continue to point to the building task's data area.

    Debugging C Tasks

    DOS and OS/2 program debuggers are available as part of the Realtime Interface Co-Processor Developer's Kit, and can be used with the Realtime Interface Co-Processor, the Realtime Interface Co-Processor Multiport, the Realtime Interface Co-Processor Multiport/2, the X.25 Interface Co-Processor/2, and the X.25 Interface Co-Processor.

    When combined with the C Compiler code listing and the link map file, the Realtime Interface Co-Processor Program Debugger is useful in debugging C tasks. The user should first generate the .COD and .MAP files. The following commands show an example of generating these files. Note that the /Gs and /Od options must also be used if the task contains interrupt handlers.

    Microsoft C 6.0 Optimizing Compiler:
    
       cl /c /AM /G1 /Zp /Fm /Fc task.c
       link icaheadc+task/NOD /NOE/m,task,,
           icams60m+icatskm+mlibca
    
    IBM C/2(4) 1.1 Compiler:
    
       cc /AM /G1 /Zp task,,,task;
       link icaheadc+task/NOD /NOE/m,task,,
           icac2m+icatskm+mlibcar
    

    The same compile and link options used for Microsoft C 6.0 compiler can be used for the Microsoft C 7.0 and Microsoft C 8.0 compilers. These commands generate a code listing, task.cod, and a link map, task.map. These two files can be used for finding code and data in the task.

    The next step is to load the co-processor adapter software including the program debugger. The following example loads the Realtime Control Microcode for co-processor 0 for a Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport, Realtime Interface Co-Processor Multiport/2, and X.25 Interface Co-Processor/2:

            icainth
            icaload 0 icaaim.com 0
            icadeb 0
    
    Then load the task onto the co-processor adapter without starting it, as in the following example:
            icaload 0 task.exe 1 L
    
    Enter the program debugger by pressing the toggle keys Alt+Esc. Display the task header with the Display command.
            >> d 1#0
    
    When memory is displayed, the address for each line is displayed on the left side of the screen; in this case, the address segment is the segment of the task header. Next, find the address of the the _main label in the link map list of public labels. Add the segment of the task header to the relative segment of the _main label; the sum is the segment in co-processor adapter memory of the task's main routine.

    For example, if the task header is located at segment 0x2000, and the address of the _main label is 0096:000A, then the address of _main is 2096:000A. Use this address when starting the task, as in the following example:

            >> st 1# 2096:000A
    
    This command starts the task and halts it when it enters the main() function of the task. From this point, the user can single-step through the task, display task data, and do what is necessary to debug the task.

    Error-Handling Task

    An error handling task, icaceh.com, is provided with the Realtime Interface Co-Processor C Language Support for the co-processor adapter. Its purpose is to watch for errors occurring in C tasks. It monitors the division by zero, overflow, array bounds exception, and undefined opcode interrupts. When one of the preceding errors occurs, icaceh.com checks the ID of the task in which the error occurred. If the error occurred in a C task, the C task is suspended, and the error and status available bits in its primary status byte are turned on. An error code is also stored in the C task's extended status buffer.

    The following format is used for storing error codes in C tasks' status buffers:

           Extended Status Values for Run-Time Errors
    
            Byte 0   Byte 1   Error Description
    ==============================================================
             0xFE    0x0000   Division by 0
             0xFE    0x0001   INTO overflow
             0xFE    0x0002   Array bounds exception
             0xFE    0x0003   Undefined opcode
             0xFE    0x0004   Escape opcode
             0xFE    0x0007   Translate Table error
             0xFE    0x0008   DAC error interrupt
             0xFE    0x0009   Extended non-maskable
                              interrupt error
    
    Use of the error handling task is optional; if the user does not want to use its services, the error handling task should not be loaded. If the user does want to use its services, the error handling task should be loaded and started with the DOS Support or OS/2 Support Application Loader.

    When the error handling task is used, it has the following requirements:


    Chapter 4. Using the Co-Processor Adapter Support


    Compiling Instructions

    Every task should include the statement:

            #include "icadeclt.h"
    
    This statement includes the declarations needed to use the Realtime Interface Co-Processor C Language Support for the co-processor adapter.

    The following compiler options should be used when compiling C tasks:

    /G1
    This option causes the compiler to generate code for the 80186, the CPU on the co-processor adapter.

    /Zp
    This option causes the supplied structures to be packed. If they are not packed, the generated programs do not access the structures correctly.

    /Ze
    This option enables the use of the far, near, and huge keywords. This is only required for the IBM C/2 Compiler.

    /Gs
    This option disables stack checks at the start of each function call. This option is required when compiling C interrupt handlers; it can also be used to improve performance in other C routines.

    /FPa
    This option must be used with C compilers if floating-point operations are going to be performed on the co-processor adapter. This causes code to be generated to use the alternate floating-point libraries.

    /Od
    This option disables optimization and must be used for interrupt handlers compiled with the C compilers.

    The following section describes the compilation steps.

    Microsoft C 6.0 Optimizing Compiler

    The following example shows a user task, ctask.c, being compiled in the small memory model (the /Gs and /Od options must be added if the task contains an interrupt handler):
       cl /AS /G1 /Zp /c ctask.c
    
    If the same task is compiled in the medium memory model, the command looks like this (the /Gs and /Od options must be added if the task contains an interrupt handler):
       cl /AM /G1 /Zp /c ctask.c
    
    If the user task is compiled in the large memory model, the compile command looks like this (the /Gs and /Od options must be added if the task contains an interrupt handler):
       cl /AL /G1 /Zp /c ctask.c
    

    IBM C/2 1.1 Compiler

    The following example shows a user task, ctask.c, being compiled in the small memory model (the /Gs and /Od options must be added if the task contains an interrupt handler):

       cc /AS /G1 /Zp ctask,ctask,ctask,ctask;
    
    If the same task is compiled in the medium memory model, the command looks like this (the /Gs and /Od options must be added if the task contains an interrupt handler):
       cc /AM /G1 /Zp ctask,ctask,ctask,ctask;
    
    If the user task is compiled in the large memory model, the compile command looks like this (the /Gs and /Od options must be added if the task contains an interrupt handler):
       cc /AL /G1 /Zp ctask,ctask,ctask,ctask;
    

    Microsoft C/C++ V7.0 and Visual C/C++ V1.5 Compilers

    The same indications listed for the Microsoft C 6.0 optimizing compiler apply. See "Microsoft C 6.0 Optimizing Compiler".


    Linking Instructions

    When linking C object modules for the co-processor adapter, certain link parameters and options must be used. Consider the following when linking C tasks.

    If floating-point support is used, the floating-point libraries must be specified after the Realtime Interface Co-Processor C Language Support library, but before the standard C/2 library.

    The following sections describe the link instructions.

    Microsoft C 6.0 Optimizing Compiler

    The following example shows a sample object file ctask.obj being linked with the Realtime Interface Co-Processor C Language Support and standard small memory model libraries:

       link icaheadc+ctask/NOD /NOE,ctask,ctask,icams60s+icatsks+slibca
    
    If the sample file is compiled in the medium model, the link command looks like this:
       link icaheadc+ctask/NOD /NOE,ctask,ctask,icams60m+icatskm+mlibca
    
    If the sample file is compiled in the large or huge memory model, the link command looks like this:
       link icaheadc+ctask/NOD /NOE,ctask,ctask,icams60l+icatskl+llibca
    

    IBM C/2 1.1 Compiler

    The following example shows a sample object file ctask.obj being linked with the Realtime Interface Co-Processor C Language Support and standard small memory model libraries:

       link icaheadc+ctask/NOD /NOE,ctask,ctask,icac2s+icatsks+slibcar;
    
    If the sample file is compiled in the medium model, the link command looks like this:
       link icaheadc+ctask/NOD /NOE,ctask,ctask,icac2m+icatskm+mlibcar;
    
    If the sample file is compiled in the large or huge memory model, the link command looks like this:
       link icaheadc+ctask/NOD /NOE,ctask,ctask,icac2l+icatskl+llibcar;
    

    Microsoft C/C++ V7.0 and Visual C/C++ V1.5 Compilers

    The same indications listed for the Microsoft C 6.0 optimizing compiler apply (see "Microsoft C 6.0 Optimizing Compiler") with the following exceptions:


    Chapter 5. Library Routines

    This chapter describes the co-processor adapter C Language interface routines in detail.

    Some of the functions accept bit-sensitive parameters. Such parameters are defined with lowercase letters for each bit that is used. The letter "x" indicates that a bit is not used in the parameter; its value does not matter. For example, the definition "xxxx abcd" indicates that the top four bits are not used but the bottom four bits are used as function parameters.


    atoe

    Purpose:

    Converts an ASCII character array to EBCDIC.

    Format:

    #include "icadeclt.h"
    
    unsigned int ICAENTRY atoe(source_ptr,dest_ptr,
                               length);
    unsigned char *source_ptr; /* Pointer to source. */
    unsigned char *dest_ptr;   /* Pointer to         */
                               /* destination.       */
    unsigned int length;       /* Length of arrays.  */
    
    Remarks:

    The atoe function takes an ASCII character array pointed to by source_ptr and converts it to an EBCDIC character array. The pointer dest_ptr should point to where the converted characters is stored. Instead of using the null character ('\0') to mark the end of the array, the length parameter is used to set the number of characters to convert.

    This routine performs the same function as PROM Services interrupt 0xC4.

    Returns:

    Converted destination string.
    Function value =
            0x0000 = Normal completion, no errors.
            0x0001 = Zero array length.
    
    Example:
    #include "icadeclt.h"
    
    unsigned char ascii_buf[10], ebcdic_buf[10];
    int error_code;
    
    error_code = atoe (ascii_buf, ebcdic_buf, 10);
    
    Related Topics:
         convtptr, etoa
    

    bcb_cmd_r

    Purpose:

    Reads the command byte field of the task's buffer control block (BCB).

    Format:

    #include "icadeclt.h"
    
    unsigned char ICAENTRY bcb_cmd_r(void);
    
    Remarks:

    The bcb_cmd_r function reads the calling task's BCB command byte field.

    Returns:

    No error codes are returned by this function.

    Function value = Command byte from the task's BCB

    Example:

    #include "icadeclt.h"
    
    unsigned char next_command;
    
    next_command = bcb_cmd_r();
    
    Related Topics:
         bcb_ib_r, bcb_ob_r, bcb_st_r
    

    bcb_ib_r

    Purpose:

    Reads the length and address of the task's input buffer from the buffer control block (BCB).

    Format:

    #include "icadeclt.h"
    
    void ICAENTRY bcb_ib_r(inlength,inptr);
    unsigned int *inlength;  /* Address of buffer */
                             /* length            */
    unsigned char **inptr;   /* Address of buffer */
                             /* pointer           */
    
    Remarks:

    The bcb_ib_r function reads the input buffer address and length from the task's BCB. The inlength and inptr parameters should contain the addresses of where the input buffer length and address is stored. The input buffer address is converted from page-and-offset format to C-pointer format before it is returned.

    Returns:

    No error codes are returned by this function.

    Example:

    #include "icadeclt.h"
    
    unsigned int inbuf_length;
    unsigned char *inbuf_addr;
    
    bcb_ib_r (&inbuf;_length,&inbuf;_addr);
    
    Related Topics:
         bcb_cmd_r, bcb_ib_w, bcb_ob_r, bcb_st_r
    

    bcb_ib_w

    Purpose:

    Writes to the input buffer fields of the task's buffer control block (BCB).

    Format:

    #include "icadeclt.h"
    
    void ICAENTRY bcb_ib_w(inlength,inptr);
    unsigned int inlength; /* Input buffer length  */
    unsigned char *inptr;  /* Input buffer address */
    
    Remarks:

    The bcb_ib_w function writes to the BCB input buffer fields, where inlength is the buffer's length and inptr is the address of the input buffer. The buffer address is converted to page:offset format before it is written to the BCB.

    If the buffer is in acquired storage, the storage address should be converted with the seg2page function and then written directly to the task's BCB.

    The BCB buffer fields should be initialized before the task begins communication with a system unit program.

    Returns:

    No error codes are returned by this function.

    Example:

    #include "icadeclt.h"
    
    unsigned char input_buffer[10];
    
    bcb_ib_w(10,input_buffer);
    
    Related Topics:
         bcb_ib_r, bcb_init, bcb_ob_w, bcb_st_w
    

    bcb_init

    Purpose:

    Initializes the buffer fields of the task's buffer control block (BCB).

    Format:

    #include "icadeclt.h"
    
    void ICAENTRY bcb_init(slength,stptr,inlength,inptr,
                           outlen,outptr);
    unsigned int  slength;  /* Status buffer fields */
    unsigned char *stptr;
    unsigned int  inlength; /* Input buffer fields  */
    unsigned char *inptr;
    unsigned int  outlen;   /* Output buffer fields */
    unsigned char *outptr;
    
    Remarks:

    The bcb_init function writes to the status buffer, input buffer, and output buffer fields in the task's BCB. This function combines the functions of bcb_ib_w, bcb_ob_w and bcb_st_w. The buffer addresses are converted to page:offset format before they are written to the BCB.

    The BCB buffer fields should be initialized before the task begins communication with a system unit program.

    If any buffers are in acquired storage, the storage addresses should be converted with the seg2page function and then written directly to the task's BCB.

    Returns:

    No error codes are returned by this function.

    Example:

    #include "icadeclt.h"
    
    unsigned char estatbuf[20];
    unsigned char inbuf[21];
    unsigned char outbuf[22];
    
    bcb_init(20,estatbuf,21,inbuf,22,outbuf);
    
    Related Topics:
         bcb_ib_w, bcb_ob_w, bcb_st_w
    

    bcb_ob_r

    Purpose:

    Reads the input buffer fields of the task's buffer control block (BCB).

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY bcb_ob_r(outlen,outptr);
    unsigned int *outlen;   /* Address of buffer */
                            /* length.           */
    unsigned char **outptr; /* Address of buffer */
                            /* pointer.          */
    
    
    Remarks:

    The bcb_ob_r function returns the output buffer length and address in the parameters outlen and outptr. The values are read from the task's BCB. The output buffer address is converted from page:offset format to C-pointer format before it is returned.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned int outbuf_len;
    unsigned char *outbuf_ptr;
    
    bcb_ob_r(&outbuf;_len,&outbuf;_ptr);
    
    Related Topics:
         bcb_ib_r, bcb_ob_w, bcb_st_r
    

    bcb_ob_w

    Purpose:

    Writes to the output buffer field of the task's buffer control block (BCB).

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY bcb_ob_w(outlen,outptr);
    unsigned int  outlen;    /* Length of output  */
                             /* buffer.           */
    unsigned char *outptr;   /* Address of output */
                             /* buffer.           */
    
    Remarks:

    The bcb_ob_w function writes to the task's BCB output buffer fields, where outlen is the buffer length and outptr is the buffer address. The address is converted to page:offset format before it is written to the BCB.

    If the buffer is in acquired storage, the storage address should be converted with the seg2page function and then written directly to the task's BCB.

    The BCB buffer fields should be initialized before the task begins communication with a system unit program.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned char output_buffer[10];
    
    bcb_ob_w(10,output_buffer);
    
    Related Topics:
         bcb_ib_w, bcb_init, bcb_ob_r, bcb_st_w
    

    bcb_st_r

    Purpose:

    Reads the length and address of the task's extended status buffer from the task's buffer control block (BCB).

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY bcb_st_r(slength,stptr);
    unsigned int *slength;    /* Address of buffer */
                              /* length            */
    unsigned char **stptr;    /* Address of buffer */
                              /* pointer           */
    
    Remarks:

    The bcb_st_r function reads the extended status buffer length and address from the task's BCB, and returns them in the slength and stptr parameters. The status buffer address is converted from page:offset format to C-pointer format before it is returned.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned int estat_length;
    unsigned char *estat_addr;
    
    bcb_st_r (&estat;_length,&estat;_addr);
    
    Related Topics:
         bcb_cmd_r, bcb_ib_r, bcb_ob_r, bcb_st_w
    

    bcb_st_w

    Purpose:

    Writes to the extended status buffer fields of the task's buffer control block (BCB).

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY bcb_st_w(slength,stptr);
    unsigned int  slength;   /* Length of buffer  */
    unsigned char *stptr;    /* Address of buffer */
    
    Remarks:

    The bcb_st_w function writes to the task's BCB extended status buffer fields, where slength is the buffer length and stptr is the buffer address. The address is converted to page&ggml.offset; format before it is written in the BCB.

    If the buffer is in acquired storage, the storage address should be converted with the seg2page function and then written directly to the task's BCB.

    The BCB buffer fields should be initialized before the task begins communication with a system unit program.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned char estat_buffer[10];
    
    bcb_st_w(10,estat_buffer);
    
    Related Topics: bcb_ib_w, bcb_init, bcb_ob_w, bcb_st_r

    cantime

    Purpose:

    Cancels the use of a software timer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY cantime(timer);
    unsigned char timer;
    
    Remarks:

    The cantime function cancels the software timer given by the timer parameter. If the timer is not running, no action is taken.

    This routine performs the same function as the svccantm function, except that cantime does not cause a dispatch cycle when it is invoked. This is the same function as SVI 0x68.

    Returns:

    Function value =
            0x0000 = Normal completion, no errors
            0x0015 = Invalid timer number
            0x0005 = Access denied
    
    A software timer should be allocated with the svcalloc function and started with the svctimer or svcprdic functions before it can be canceled.

    Example:

    #Include "icadeclt.h"
    
    unsigned char timer_num; /* Start and cancel a */
                             /* software timer.    */
    unsigned int duration;
    void (far *timer_handler)(void);
                             /* Assume timer is    */
                             /* already allocated. */
    
    svctimer(timer_num,duration,timer_handler);
                          /* Start software timer. */
    
    cantime(timer_num);           /* Cancel timer. */
    
    Related Topics:
         svcalloc, svccantm, svcprdic, svctimer
    

    cioreg

    Purpose:

    Enables, disables, or configures a port for a counter/timer and parallel I/O unit (CIO).

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY cioreg(port,request,table_ptr);
    unsigned char port;
    unsigned char request;
    unsigned char *table_ptr;
    
    Remarks:

    The cioreg function enables, disables, or configures a CIO port or accesses the CIO registers. Port C of CIO 0 cannot be configured. Realtime Control Microcode Version 2.01 has added support for additional CIO ports. All registers may be read, and all registers except the interrupt vector registers and the command and status registers may be written. The CIO port should be allocated with the svcalloc function before it is used.

    The parameter port should contain the number of the port to configure. The bit-sensitive request parameter is used to define the CIO operation; the following table shows the request bits and their corresponding operations:

            00xxxxx0 = Disable port
            01xxxxx0 = Enable port
            10xxxxx0 = Disable port and write CIO
                       registers
            11xxxxx0 = Disable port, write CIO
                       registers and enable
                       port
            xxxxxxx1 = Read CIO registers
    
    If a read or write register request is made, the pointer table_ptr should point to a parameter table. The first character of the parameter table should be a count of registers to read or write. Following the count are character pairs in which the first character in the pair is a pointer to the register to be read or written. If a write is requested, the second character is the value to write; if a read is requested, the second character is overwritten with the value read.

    Only the following CIO register pointers are valid. These pointers do not correspond directly with the Z8036 CIO register address specification. Registers 0x09 and 0x0A are read only; all others are read/write.

            0x00  Data register
            0x01  Mode specification register
            0x02  Handshake register
            0x03  Polarity register
            0x04  Direction register
            0x05  Special I/O register
            0x06  Pattern polarity register
            0x07  Pattern transition register
            0x08  Pattern mask register
            0x09  Command/status register (read only)
            0x0A  Interrupt vector register (read only)
    
    This routine performs the same function as PROM Services interrupt 0xA6. See your co-processor adapter's Technical Reference manual for more information on programming the 8036 CIO.

    Returns:

    Function value =
            0x0000 = Normal completion, no errors
            0x0001 = Invalid register specification
                     if a read was requested; or
                     invalid port
            0x0018 = Invalid port number.
    

    Example:

    #Include "icadeclt.h"
    
    unsigned char cio_table[10], port, request;
    
       /* Set up CIO port 0 for straight-forward ASYNC */
    
    cio_table[0] = 4;     /* Four registers to write   */
    
    cio_table[1] = 1;         /* Mode spec. reg        */
    cio_table[2] = 0;         /*   = bit-port, disable */
                              /*     pattern match     */
    
    cio_table[3] = 3;         /* Polarity register     */
    cio_table[4] = 0;         /*   = non-inverting     */
    
    cio_table[5] = 4;         /* Direction register    */
    cio_table[6] = 0;         /*   = all output bits   */
    
    cio_table[7] = 0;         /* Data register         */
    cio_table[8] = 0;         /*   = dummy data        */
    
    port = 0;                 /* Select port 0         */
    request = 0xC0;           /* Disable,write,enable  */
    
    cioreg(port,request,cio_table);/* Set up CIO port 0*/
    
    Related Topics:
         ciotimer, svcalloc
    

    ciotimer

    Purpose:

    Stops, starts, triggers or configures the requested hardware timer.

    Format:

    #Include "icadeclt.h"
    
    unsigned int ICAENTRY ciotimer(timer,request,timeout);
    unsigned char timer;          /* CIO timer number */
    unsigned char request;        /* Request code     */
    unsigned int timeout;         /* Timeout value    */
    
    Remarks:

    The ciotimer function starts, stops, triggers, and configures a timer for a counter/timer and parallel I/O unit (CIO). CIO 0 timer 3 cannot be accessed. The timer parameter should contain the number of the timer to configure. The request parameter is bit-sensitive so that various options can be combined into one call. The following table shows the request bits and their corresponding operations:

       xxxxxxx1   Activates bit 2; set single or
                  continuous mode
       xxxxx0x1   Stop timer and set single-cycle
                  mode
       xxxxx1x1   Stop timer and set continuous-
                  cycle mode
    
       x1xxxxxx   Activates bit 7; set restart or
                  retrigger
       01xxxxxx   Restart timer (starts count from
                  where it left off with same options)
       11xxxxxx   Retrigger timer (reloads count with
                  new options)
    
       xx1xxxxx   Activates bit 4; disable or enable
                  interrupts
       xx10xxxx   Disable timer interrupts
       xx11xxxx   Enable timer interrupts
    
       xxxxxx1x   Read timer count into timeout parameter
                  (stops timer)
    
    If the timeout has a value of 0, the timer timeout value is not changed; otherwise, the timer gets the new timeout value.

    If a request is made to change the continuous/single cycle mode and/or the timeout value and a restart option is chosen, the reconfiguration does not take effect until the next (re)trigger of the timer.

    Returns:

    If a timeout is read, the function return value contains the timeout value; otherwise, the return value is meaningless.

    A CIO timer should be allocated with the svcalloc before it is accessed.

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
                                 /* Request codes */
    #define STOP_CONT 0x05
    #define READ_TIMER 0x02
    
    unsigned int ICAENTRY timeout;
    
            /* Stop timer 0, set continuous mode, */
            /* and read timeout value             */
    timeout = ciotimer(0,(STOP_CONT|READ_TIMER),0);
    
    Related Topics:
         cioreg, svcalloc
    

    cli

    Purpose:

    Reads the appropriate diagnostic address compare (DAC) registers.

    Format:

    #include "icadeclt.h"
    
    void ICAENTRY dacread (controlinfo, physaddr)
    unsigned int *controlinfo;
    unsigned long *physaddr;
    
    Remarks:

    The dacread function performs the read function of INT CEh, AH = 06. This routine does not return an error code, and is defined only for Realtime Control Microcode Version 2.01.

    Returns:

    Function value =
       CONTROLINFO = source information
       PHYSADDR    = 32-bit address where DAC occurred
    
    Example:
    #include "icadeclt.h"
    
    unsigned int *controlinfo;
    unsigned long *physaddr;
    
    dacread(controlinfo, &physaddr;);
    
    Related Topics:
         dacwrite
    

    dacwrite

    Purpose:

    Writes to the appropriate diagnostic address compare (DAC) registers.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY dacwrite (controlinfo, physaddr,
                            range, mode)
    unsigned int controlinfo;
    unsigned long physaddr;
    unsigned int range;
    unsigned char mode;
    
    Remarks:

    The dacwrite function performs the write function of INT CEh, AH = 06. The dacwrite function is passed control information, a physical address, a range and a mode. This function is defined only for Realtime Control Microcode Version 2.01.

    controlinfo  =
       Bit 0 = 0 = Monitor read/write accesses
               1 = Monitor only write accesses
       Bit 1 = 1 = Monitor 80C186 accesses
       Bit 2 = 1 = Monitor memory slave accesses
       Bit 3 = 1 = Monitor backend DMA accesses
       Bit 4 = 1 = Monitor busmaster channel accesses
       Bit 5 = 0 = Do not block the memory write
                   attempt
               1 = Block the memory write attempt
    physaddr = 32-bit physical address for start
               of memory
    range    = To mark address range of memory to
               mark, up to 64KB
    mode     = 0x0000 = Write, disable DAC
               0x0001 = Write, enable DAC (Note: If
                        disable is chosen, however,
                        the parameters still need to
                        be passed; other parameters
                        are ignored.)
    
    Returns:

    This routine does not return a function value.

    Example:

    #Include "icadeclt.h"
    
    unsigned long physaddr;
    physaddr 0x0000;
    
    dacwrite (0x11, physaddr, 0xFFFF);
     /* Monitor write accesses to channel 1 in 64KB range;*/
     /* enable DAC; start at physical address 0.          */
    
    Related Topics:
         dacread
    

    dhook_exit

    Purpose:

    Restores the machine environment after an application has used a dispatch extended service hook. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY dhook_exit (exit_flag, dhookrb)
    unsigned int exit_flag;
    struct hookrbstruct *dhookrb;
    
    Remarks:

    The user application must ensure that upon return to Realtime Control Microcode Version 2.01, the stack frame is intact.

    dhookrb       = Pointer to dispatch hook resource
                    block
    exit_flag     = Type of return to make to Realtime
                    Control Microcode 2.01
    0x0000 Normal = NORMOFF/NORMSEG (monitor and
                    process type hooks)
    0x0001 Quick  = QUICKQUICKOFF/QUICKSEG (replace
                    type hooks)
    
    This routine cannot be shared by more than one task.

    Returns:

    This routine does not return a function value.

    Example:

    #Include "icadeclt.h"
    
    #define normexit 0x0;
    struct hookrbstruct dhookrb;
    
    dhook_exit (normexit, &dhookrb;);
    
    Related Topics:
         dhook_ntry, hookntry, hookexit
    

    dhook_ntry

    Purpose:

    Saves the machine environment when using the dispatch extended service hook. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    struct dhookenv far *ICAENTRY dhook_ntry (void);
    
    Remarks:

    If this call is used in an interrupt handler, it must be the first instruction in the interrupt handler. This function is used for dispatch extended service hooks to save the environment of the interrupted task. It returns a pointer to the saved registers on the stack. These registers may be referenced with the dhookenv structure.

    This routine cannot be shared by more than one task.

    Returns:

    Function value = Pointer to saved registers on stack.

    Example:

    #Include "icadeclt.h"
    
    struct dhookenv far *hookenv;
    hookenv = dhook_ntry();
    
    Related Topics:
         dhook_exit, hookexit, hookntry
    

    dispreempt

    Purpose:

    Disables preemption for completion of a critical path.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY dispreempt(void);
    
    Remarks:

    The dispreempt function disables the preempt capability of the posti function. If tasks of a higher priority are posted while preemption is disabled, a flag is set so that when preemption is enabled, the higher priority task can be given immediate control. Preemption may not be enabled or disabled from an interrupt handler.

    This routine performs the same function as the Disable Preempt SVI.

    Returns:

    Function value = 0x0000 = Normal completion; no errors 0x0005 = Access denied (when called from an interrupt handler)

    Example:

    #Include "icadeclt.h"
    
    int error_code;
    
    error_code = dispreempt();
    
    Related Topics:
         enpreempt
    

    dmaconec

    Purpose:

    Connects an 80186 direct memory access (DMA) channel to any of the four serial communications controller (SCC) DMA request outputs. This function is not supported in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY dmaconec(channel,connection,new_dma,
                           old_dma);
    unsigned char channel;
    unsigned char connection;
    unsigned char *new_dma;
    unsigned char *old_dma;
    
    Remarks:

    The dmaconec function connects a DMA channel to any of the four SCC DMA outputs. This routine provides the facility to connect either DMA channel without disturbing the other channel, or to connect both channels with a single call. No checking is done; it is the caller's responsibility to ensure the integrity of the hardware and software systems when using this routine (ownership of resources, correctness of channel selection, target DMA channel(s) stopped, etc.). This routine should not be used with Realtime Control Microcode Version 2.01, because 80186 DMA channels cannot be connected to the communication ports.

    The channel parameter has three valid values:

            0x00 = Only connect DMA channel 0
            0x01 = Only connect DMA channel 1
            0xFF = Connect both DMA channels
    
    The bottom four bits of the connection parameter (xxxx aabb) are used to choose the type of DMA connection. To connect only one channel without disturbing the other, bb is used and aa is ignored. To connect both channels at the same time, bb is used for channel 0 and aa is used for channel 1.

    The following bit codes are used for aa and bb:

            00 = connect SCC port A transmit to DMA
                 request
            01 = connect SCC port A receive to DMA
                 request
            10 = connect SCC port B transmit to DMA
                 request
            11 = connect SCC port B receive to DMA
                 request
    
    The parameters new_dma and old_dma are returned by dmaconec. The parameter new_dma returns the new value of the DMA allocation register with the bit pattern "aabb 0000," where aa is the channel-1 setting and bb is the channel-0 setting. The parameter old_dma returns the old value of the DMA allocation register with the same bit pattern "aabb 0000" where aa is the channel-1 setting and bb is the channel-0 setting. The bit codes returned in new_dma and old_dma have the same meaning as the codes in the connection parameter.

    This routine performs the same function as PROM Services interrupt 0xAA.

    Returns:

    If used with Realtime Control Microcode Version 2.01, this routine returns a value of 0x0001.

    Example:

    #Include "icadeclt.h"
    
    unsigned char newdma, olddma;
    unsigned int error;
    
                          /* Connect DMA channel */
                          /* 0 to SCC port A     */
                          /* receive             */
    
    error = dmaconec(0x00, 0x01, &newdma;, &olddma;);
    
    Related Topics:
         dmareg, dmastart, dmastop, dmaxlate, svcalloc
    

    dmareg

    Purpose:

    Reads six words from a 12-byte table and writes them to the specified direct memory access (DMA) channel registers, or reads the DMA channel registers and writes them to a 12-byte table.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY dmareg(port,rw,table_ptr);
    unsigned int port;
    unsigned char rw;
    unsigned int *table_ptr;
    
    Remarks:

    The dmareg function reads or writes the DMA channel registers. If writing the registers, the table must contain precisely the correct data for the DMA, as specified in the Intel manuals; no validity checking is done. (Source and destination must be physical memory and/or I/O addresses.) The 12-byte table should have the following format:

    Offset     Contents
    ======================================================
      0        Source low-order 16 bits of 20-bit
               physical address
     +2        Source high-order 4 bits of 20-bit
               physical address
     +4        Destination low-order 16 bits of
               20-bit physical address
     +6        Destination high-order 4 bits of
               20-bit physical address
     +8        Byte or word count (depends on
               control word value)
     +10       DMA control word
    
    If the rw parameter is less than 0x80, then the DMA registers are written. If it is greater than or equal to 0x80, then the DMA registers are read. The port parameter should contain the DMA base address returned in the DMAADDR field of the DMA request block by the svcalloc function.

    A DMA should be allocated with the svcalloc function before it is used. This routine performs the same function as PROM Services interrupt 0xAE.

    Returns:

    If a read is selected, the data in the table read is selected; otherwise, the routine does not return a function value.

    Example:

    #Include "icadeclt.h"
    
    unsigned char dma_table[12];
    unsigned int dma_port_address;
    
    
    dmareg(dma_port_address,0x00,&dma;_table);
                       /* Read the DMA registers */
    
    Related Topics:
         dmaconec, dmastart, dmastop, dmaxlate, svcalloc
    

    dmastart

    Purpose:

    Sets up and starts a direct memory access (DMA) channel.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY dmastart(request,control,
                   port_addr,channel_addr,table_ptr);
    unsigned char request;
    unsigned int control;
    unsigned int port_addr;
    unsigned int channel_addr;
    unsigned int *table_addr;
    
    Remarks:

    The dmastart function sets up and starts one DMA channel. This function is intended to simplify the most common setups of the 80186 DMA channels. The user provides I/O addresses, the DMA control word, memory addresses, and transfer counts. This routine optionally converts memory addresses from segment:offset format to the physical address format that the DMA requires. The selected DMA channel is configured by writing the control word last so that the DMA operation may be immediately started without a separate call. I/O-to-memory (receive), memory-to-I/O (transmit), and memory-to-memory DMA types are supported; I/O-to-I/O is not. No checking of input data is done. This routine is designed to be called by preparatory setup and checking routines.

    The control parameter should contain the DMA control word. The port_addr parameter should contain the port address for either the source or destination (not needed for memory-to-memory options). The channel_addr parameter should contain the I/O port address for the selected DMA channel. The request parameter is bit-sensitive and determines the type of operation and the format of the table pointed to by table_ptr. The following request bit codes and table formats are accepted:

    
    I/O-to-Memory (segment:offset)
         request = 001x xxxx
         table = +------------------------+
                 | Destination offset     |
                 | Destination segment    |
                 | Maximum transfer       |
                 +------------------------+
    
    
    
    Memory-to-I/O (segment:offset)
         request = 010x xxxx
         table = +------------------------+
                 | Source offset          |
                 | Source segment         |
                 | Transmit transfer count|
                 +------------------------+
    
    
    Memory-to-Memory (segment:offset)
         request = 011x xxxx
         table = +------------------------+
                 | Source offset          |
                 | Source segment         |
                 | Destination offset     |
                 | Destination segment    |
                 | Transfer count         |
                 +------------------------+
    
    
    I/O-to-Memory (physical address)
         request = 101x xxxx
         table = +------------------------+
                 | Physical destination   |
                 |  address (low 16 bits) |
                 | Physical destination   |
                 |  address (high 4 bits) |
                 | Maximum transfer count |
                 +------------------------+
    
    
    Memory-to-I/O (physical address)
         request = 110x xxxx
         table = +-------------------------+
                 | Physical source address |
                 |  (low 16 bits)          |
                 | Physical source address |
                 |  (high 4 bits)          |
                 | Transmit byte count     |
                 +-------------------------+
    
    
    Memory-to-Memory (physical address)
         request = 111x xxxx
         table = +-------------------------+
                 | Physical source address |
                 |  (low 16 bits)          |
                 | Physical source address |
                 |  (high 4 bits)          |
                 | Physical destination    |
                 |  address (low 16 bits)  |
                 | Physical destination    |
                 |  address (high 4 bits)  |
                 | Transfer count          |
                 +-------------------------+
    
    This routine performs the same function as PROM Services interrupt 0xAC. The svcalloc function should be used to allocate a DMA before it is used.

    Returns:

    Function value =
            0x0000 = Normal operation; no errors
            0x0001 = Request rejected because of invalid
                     parameters
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    char far *mem_addr;/* Source address for DMA transfer */
    unsigned int dma_channel, io_port;
    unsigned int dma_control_word;
    unsigned int dma_table[3];
    
       /* Set up table for I/O-to-memory transfer of 1000 */
       /* bytes. Source address has segment:offset format */
    dma_table[0] = (unsigned int) FP_OFF(mem_addr);
    dma_table[1] = (unsigned int) FP_SEG(mem_addr);
    dma_table[2] = (unsigned int) 1000;
    
                 /* Set up DMA for I/O-to-memory transfer */
    error_code = dmastart(0x20, dma_control_word,
                    io_port, dma_channel, dma_table);
    
    Related Topics:
         dmaconec, dmareg, dmastop, dmaxlate, svcalloc
    

    dmastop

    Purpose:

    Stops a DMA channel.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY dmastop(dma_port);
    unsigned int dma_port;
    
    Remarks:

    The dmastop function immediately stops a DMA channel regardless of the operation in progress, and returns the byte count register as the function return value. The byte count is read after a short settling delay; no checking is done. The dma_port parameter should contain the DMA port address of the channel to stop.

    This routine performs the same function as PROM Services interrupt 0xB0.

    Returns:

    This routine does not return an error code.

    Function value = Residual byte count.

    Example:

    #Include "icadeclt.h"
    
    unsigned int ICAENTRY dma_port_address;
    unsigned int byte_count;
    
    byte_count = dmastop(dma_port_address);
    
    Related Topics:
         dmaconec, dmareg, dmastart, dmaxlate, svcalloc
    

    dmaxlate

    Purpose:

    Converts a segment:offset address to the physical address format used by the 80186 DMA.

    Format:

    #Include "icadeclt.h"
    
    unsigned long ICAENTRY dmaxlate(segaddr);
    char far **segaddr;
    
    Remarks:

    The dmaxlate function reads a 4-byte logical segment:offset address from memory, translates it to the physical address form that is required by the 80186 DMA device, and writes the result back into the same memory locations (overwriting the input).

    This routine performs the same function as PROM Services interrupt 0xB2. This routine does not return an error code.

    Returns:

    Function value = A 20-bit address contained in a 32-bit field.

    Example:

    #Include "icadeclt.h"
    
    char text_buffer[100];
    char far *buffer_ptr;
    unsigned long buffer_phys_addr;
    
                 /* Get address of buffer, and   */
                 /*  convert to physical address */
    buffer_ptr = text_buffer;
    buffer_phys_addr = dmaxlate(&buffer;_ptr);
    
    Related Topics:
         dmaconec, dmareg, dmastart, dmastop, svcalloc
    

    emm2page

    Purpose:

    Converts EMM handle, logical page number, and offset to a page and offset. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY emm2page (emmhandle, logpgnum,
                           pgoffset, physpage, physoff)
    unsigned int emmhandle, logpgnum, pgoffset;
    unsigned int *physpage;
    unsigned int *physoff;
    
    Remarks:

    The page and offset is used by the system unit to view physical memory.

    emmhandle = EMM handle
    logpgnum  = logical page number
    pgoffset  = offset in logical page
    
    Returns:
    physpage
    physoff
    Function value =
            0x0000 = No error
            0x0001 = Invalid entry parameter
            0x0005 = Access denied (expanded memory
                     not present)
            0x000E = Unknown EMM handle
            0x000F = Logical page number out of range
            0x0012 = Address out of range (offset
                     greater than 64KB)
    
    Example:
    #Include "icadeclt.h"
    
    struct emmrbstruct EMM;
    unsigned int physpage;
    unsigned int physoff;
    
    emm2page(emm.emmhandle, 1, 0, &physpg;, &physoff;);
            /* Convert EMM handle, logical page    */
            /* number 1; offset 0 to a page:offset */
            /* address                             */
    
    Related Topics:
         emm2phys
    

    emm2phys

    Purpose:

    Converts an EMM handle, logical page number, and offset to a 32-bit physical address. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY emm2phys (emmhandle, logpgnum,
                           pgoffset, physaddr)
    int emmhandle,logpgnum,pgoffset;
    unsigned long *physaddr;
    
    Remarks:

    The system unit uses the page offset address to view physical memory. The physical page number is the page in 80186 addressable memory where the expanded memory page is to be mapped. The physical page numbers range from 0 through the number of pages in the page frame minus 1.

    The logical page number contains the number of the page to be mapped to the physical page frame. Logical pages are numbered 0 relative and must be in the range 0 through the number of pages allocated to the EMM handle minus 1. If a logical page number of minus 1 is specified, the physical page number specified in pgoffset is unmapped and made inaccessible for reading or writing.

    emmhandle = EMM handle
    logpgnum  = logical page number
    pgoffset  = offset within logical page
    
    Returns:
    physaddr       = 32-bit physical address
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0005 = Access denied (expanded memory
                     not present)
            0x000E = Unknown EMM handle
            0x000F = Logical page number out of
                     range
            0x0012 = Address out of range
            0x0013 = Invalid data (offset greater
                     than 16KB)
    
    Example:
    #Include "icadeclt.h"
    
    struct emmrbstruct EMM;
    unsigned long physaddr;
    
    emm2phys(emm.emmhandle, 2, 0, &physaddr;);
      /* Convert EMM handle, logical page number  */
      /* 2; offset 0 to a 32-bit physical address.*/
    
    Related Topics:
         emm2page, map_emm, map_physpg
    

    enpreempt

    Purpose:

    Enables preemption at completion of a critical path.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY enpreempt(void);
    
    Remarks:

    The enpreempt function enables the preempt capability of the POSTI function. If a higher priority task was posted while preemption was disabled, that task is given control. Preemption may not be enabled or disabled from an interrupt handler.

    This routine performs the same function as the Enable Preempt SVI.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (when called from
                     an interrupt handler)
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
    error_code = enpreempt();
    
    Related Topics:
         dispreempt
    

    estat_r

    Purpose:

    Reads the contents of the task's extended status buffer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY estat_r(target,count);
    char *target;
    unsigned int count;
    
    Remarks: The estat_r function reads the contents of the task's extended status buffer. The target parameter should be a pointer to a target buffer where the status buffer bytes are written. The count parameter is the number of bytes to read. If the byte count is larger than the length of the status buffer, the entire status buffer is returned and an error is indicated. The actual number of bytes transferred can be found by using the bcb_st_r function to get the length of the buffer. It is assumed that the target area is large enough to receive the data.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0013 = Byte count greater than the
                     size of the status buffer
    
    Example:
    #Include "icadeclt.h"
    
    char temp_buffer[20];
    int error_code;
    
    error_code = estat_r(temp_buffer,20);
              /* Read 20 bytes of status buffer */
              /* into temporary buffer          */
    
    Related Topics:
           bcb_st_r, estat_w
    

    estat_w

    Purpose:

    Writes the task's extended status buffer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY estat_w(source,count);
    char *source;
    unsigned int count;
    
    Remarks:

    The estat_w function writes count bytes from the buffer referenced by the source parameter to the task's extended status buffer. If the count parameter is greater than the length of the buffer, nothing is written and an error code is returned. The length of the extended status buffer can be found by using the bcb_st_r function.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0013 = Count value is larger than the
                     length of the extended status
                     buffer
    
    Example:
    #Include "icadeclt.h"
    
    char temp_buffer[20] = "New status bytes";
    int error_code;
    
    error_code = estat_w(temp_buffer,20);
                           /* Write 20 bytes to */
                           /* the status buffer */
    
    Related Topics:
         bcb_st_r, estat_r
    

    etoa

    Purpose:

    Converts an EBCDIC character array to an ASCII string.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY etoa(source_ptr,destn_ptr,
                               length);
    unsigned char *source_ptr;
    unsigned char *destn_ptr;
    unsigned int length;
    
    Remarks:

    The etoa function takes as input an EBCDIC character array pointed to by source_ptr and converts length bytes to ASCII. It stores the converted characters in the area pointed to by destn_ptr. This performs the same function as PROM Services interrupt 0xC2.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0001 = Request rejected due to 0-byte
                     count
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char ebcdic_buf[100];
    unsigned char ascii_buf[100];
    int error_code;
    
    error_code = etoa(ebcdic_buf,ascii_buf,100);
    
    Related Topics:
         atoe, convtptr
    

    extstcl

    Purpose:

    Clears external/status interrupts for a port. This routine does not enable interrupts.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY extstcl (port,status);
    unsigned char port;
    unsigned char *status;
    
    Remarks:

    For the Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport, and Realtime Interface Co-Processor Multiport/2 adapters, the extstcl function clears a pending external/status interrupt and returns the values of the external/status control inputs (DCD, zero count, transmit underrun, break/abort, CTS, RI, and DSR) for the specified port. This includes issuing an EOI to the SCC and/or CIO, as required, clearing IP and IUS on the CIO, as required, and issuing a reset external/status to the SCC port. This routine should be used only for SCC/CIO packages, communication port packages, RS-232 ports, or RS-422 ports. It is the responsibility of the application to verify that the installed EIB is appropriate for the service requested.

    For the Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2, this SVI does not issue a nonspecific EOI to the 80186 processor or &pdma.; this must be done by the user. The zero count, transmit underrun, and break/abort bits (1, 6, and 7) are reserved and 0's are returned. If half rate select (HRS) is defined as an input signal, the value is returned in bit 2. This SVI should be used only with communication port packages.

    The format of the status parameter is abcdefgh, where the bits have the following meanings:

    Zilog:                       Signetics:
    ========================================================
    a=value of break/abort       a=reserved
    b=value of transmit          b=reserved
      underrun
    c=value of CTS               c=value of CTS
      RS-232 only)                 RS-232 only)
    d=value of DSR               d=value of DSR
      RS-232 only)                 RS-232 only)
    e=value of DCD               e=value of DCD
      RS-232 only)                 RS-232 only)
    f=value of HRS               f=value of HRS
      input signal                 input signal
    g=value of zero count        g=reserved
    h=value of ring indicate     h=value of Ring Indicate
      RS-232 only)                 RS-232 only)
    
    This routine performs the same function as Clear External/Status Interrupts SVI for Realtime Control Microcode.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (function not
                     supported on port)
            0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char status;
    
    error_code = extstcl(3, &status;);
                      /* Clear port 3 external */
                      /* status interrupts     */
    
    Related Topics:
         extstco, extstqu
    

    extstco

    Purpose:

    Enables or disables the external/status interrupt inputs for a port.

    This routine does not enable interrupts.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY extstco (port,select,request);
    unsigned char port;
    unsigned char select;
    unsigned char request;
    
    Remarks:

    For the Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport, and Realtime Interface Co-Processor Multiport/2 adapters, the extstco function enables or disables the external/status interrupt inputs (DCD, zero count, transmit underrun, break/abort, CTS, RI and DSR) for the specified port. Multiple inputs may be affected by one call.

    The select parameter indicates which inputs are to be affected by the call; all others are left in their previous states. Enabling and disabling of different inputs may be done by the same call. The request value indicates the request to enable or disable the input for each affected input.

    This routine should be used only for SCC/CIO packages, communication port packages, RS-232 ports, or RS-422 ports. It is the responsibility of the application to verify that the installed EIB is appropriate for the service requested.

    The format of the select parameter is abcdefgh where the bits have the following meanings:

    Zilog SCC:                   Signetics DUSCC:
    ============================================================
    a=value of break/abort       a=reserved
    b=value of transmit          b=reserved
      underrun
    c=value of CTS               c=value of CTS
      RS-232 only)                 RS-232 only)
    d=value of DSR               d=value of DSR
      RS-232 only)                 RS-232 only)
    e=value of DCD               e=value of DCD
      RS-232 only)                 RS-232 only)
    f=value of HRS               f=value of HRS
      input signal                 input signal
    g=value of zero count        g=reserved
    h=value of ring indicate     h=value of Ring Indicate
      RS-232 only)                 RS-232 only)
    
    A bit value of 1 indicates that input is selected for alteration; a bit value of 0 indicates that input is not to be affected by this routine. The format of the request parameter is identical to that of the select, with each bit value being the enable or disable of that input interrupt (1 = enable; 0 = disable).

    For the Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2, this SVI does not issue a nonspecific EOI to the 80186 processor or DMA/Peripheral Interface Communications Controller, the zero count, transmit underrun, and break/abort bits (1, 6, and 7) are reserved and 0's are returned. If half rate select (HRS) is defined as an input signal, the value is returned in bit 2. The DCD and CTS signals share an interrupt enable bit. They are either enabled or disabled together. If the bits for DCD and CTS are set differently, DCD gets precedence over CTS and the bits are enabled or disabled according to the DCD bits in the select parameter. This SVI should be used only with communication port packages.

    This routine performs the same function as External/Status Interrupt Control SVI for Realtime Control Microcode.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (function not
                     supported on port)
            0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char select;
    unsigned char request;
    
      /* Affect all external/status input interrupts    */
      /* for port 0. Enable CTS, DSR, and RI interrupts */
      /* and disable all others.                        */
    error_code = extstco(0, 0x00FB, 0x0031);
    
    Related Topics:
         extstcl, extstqu
    

    extstqu

    Purpose:

    Queries the value of the external/status inputs for a port.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY extstqu (port,status);
    unsigned char port;
    unsigned char *status;
    
    Remarks:

    For the Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport, and Realtime Interface Co-Processor Multiport/2 adapters, the extstqu function returns the values of the external/status control inputs (DCD, zero count, transmit underrun, break/abort, CTS, RI and DSR) for the specified port. This routine should be used only for SCC/CIO packages, communication port packages, RS-232 ports, or RS-422 ports. It is the responsibility of the application to verify that the installed EIB is appropriate for the service requested. This routine does not enable interrupts.

    For the Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2, the zero count, transmit underrun, and break/abort bits (1, 6, and 7) are reserved and 0's are returned. If half rate select (HRS) is defined as an input signal, the value is returned in bit 2. This SVI should be used only with communication port packages.

    The format of the status parameter is abcdefgh where the bits have the following meanings:

    Zilog SCC:                   Signetics DUSCC:
    ============================================================
    a=value of break/abort       a=reserved
    b=value of transmit          b=reserved
      underrun
    c=value of CTS               c=value of CTS
      RS-232 only)                 RS-232 only)
    d=value of DSR               d=value of DSR
      RS-232 only)                 RS-232 only)
    e=value of DCD               e=value of DCD
      RS-232 only)                 RS-232 only)
    f=value of HRS               f=value of HRS
      input signal                 input signal
    g=value of Zero Count        g=reserved
    h=value of Ring Indicate     h=value of Ring Indicate
      RS-232 only)                 RS-232 only)
    
    This routine performs the same function as Query External/Status Inputs SVI for Realtime Control Microcode.

    Returns:

    Function value =
      0x0000 = Normal completion; no errors
      0x0005 = Access denied (function not
               supported)
      0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char status;
    
    error_code = extstqu(3, &status;);
                     /* Request query of port 3 */
                     /* external/status inputs  */
    
    Related Topics:
         extstco, extstcl
    

    ftime

    Purpose:

    Gets the current time and stores it. This function is supported only in Realtime Control Microcode 2.01.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY ftime (timeptr);
    struct timeb far *timeptr;
    
    Remarks:

    This routine is identical to the C ftime and time library routines, except that the time is read from the co-processor adapter rather than the system unit.

    timeptr = pointer to time structure
    
    Returns:

    This routine does not return a function value.

    Example:

    #Include <-mt-sys-types.h>
    
    #include <-mt-sys-timeb.h>
    
    struct timeb timebuffer;
    
    ftime(&timebuffer;);   /* Get number of seconds  */
                          /* since 01/01/1970.      */
    ctime(&(timebuffer.time));   /* Convert seconds */
                                 /* to current time.*/
    
    Related Topics;
         time and set_time
    

    get_baseid

    Purpose:

    Returns unique values for the co-processor adapters.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY get_baseid (void);
    
    Returns:

    This routine does not return an error code.

    Function value =
      0x0080 = Realtime Interface Co-Processor
               Portmaster Adapter/A
      0x0000 = Realtime Interface Co-Processor
               Multiport Adapter, Model 2
      0x0100 = Realtime Interface Co-Processor
               Adapter
      0x0130 = Realtime Interface Co-Processor
               Adapter Multiport
      0x01C0 = Realtime Interface Co-Processor
               Multiport/2 and X.25 Interface
               Co-Processor/2
    
    Example:
    #Include icadeclt.h
    
    unsigned int baseid;
    baseid = get_baseid();
    
    Related Topics:
         None
    

    get_call_addr

    Purpose:

    Returns a pointer to a structure containing the addresses of selected routines. This routine is available only in Realtime Control Microcode 2.01.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY get_call_addr(addrstruct);
    struct call_addr_struct far **addrstruct;
    
    Remarks:

    See the "Callable Address Structure" (call_addr_struct) in Chapter 2 for those routines whose addresses are returned by this routine. These routines may be called by applications to extend Realtime Control Microcode Version 2.01 services.

    This routine does not enable interrupts.

    Returns:

    ADDRSTRUCT     = Pointer to a structure that
                     contains addresses of selected
                     Realtime Control Microcode 2.01
                     routines
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
                     (AH is out of range)
    
    Example:
    #Include icadeclt.h
    
    struct call_addr_struct far *calladdress;
    
    get_call_address(&calladdress;);
    
    Related Topics:
         None
    

    getextid

    Purpose:

    Gets the identifier of the extended electrical interface board (EIB).

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY getextid (void);
    
    Remarks:

    The getextid function performs the same service as Diagnostic Test Module FEh (AH = 0Eh).

    Returns:

    Extended EIB identifier.

    Function value =
      0x0010 = Realtime Interface Co-Processor
                 Portmaster Adapter/A or
               Realtime Interface Co-Processor
                 Multiport Adapter, Model 2,
               for RS-232
      0x0021 = Realtime Interface Co-Processor
                 Portmaster Adapter/A or
               Realtime Interface Co-Processor
                 Multiport Adapter, Model 2,
               for RS-422
      0x00BE = Realtime Interface Co-Processor
                 Multiport/2
               for 8-port RS-422
      0x00BF = Realtime Interface Co-Processor
                 Portmaster Adapter/A or
               Realtime Interface Co-Processor
                 Multiport Adapter, Model 2,
               for 4-port RS-232/4-port RS-422
               selectable
      0x00C1 = Realtime Interface Co-Processor Adapter,
               for RS-232 (1-port)
      0x00C2 = Realtime Interface Co-Processor Adapter,
               for RS-422/X.21 (1-port)
      0x00C3 = 20 ma Current Loop (1-port)
      0x00C4 = V.35 (1-port)
      0x00C7 = Realtime Interface Co-Processor
                 Multiport or
               Realtime Interface Co-Processor
                 Multiport/2,
               for 4- or 8-port RS-232
      0x00C8 = Realtime Interface Co-Processor
                 Multiport or
               Realtime Interface Co-Processor
                 Multiport/2,
               for 4-port RS-232/4-port RS-422
    
      0x00C9 = X.25 Interface Co-Processor/2
      0x00CF = Realtime Interface Co-Processor
                 Multiport/2,
               for 6-port (sync) RS-232
      0x00FF = No EIB attached
    
    Example:
    #Include icadeclt.h
    
    unsigned int extid;
    extid = getextid();
    
    Related Topics:
         None
    

    get_int_cnt

    Purpose:

    Returns the current depth of hardware interrupts. This routine is available only in Realtime Control Microcode Version 2.01.

    This routine does not enable interrupts.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY get_int_cnt(void);
    
    Returns:

    Current depth of interrupts.

    Function value = depth of hardware interrupts
                     (0 = none).
    
    Example:
    #Include icadeclt.h
    
    unsigned int intdepth;
    
    intdepth = get_int_cnt(void);
                     /* Get depth of hardware */
                     /* interrupts            */
    
    Related Topics:
         None
    

    get_next_avail

    Purpose:

    Accepts as input a hardware or software resource type and returns the next available unused number for the given hardware or software resource. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY get_next_avail(restype,resnum);
    unsigned char restype;
    unsigned char *resnum;
    
    Remarks:
    restype        =
            0x0000 = Hardware timer
            0x0001 = 80186 DMA channel
            0x0002 = User interrupt vector
            0x0003 = Software timer
            0x0004 = User queue
            0x0005 = Task number
    
    resnum         = Next available resource number
    
    This routine does not enable interrupts.

    Returns:

    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
                     (restype is out of range)
            0x000D = No resource available
                     (all resources of this
                     type are in use)
    
    Example:
    #Include icadeclt.h
    
    unsigned int rnumber;
    unsigned char resource;
    
    rnumber=get_next_avail(3, &resource;);
                 /* Get number of next available */
                 /* software timer               */
    
    Related Topics:
         None
    

    get_pgfrm

    Purpose:

    Returns the logical segment address and number of 16KB pages in the expanded memory page frame. This routine is available only in Realtime Control Microcode Version 2.01, and is valid only on a Portmaster Adapter/A with expanded memory.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY get_pgfrm (pgfrmsegadd, pages)
    unsigned char far **pgfrmsegadd;
    unsigned char *pages;
    
    Remarks:

    The get_pgfrm routine performs the same function as the Get Page Frame Segment Address SVI in Realtime Control Microcode Version 2.01.

    pgfrmsegadd = Page frame segment address
    pages       = Number of pages in frame if no error
    
    Returns:
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0005 = Access denied (expanded memory
                     not present)
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char far *pagefrmsegadd;
    unsigned char pages;
    unsigned int errorcode;
    
    errorcode = get_pgfrm(&pagefrmsegadd;, &pages;);
    
    Related Topics:
         None
    

    get_ptrs

    Purpose:

    Fills the supplied cbptr structure with pointers to the interface block, the task's TCB, the task's BCB, and the task's header.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY get_ptrs(sptr);
    struct cbptr *sptr;
    
    Remarks:

    The get_ptrs function takes the pointer sptr to a cbptr structure and fills in the structure fields. The first field in the structure is the pointer to the interface block, which is a general control block maintained by the Realtime Control Microcode. The ibstruct structure defines the fields of the interface block. The second field of the structure is a pointer to the task's TCB. The TCB fields are described by the tcbstruct structure declaration. The third field of the structure is a pointer to the task's BCB; the BCB fields are described by the bcbstruct structure declaration. The fourth, and last, field of the structure is a pointer to the task's header; the task header fields are described by the thstruct structure declaration.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    struct cbptr control_blocks;
    
    get_ptrs(&control;_blocks);
                /* Change the task's ID field in */
                /* the task header to 0xF00D     */
    
    control_blocks.THEADPTR->TSKID = 0xF00D;
    
    Related Topics:
         None
    

    get_res_cnt

    Purpose:

    Returns a pointer to a structure containing a list of hardware and software resources. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY get_res_cnt(cntstruct);
    struct res_cnt_struct far **cntstruct);
    
    Remarks:

    Each list item contains a count specifying the maximum number of that type that can be allocated.

    This routine does not enable interrupts.

    Returns:

    CNTSTRUCT      = 32-bit address of resource count
                     structure
    Function value = None
    
    Example:
    #Include "icadeclt.h"
    
    struct res_cnt_struct far *rescount;
    
    get_res_cnt(&rescount;);
    
    Related Topics:
         None
    

    get_task

    Purpose:

    Returns the task number of the current task in execution. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    unsigned char ICAENTRY get_task (void);
    
    Remarks:

    The get_task routine performs the same functions as the Get Task in Execution SVI for Realtime Control Microcode Version 2.01.

    This routine does not enable interrupts.

    Returns:

    Task number in execution.

    Function value =
            0x0000 = No error
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char tasknum;
    tasknum = get_task();   /* Get task number in */
                            /* execution          */
    
    Related Topics:
         None
    

    halfrate

    Purpose:

    Enables or disables the half rate select (HRS).

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY halfrate(port,request);
    unsigned char port;
    unsigned char request;
    
    Remarks:

    The halfrate function enables or disables the half rate select of the specified port. On Multiport/2 EIBs, half rate select is only a feature of ports 0 and 1. On Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2 EIBs, this signal can be either an input, output, or both, as determined by the EIB ROM. This routine should be used only for SCC/CIO packages, communication port packages, RS-232 ports, or RS-422 ports. It is the responsibility of the application to verify that the installed interface board is appropriate for the service requested.

    The halfrate select function is not available on the IBM X.25 Interface Co-Processor/2.

    This routine assumes that the initial allocation state of the CIO is preserved.

    The format of the request parameter is as follows:

            0x0000 = Disable
            0x0001 = Enable
    
    This performs the same function as the half rate select SVI.

    Returns:

    Function value =
            0x0000 = Normal completion, no error
            0x0005 = Access denied (HRS not an output
                     on port)
            0x0018 = Invalid port number
    

    Example:

    #Include "icadeclt.h"
    
    int error_code;
    
    error_code = halfrate (0, 0x0001);
                     /* Request enable of port 0 */
                     /* half rate select         */
    
    Related Topics:
         None
    

    hook_exit

    Purpose:

    Restores the machine environment after an application uses a non-dispatch extended service hook. This routine is only available in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY hook_exit (hookrb, exit_flag)
    unsigned int exit_flag;
    struct hookrbstruct *hookrb;
    
    Remarks:

    The user application must ensure that upon return to Realtime Control Microcode Version 2.01, the stack frame is intact.

    hookrb        = Pointer to non-dispatch hook
                    resource block
    exit_flag     = Type of return to make to Realtime
                    Control Microcode 2.01
    0x0000 Normal = NORMOFF/NORMSEG (monitor and
                    process type hooks)
    0x0001 Quick  = QUICKOFF/QUICKSEG (replace type
                    hooks)
    
    This routine cannot be shared by more than one task.

    Returns:

    This routine does not return a function value.

    Example:

    #Include "icadeclt.h"
    
    struct hookrbstruct hookrbs;
    
    hook_exit(0, &hookrbs;);
                   /* Normal exit to next hook */
                   /* element in chain         */
    
    Related Topics:
         dhook_exit, dhook_ntry, hook_ntry
    

    hook_ntry

    Purpose:

    Saves the machine environment prior to using a non-dispatch extended service hook.

    Format:

    #Include "icadeclt.h"
    
    struct hookenv far * ICAENTRY hook_ntry (void);
    
    Remarks:

    If this function is used in an interrupt handler, it must be the first instruction in the interrupt handler. This function is used for non-dispatch extended service hooks to save the environment of the interrupted task. It returns a pointer to the saved registers on the stack. These registers may be referenced with the hookparms structure.

    This routine cannot be shared by more than one task.

    Returns:

    Function value = Pointer to saved registers on stack.

    Example:

    #Include "icadeclt.h"
    
    struct hookenv far *hookenv;
    
    hookenv = hook_ntry();
    
    Related Topics:
         dhook_exit, dhook_ntry, hook_exit
    

    inbuf_r

    Purpose:

    Reads the task's input buffer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY inbuf_r(target,count);
    char *target;
    unsigned int count;
    
    Remarks:

    The inbuf_r function reads count bytes of the task's input buffer and stores them in the area pointed to by the target parameter. If the count parameter is greater than the length of the task's input buffer, the entire input buffer is read and an error code is returned. The actual number of bytes transferred can be found by using the bcb_ib_r function. It is assumed that the target area is large enough to receive the data.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0013 = Byte count greater than the size
                     of the input buffer
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    char read_input[20];
    
    error_code = inbuf_r(read_input,20);
    
    Related Topics:
         bcb_ib_r, inbuf_w
    

    inbuf_w

    Purpose:

    Writes to the task's input buffer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY inbuf_w(source,count);
    char *source;
    unsigned int count;
    
    Remarks:

    The inbuf_w function writes count bytes to the task's input buffer from the area pointed to by source. If the count parameter is greater than the length of the input buffer, nothing is written and an error is returned. If the count parameter is 0, the length of the input buffer (read from the task's BCB) is used as the transfer count; use the bcb_ib_r function to find the length of the input buffer.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0013 = Count value is larger than the
                     input buffer
    
    Example:
    #Include "icadeclt.h"
    
    char tempbuf[24] = "Initialization Complete";
               /* String to pass back to system */
               /*  unit application.            */
    int e;     /* "inbuf_w" error code          */
    
    e = inbuf_w(tempbuf,24);
               /* Copy "tempbuf" to input buffer*/
    
    Related Topics:
         bcb_ib_r, estat_w, inbuf_r, outbuf_w
    

    initpri

    Purpose:

    Sets the task's priority.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY initpri(priority);
    unsigned char priority;
    
    Remarks:

    The initpri function sets the task's priority. The task's priority defaults to 5 in the supplied task header icaheadc.obj. The task should only call initpri during initialization before it calls the svcinitc function. The change in task priority occurs immediately.

    The other method of modifying the task's priority is to change the header module icaheadc.obj. Change the priority field in the task header in icaheadc.asm to the desired value, re-assemble icaheadc.asm with the /S option, and link the new icaheadc.obj module to the compiled task code. No call to initpri is necessary by this method; the task has the correct priority at startup.

    Returns:

    Function value =
            0x0000 = No errors
            0x0013 = Priority is out of the range
                     of 0 to MAXPRI
    
    Example:
    #Include "icadeclt.h"
    
    int e;
    unsigned char newpri = 2;
    
    e = initpri(newpri); /* Change priority from */
                         /* 5 to 2               */
    
    Related Topics:
         None
    

    int_exit

    Purpose:

    Returns from an I/O or timer interrupt handler.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY int_exit(void);
    
    Remarks:

    The int_exit function restores the machine environment at the end of an I/O timer interrupt handler. This function is also used for command interrupts if the supplied command handler icacmdh is replaced.

    This routine cannot be shared by more than one task.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    int timer_counter;
    
    void far timer_handler ()
    {
     int_ntry();     /* Save machine environment   */
    
     timer_counter++;/* Increment counter          */
    
     int_exit();     /* Restore machine environment*/
    }
    
    Related Topics:
         int_ntry, svcalloc
    

    int_ntry

    Purpose:

    Saves the machine environment in an interrupt handler.

    Format:

    #Include "icadeclt.h"
    
    struct intenv far * ICAENTRY int_ntry(void);
    
    Remarks:

    If this function is used in an interrupt handler, it must be the first statement in the interrupt handler. This function is used in I/O, timer and software interrupt handlers to save the environment of the interrupted task. This function is also used for command interrupt handlers if the supplied command handler icacmdh is replaced. This function must be called before sfw_chn in software interrupt handlers.

    The int_ntry function saves all the registers on the stack. It then sets up the DS register to the DGROUP segment, which is the segment of the task header. This allows all the task's global variables to be accessed.

    This routine cannot be shared by more than one task.

    Returns:

    A pointer to the saved registers on the stack is returned as the function value.

    Example:

    #Include "icadeclt.h"
    
    int i_o_counter;
    
    void far i_o_timer ()  /* I/O handler counts  */
                           /* interrupts          */
    {
            int_ntry();    /* Save environment    */
            i_o_counter++; /* Increment counter   */
            int_exit();    /* Restore environment */
    }
    
    Related Topics:
         int_exit, sfw_chn
    

    map_emm

    Purpose:

    Maps or unmaps logical expanded memory pages to a page frame page. This routine is available only in Realtime Control Microcode Version 2.01 on a Portmaster Adapter/A with expanded memory.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY map_emm (pageframe, logpage,
                         emmhandle, mappedseg)
    unsigned char pageframe;
    unsigned int logpage, emmhandle;
    unsigned char far **mappedseg;
    
    Remarks:

    The map_emm function supports the Realtime Interface Co-Processor Portmaster Adapter/A adapters only. The mapping of expanded memory pages is preserved across dispatch cycles. The physical page number is the page in 80186 addressable memory where the expanded memory page is to be mapped. The physical page numbers range from 0 through the number of pages in the page frame -1.

    The logical page number contains the number of the page to be mapped to the physical page frame. Logical pages begin at 0, and must be in the range 0 through the number of pages allocated to the EMM handle -1. If a logical page number of 0xFFFF is specified, the physical page number specified is unmapped and made inaccessible for reading or writing.

    pageframe = page frame page number
    logpage   = emmhandle logical page number
    emmhandle = EMM handle
    mappedseg = mapped segment
    
    Returns:
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0005 = Access denied
            0x000E = Unknown EMM handle
            0x000F = Logical page number out of
                     range
            0x0010 = Physical page number out of
                     range
    
    Example:
    #Include "icadeclt.h"
    
    struct emmrbstruct EMM;
    unsigned char far *mappedseg;
    
    map_emm(0, 1 emm.emmhandle, &mappedseg;);
             /* Map first logical page to page 0. */
    
    Related Topics:
         map_physpg
    

    map_physpg

    Purpose:

    Maps or unmaps physical expanded memory pages to a page frame page. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY map_physpg (pageframe, physaddr,
                             mappedmem)
    unsigned char pageframe;
    unsigned long physaddr;
    unsigned char far **mappedmem;
    
    Remarks:

    The mapping of expanded memory pages is preserved across dispatch cycles. The page frame page number is the page in 80186 addressable memory where the expanded memory page is to be mapped. The page frame page numbers range from 0 through the number of pages in the page frame minus 1.

    If a logical page number of minus 1 is specified, the page number specified is unmapped and made inaccessible for reading or writing.

    pageframe = physical page number
    physaddr  = 32-bit physical address to be mapped
    mappedmem = Segment:offset of mapped memory
    
    Returns:
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0005 = Access denied
            0x0010 = Physical page number out of
                     range
            0x0011 = Physical address mapped, but
                     unallocated
            0x0012 = Address out of range (window
                     size > 64KB)
            0x0013 = Invalid data (invalid 32-bit
                     address)
    
    Example:
    #Include "icadeclt.h"
    
    unsigned long physaddr;
    unsigned char far *mappedseg;
    
    map_physpg(1, physaddr, &mappedseg;);
          /* Map physaddr to first page.*/
    
    Related Topics:
         map_emm
    

    nseoi

    Purpose:

    Issues a non-specific end of interrupts (NSEOI) to the 80186 Programmable Interrupt Controller (PIC).

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY nseoi(void);
    
    Remarks:

    The nseoi must be issued to the PIC after each I/O interrupt. There must be only one nseoi issued per interrupt.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    void far i_o_handler()
    {
            int_ntry();
    
                     /* .... I/O handler code .... */
    
            nseoi();
            int_exit();
    }
    
    Related Topics:
         int_ntry, int_exit
    

    outbuf_r

    Purpose:

    Reads the contents of the task's output buffer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY outbuf_r(target,count);
    char *target;
    unsigned int count;
    
    Remarks:

    The outbuf_r function reads count bytes of the task's output buffer. If the count parameter is greater than the length of the output buffer, the whole buffer is read and an error is indicated in the return code. If the count parameter is equal to 0, the length of the output buffer is used as the count. The output buffer's length can be found by calling the bcb_ob_r function. It is assumed that the target area is large enough to receive the data.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0013 = Byte count greater than the size
                     of the output buffer
    
    Example:
    #Include "icadeclt.h"
    
    char tempbuf[100]; /* Copy output buffer here */
    int e ;            /* Error code              */
    
    e = outbuf_r(tempbuf,0);/* read entire buffer */
    
    Related Topics:
         bcb_ob_r, estat_r, inbuf_r, outbuf_w
    

    outbuf_w

    Purpose:

    Writes to the task's output buffer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY outbuf_w(source,count);
    char *source;
    unsigned int count;
    
    Remarks:

    The outbuf_w function writes count bytes of the source data to the task's output buffer. If the count parameter is greater than the length of the output buffer, no data is written and an error is indicated in the error code. If the count parameter is 0, the length of the output buffer is used as the count for writing data bytes; the length of the output buffer can be found with the bcb_ob_r function.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0013 = Count value is larger than the
                     output buffer length
    
    Example:
    #Include "icadeclt.h"
    
    int e;
    char tempbuf[20] = "Command complete.";
    
    e = outbuf_w(tempbuf,20);
                      /* Write character text to */
                      /* output buffer           */
    
    Related Topics:
         bcb_ob_r, estat_w, inbuf_w, outbuf_r
    

    page2seg

    Purpose:

    Translates a page:offset into a far pointer.

    Format:

    #Include "icadeclt.h"
    
    char far * ICAENTRY page2seg(page_off);
    struct offpage *page_off;
    
    Remarks:

    The page2seg function converts address formats from page:offset format to segment:offset format. The page and offset format is used by system unit programs to access co-processor adapter memory through the memory window. A common use of the page2seg function would be to load a buffer address from a task's BCB and convert it with page2seg to a 32-bit pointer; the pointer can then be used by a task to access the buffer. This conversion is done automatically by the bcb_ib_r, bcb_ob_r and bcb_st_r functions when a task is reading the address of its own buffers.

    The function seg2page converts the other direction, from segment addresses to page and offset addresses.

    This routine performs the same function as SVI 0x62.

    Returns:

    This routine does not return an error code.

    Function value = Far pointer of specified
                     page:offset
    
    Example:
    #Include "icadeclt.h"
    
    struct offpage bufaddr;
    char far *bufptr;
    
             /* Assume a page-and-offset address */
             /* in "bufaddr"                     */
    
             /* Convert it to a far pointer      */
    bufptr = page2seg(&bufaddr;);
    
    Related Topics:
         bcb_ib_r, bcb_ob_r, bcb_st_r, seg2page
    

    pag2segc

    Purpose

    Translates a co-processor adapter's storage address from page format to segment format. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY pag2segc (page_off, seg_off);
    struct offpage *page_off;
    char far **seg_off;
    
    Remarks:

    This function performs the same function as SVI 0x62 and should be used for the Realtime Interface Co-Processor Portmaster Adapter/A, because an error is returned if the address is in expanded memory, or if the page size is above 64KB. The page_off parameter is the page to translate; the seg_off parameter returned is the translated segment:offset.

    Returns:

    Function value =
            0x0000 = Translated segment and offset
                     within installed base memory
            0x0012 = 32-bit physical address and
                     error greater than installed
                     base memory
    
    Example:
    #Include "icadeclt.h"
    
    struct offpage bufaddr;
    char far *bufptr;
    int errcode;
    
              /* Assume a page:offset address    */
              /* in "bufaddr".                   */
              /* Convert it to a 32-bit pointer. */
    
    errcode = pag2segc(&bufaddr;, &bufptr;);
    
    Related Topics:
         bcb_ib_r, bcb_ob_r, bcb_st_r, seg2page, page2seg
    

    pdmareg

    Purpose:

    Reads or writes the registers of the specified direct memory access DMA/peripheral interface controller channel. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY pdmareg (port, rw, regs)
    unsigned int port;
    unsigned char rw;
    struct pdmaregstruct pdma;
    
    Remarks:

    The channel parameter indicates which DMA channel to access. No error code is return by this function. It will use INT CEh (AH=02).

    port = Base address of DMA/peripheral interface
           communications port
    
    rw   = 1xxx xxxx  Read
           0xxx xxx0  Write with baud rate less than
                      1Mbps
           0xxx xxx1  Write with baud rate greater
                      than 1Mbps
    
           Where the value of x does not
           matter.
    
    regs = Pointer to structure where DMA registers
           are read or stored
    
    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    struct pdmaregstruct pdma;
    
    pdmareg(0x8000, 0x80, DMA/Peripheral Interface Communications Controller)
                           /* Read channel 0 */
    
    Related Topics:
         None
    

    peer_req

    Purpose:

    Sends a peer request to another task. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY peer_req (req)
    struct prbstruct *req;
    
    Remarks:

    req = Far pointer to peer request block

    The peer_req function supports the Realtime Interface Co-Processor Portmaster Adapter/A only. The destination task can be a task on a local or a remote processor. The remote processor can be either another Realtime Interface Co-Processor Portmaster Adapter/A adapter or the system unit.

    Peer_req can be called from an interrupt handler only when the NO WAIT option in the peer request block is requested.

    Refer to "Peer Request Block" (prbstruct), in Chapter 2, for a description of the peer request block. Refer to "Peer Services" in the Realtime Interface Co-Processor Firmware Technical Reference manual for an overview of the peer services provided by Realtime Control Microcode Version 2.01 for the Realtime Interface Co-Processor Portmaster Adapter/A.

    This routine enables interrupts.

    Returns:

    Function value =
            0x0000 = No errors.
            0x0001 = Invalid entry parameter (the
                     peer request block completion
                     code field contains errors).
            0x0005 = Access denied (peer services
                     are not enabled).
            0x0013 = Invalid target processor/task.
    
    Example:
    #Include "icadeclt.h"
    
    struct prbstruct far *PRB;
    
    peer_req(&PRB;);   /* Send peer request with */
                      /* acknowledgement.       */
    
    Related Topics:
         None
    

    phys2page

    Purpose:

    Converts a 32-bit physical address to a page:offset address. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY phys2page (windowsize,
                           physaddr, page, pageoff)
    unsigned char windowsize;
                        /* 0x0000 =  8KB        */
                        /* 0x0001 = 16KB        */
                        /* 0x0002 = 32KB        */
                        /* 0x0003 = 64KB        */
                        /* 0x00FF = Window size */
    unsigned long physaddr;
    unsigned int *page;
    unsigned int *pageoff;
    
    Remarks:
    physaddr       = 32-bit physical address
    page           = Address of translated page
    pageoff        = Address of translated page offset
    
    Note: For the Realtime Interface Co-Processor Multiport Adapter, Model 2,
          the window size is always 8KB. On a Realtime Interface Co-Processor
          Portmaster Adapter/A, if the window size is greater than 64KB, then
          a 64KB block size is used when performing the conversion.
    
    Returns:
    Function value =
            0x0000 = No error
            0x0002 = Page size cannot be stored in
                     16-bit register
    
    Example:
    #Include "icadeclt.h"
    
    unsigned long physaddr;
    unsigned int page;
    unsigned int pageoff;
    unsigned int error;
    
    error = phys2page(1, 2010, &page;, &pageoff;);
      /* Convert a physical address, windowsize*/
      /* 16KB, into a page:offset address      */
    
    Related Topics:
         seg2phys
    

    poppgmap

    Purpose:

    Restores the expanded memory page frame mapping that was previously saved by a pushpgmap call. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY poppgmap (void)
    
    Remarks:

    See "pushpgmap," later in this chapter, for a description of the use of the save and restore page map functions.

    Returns:

    Function value =
            0x0000 = No errors.
            0x0001 = Invalid entry parameter
            0x0005 = Access denied (expanded memory
                     not present)
            0x001B = Stack overflow/underflow
    
    Example:
    #Include "icadeclt.h"
    
    int errorcode;
    
    errorcode = poppgmap ();
    
    Related Topics:
         pushpgmap
    

    postcd_r

    Purpose:

    Reads the task's post code.

    Format:

    #Include "icadeclt.h"
    
    unsigned int ICAENTRY postcd_r(void);
    
    Remarks:

    The postcd_r function reads the task's post code from its TCB and returns it as the function return value.

    A post code is sent when a task is posted. The task should read its post code after it has returned from a call to svcwait.

    Returns:

    Task's post code.

    Example:

    #Include "icadeclt.h"
    
    unsigned int ICAENTRY next_post_code;
    int error_code;
    
    error_code = svcwait();/* Wait for next post to */
                           /* arrive.               */
    
    next_post_code = postcd_r();  /* Read post code */
                                  /* from TCB.      */
    
                  /* ... Then process post code ... */
    
    Related Topics: posti, svcpost, svcwait

    posti

    Purpose:

    Posts a task without necessarily causing a dispatch cycle.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY posti(post_task,post_code);
    unsigned char post_task;
    unsigned int post_code;
    
    Remarks:

    The posti function posts a task (post_task) and passes it a post_code. This is the same as the svcpost function except that it may not cause a dispatch cycle and can be used from an interrupt handler. A dispatch cycle can be caused if a higher priority task is posted causing a preemptive dispatch.

    This performs the same function as SVI 0x64.

    Returns:

    Function value =
            0x0000 = No errors
            0x0005 = Access denied
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char async_task_num;
    unsigned int start_code;
    int error_code;
    
    error_code = posti(async_task_num,start_code);
       /* Post an ASYNC protocol task to  tell it */
       /* to start transmission                   */
    
    Related Topics:
         postcd_r, svcpost, svcwait
    

    psb_and

    Purpose:

    Performs a bit-wise AND with the task's primary status.

    Format:

    #Include "icadeclt.h"
    
    unsigned char ICAENTRY psb_and(mask);
    unsigned char mask;
    
    Remarks:

    The psb_and function performs a bit-wise AND with the task's primary status byte and the mask parameter. This is useful for clearing bits in the primary status. The new primary status byte is returned as the function return value.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned char new_stat;
    
    new_stat = psb_and(0x3F); /* Clear PSBUSY and */
                              /* PSOBBZ bits      */
    
    Related Topics:
         psb_or, psb_r, psb_w
    

    psb_or

    Purpose:

    Performs a bit-wise OR with the task's primary status.

    Format:

    #Include "icadeclt.h"
    
    unsigned char ICAENTRY psb_or(mask);
    unsigned char mask;
    
    Remarks:

    The psb_or function performs a bit-wise OR with the task's primary status byte and the mask parameter. This is useful for setting bits in the primary status. The new primary status is returned as the function return value.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned char new_stat;
    
    new_stat = psb_or(0x30); /* Set ESTATS and ERROR */
                             /* bits after an error  */
                             /* occurs.              */
    
    Related Topics:
         psb_and, psb_r, psb_w
    

    psb_r

    Purpose:

    Reads the task's primary status byte.

    Format:

    #Include "icadeclt.h"
    
    unsigned char ICAENTRY char psb_r(void);
    
    Remarks:

    The psb_r function reads the task's own primary status byte from the interface block and returns it as the function return value.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    unsigned char primstat;
    
    primstat = psb_r();
    
    Related Topics:
         psb_and, psb_or, psb_w
    

    psb_w

    Purpose:

    Writes the task's primary status byte.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY psb_w(status);
    unsigned char status;
    
    Remarks:

    The psb_w function writes the status parameter to the task's primary status byte. The psb_or and psb_and functions can be used for setting or clearing status bits to save the time of reading and then writing the primary status byte.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    psb_w(0x03);        /* Set status bits LOADED */
                        /* and INITZD             */
    
    Related Topics:
         psb_and, psb_or, psb_r
    

    pushpgmap

    Purpose:

    Saves the contents of the page mapping registers for the entire page frame in an internal save area. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY pushpgmap(void)
    
    Remarks:

    The pushpgmap function supports the Realtime Interface Co-Processor Portmaster Adapter/A only. This function saves the memory mapping context when an interrupt occurs.

    Every pushpgmap call must have a corresponding poppgmap call. To maintain stack integrity, these calls must be used like the 80186 Push and Pop instructions are used to preserve the register environment in an interrupt handler.

    Returns:

    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0005 = Access denied (expanded memory
                     not present)
            0x001B = Stack overflow/underflow
    
    Example:
    #Include "icadeclt.h"
    
    int errorcode;
    
    errorcode = pushpgmap ();
    
    Related Topics:
         poppgmap
    

    readcio

    Purpose:

    Reads the value of the specified CIO port data register.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY readcio(port,select,value);
    unsigned char port;
    unsigned char select;
    unsigned char *value;
    
    Remarks:

    The readcio function reads the data register of a CIO port and returns the selected inputs. No check is made to ensure that the calling task is the owner of the port. No checks are made to ensure that a read is requested for an input bit. Data polarity resolution is the responsibility of the calling task.

    For the Realtime Interface Co-Processor, Realtime Interface Co-Processor Multiport and Realtime Interface Co-Processor Multiport/2, the valid range of the port parameter depends on the presence of CIO 1, which can be determined by examining the Hardware Configuration Descriptor (HCD) bits (described in the Realtime Interface Co-Processor Firmware Technical Reference). If CIO 1 is present and functioning, the range is 0-3; otherwise, the range is 0-1.

    For the Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2, the valid range depends on the presence of additional CIOs, which can be determined by examining the Hardware Configuration Descriptor (HCD) bits (described in the Realtime Interface Co-Processor Firmware Technical Reference). If CIO 7 is present and functioning, the range is 0-16h.

    This routine should only be used for CIO ports, communication port packages, or SCC/CIO packages. The port parameter indicates which CIO data register to read:

       0x00 = CIO 0, Port A     0x0C = CIO 4, Port B
       0x01 = CIO 0, Port B     0x0D = CIO 4, Port C
       0x02 = CIO 1, Port A     0x0E = CIO 5, Port A
       0x03 = CIO 1, Port B     0x0F = CIO 5, Port B
       0x04 = CIO 1, Port C     0x010 = CIO 5, Port C
       0x05 = CIO 2, Port A     0x011 = CIO 6, Port A
       0x06 = CIO 2, Port B     0x012 = CIO 6, Port B
       0x07 = CIO 2, Port C     0x013 = CIO 6, Port C
       0x08 = CIO 3, Port A     0x014 = CIO 7, Port A
       0x09 = CIO 3, Port B     0x015 = CIO 7, Port B
       0x0A = CIO 3, Port C     16 = CIO 7, Port C
       0x0B = CIO 4, Port A
    
    The readcio function should be used when the CIO has been allocated as a resource. It is normally used to interface with a special purpose electrical interface board; in this case, the bit definitions for the select and value parameters depend on the particular EIB. Although the CIO port data registers are often used in conjunction with an SCC for modem control, this function should not be used for reading modem controls.

    This performs the read function of the Read/Write CIO bits SVI.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char value;
    
    error_code = readcio (3, 0x000F, &value;);
         /* Read CIO port 3 lower nibble only. */
    
    Related Topics:
         writecio
    

    resumei

    Purpose:

    Cancels the suspended state of a task.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY resumei(task);
    unsigned char task;
    
    Remarks:

    The resumei function resumes the task after it has been suspended with the svcsspnd function. If the task was posted when it was suspended or was posted since it was suspended, the resumei function places the task on the dispatch queue. If the task is not suspended when resumei is called, no action is taken.

    The resumei routine performs the same function as SVI 0x66.

    Returns:

    Function value =
            0x0000 = Normal operation, no errors.
            0x0005 = Access denied.
            0x000C = Request action already performed;
                     task is not suspended.
            0x0014 = Invalid task number (task is not
                     started or task number is out of
                     range).
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char suspended_task;
    int error_code;
    
    error_code = resumei(suspended_task);
               /* Cancel suspended state of task */
    
    Related Topics:
         svcrsume, svcsspnd
    

    ringaddl

    Purpose:

    Adds an element to a structure with 32-bit forward and backward pointers.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY ringaddl(disp,before_ptr,element_ptr);
    unsigned int disp;
    unsigned char far *before_ptr;
    unsigned char far *element_ptr;
    
    Remarks:

    The ringaddl function adds an element referenced with the element_ptr parameter to a ring structure. It is inserted into the ring just before the element referenced by the before_ptr parameter. This function assumes the existence of at least one element in the ring. The disp parameter contains the displacement of the forward and backward parameters in the ring element referenced with element_ptr. The two pointers should be far (32-bit) pointers, with the backward pointer immediately following the forward pointer.

    Returns:

    No error codes are returned by this function.

    Example:

    #Include "icadeclt.h"
    
    struct ringelem {
        struct ringelem far *fore;
        struct ringelem far *back;
        char elemdata[100];
        } elem1, *head;
    
             /* Assume "head" points to head of   */
             /* ring.                             */
    
             /* The "disp" is 0 because there are */
             /* no fields before the pointers in  */
             /* the structure.                    */
    
    ringaddl(0,(unsigned char far *)head,
               (unsigned char far *)&elem1;);
    
    Related Topics:
         ringadds, ringreml, ringrems
    

    ringadds

    Purpose:

    Adds an element to a ring with 16-bit forward and backward pointers.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY ringadds(disp,before_offset,
                                   element_offset);
    unsigned int disp;
    unsigned char *before_offset;
    unsigned char *element_offset;
    
    Remarks:

    The ringadds function adds the element referenced with the element_offset parameter to a ring structure. It is inserted before the element referenced with the before_offset parameter, which is assumed to be an element in the ring. The ring structure is assumed to have at least one element. The disp parameter contains the offset within the structure of the forward and backward pointers in the ring element, where the forward pointer is immediately followed by the backward pointer.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors.
            0x0013 = The two ring elements are in
                     different segments; no action
                     is taken.
    
    Example:
    #Include "icadeclt.h"
    
    struct ringelem {
        struct ringelem *fore;
        struct ringelem *back;
        char elemdata[100];
        } elem1, *head;
    
              /* Assume "head" points to head of   */
              /* ring.                             */
    
              /* The "disp" is 0 because there are */
              /* no fields before the pointers     */
    
    ringadds(0,(unsigned char *)head,
               (unsigned char *)&elem1;);
    
    Related Topics:
         ringaddl, ringreml, ringrems
    

    ringreml

    Purpose:

    Removes an element from a ring structure with 32-bit forward and backward pointers.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY ringreml(disp,element_ptr);
    unsigned int disp;
    unsigned char far *element_ptr;
    
    Remarks:

    The ringreml function removes an element referenced by the element_ptr parameter from a ring structure with 32-bit forward and backward pointers. The disp parameter contains the offset of the forward and backward pointers in the ring element.

    Returns:

    Function value =
            0x0000 = Normal completion; element is
                     not last in the ring
            0x0001 = Normal completion; element is
                     last in the ring
            0x0002 = Error detected
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    struct ringelem {
        struct ringelem far *fore;
        struct ringelem far *back;
        char elemdata[100];
        } *elem, *head;
    
        /* Remove first element from ring where  */
        /* "head" points to head of ring.        */
    
        /* Get pointer to first queue element.   */
    elem = head;
    
        /* Update "head" pointer to next element.*/
    head = head.fore;
    
        /* Remove element from ring. "disp" = 0  */
        /* because pointers are first in record. */
    error_code = ringreml(0, (unsigned char far *)elem);
    
    Related Topics:
         ringaddl, ringadds, ringrems
    

    ringrems

    Purpose:

    Removes an element from a ring structure with 16-bit forward and backward pointers.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY ringrems(disp,element_offset);
    unsigned int disp;
    unsigned char *element_offset;
    
    Remarks:

    The ringrems function removes an element referenced by the element_offset parameter from a ring structure with 16-bit forward and backward pointers. The disp parameter contains the offset of the 16-bit pointers in the ring element.

    Returns:

    Function value =
            0x0000 = No error; last element in ring
            0x0001 = No error; not last element in ring
            0x0002 = Error detected
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    struct ringelem {
        struct ringelem *fore;
        struct ringelem *back;
        char elemdata[100];
        } *elem, *head;
    
        /* Remove first element from ring where   */
        /* "head" points to head of ring.         */
    
        /* Get pointer to first queue element.    */
    elem = head;
    
        /* Update "head" pointer to next element. */
    head = head.fore;
    
        /* Remove element from ring. "disp" = 0   */
        /* because pointers are first in record.  */
    error_code = ringreml(0, (unsigned char *)elem);
    
    Related Topics:
         ringaddl, ringadds, ringreml
    

    rtsdtr

    Purpose:

    Controls the RTS and DTR outputs for a port.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY rtsdtr(port,select,request);
    unsigned char port;
    unsigned char select;
    unsigned char request;
    
    Remarks:

    The rtsdtr function enables, disables, or enables and disables the RTS and DTR control outputs. This routine should be used only for communication port packages, SCC/CIO packages or RS-232 ports. It is the responsibility of the application to verify that the installed electrical interface board is appropriate for the service requested. Use of this routine requires that all writes to the SCC, except to the SCC data register, be performed using Realtime Control Microcode and PROM Services calls (such as sccreg).

    The format of the select parameter is 000000dr, where the bits have the following meanings:

      If d=0, do not alter DTR output.
      If d=1, write request d value to DTR.
      If r=0, do not alter RTS output.
      If r=1, write request r value to RTS.
    
    The format of the request parameter is 000000dr where the bits d and r are the values written if selected in the select parameter.

    For this function, it is assumed that the initial allocation state of the CIO ports is preserved.

    The rtsdtr routine performs the same function as RTS/DTR Control SVI. This routine does not enable interrupts.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (selected signal
                     not supported on port)
            0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
    error_code = rtsdtr (4, 0x0001, 0x0000);
           /* Request clear of port 4 RTS output; */
           /* Leave DTR unchanged.                */
    
    Related Topics:
         None
    

    sccreg

    Purpose:

    Reads/writes any type of communications controller port.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY sccreg(port,rw,table_ptr);
    unsigned char port;
    unsigned char rw;
    unsigned char *table_ptr;
    
    Remarks:

    The sccreg function reads any SCC/DUSCC registers and writes to any SCC/DUSCC write registers. No enabling or disabling of the port is done automatically. No checking is done to verify that the calling task owns the port or that the values written are meaningful.

    The port parameter should have the number of the SCC port to access. The rw flag determines if the operation is a read or a write; values less than or equal to 0x7F indicate a write, and values greater than or equal to 0x80 indicate a read operation.

    The table_ptr parameter is a pointer to a fixed format parameter table. The first byte of this table must be a non-0 count of registers to read or write. Following the count byte are byte pairs of which the first byte is always a pointer to the register to be read or written. If a write is requested, the second byte in each pair is the value to write. If a read is requested, the second byte in each pair is overwritten with the value read.

    Note:

    Zilog write registers 2 and 9 and DUSCC write registers ICR, IVR and MRR should not be written; changing these registers may yield unpredictable results. See the Realtime Interface Co-Processor Firmware Technical Reference for a complete list of Zilog and DUSCC registers.

    Tasks should acquire the communication port with the svcalloc function before using the sccreg routine.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
               /* Read registers 3 and 5 from Port 0 */
    
    unsigned char scctable[5] = "\x02\x03\x00\x05\x00";
    
    sccreg(0,0x80,scctable);
    
    Related Topics:
         sccrst, svcalloc
    

    sccrst

    Purpose:

    Resets a specified communications controller port.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY sccrst(port);
    unsigned char port;
    
    Remarks:

    The sccrst function issues a software reset to the selected port. The port parameter indicates which port to reset.

    SCC and DUSCC ports are reset to known states. Refer to the PROM service description in your co-processor adapter's Technical Reference manual for descriptions of the states to which the communications controller ports are set.

    When calling this routine to reset a Signetics DUSCC port, the interrupts to the processor must be enabled prior to issuing the sccrst. The Interrupt Enable Register (IER) of the port to be reset should be initialized to 0 (zero).

    The sccrst routine cannot guarantee that the state of the processor interrupt enable flag will be preserved during its execution.

    Tasks should acquire the SCC with the svcalloc before using the sccrst routine.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    sccrst(1);             /* Reset SCC Port 1 */
    
    Related Topics:
         sccreg, svcalloc
    

    seg2page

    Purpose:

    Translates a co-processor adapter storage address from far pointer to page and offset format.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY seg2page(page_off,seg_off);
    struct offpage *page_off;
    char far *seg_off;
    
    Remarks:

    The seg2page function converts a segment and offset address to a page and offset address. The page and offset address format is used by system unit applications to look through the memory window at co-processor adapter memory. The bcb_ib_w, bcb_ob_w and bcb_st_w functions do this automatically when storing buffer addresses in the task's BCB.

    In Realtime Control Microcode Version 2.01, for window sizes greater than 64KB, the offset is 0 through 64KB; the lower-order bits of the page number contains a logical 64KB page.

    The seg2page routine performs the same function as SVI 0x60.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    struct offpage buf_pageaddr;
    char tempbuf[100];
    char far *tempbufptr;
    
       /* Convert array address to page and offset */
    tempbufptr = (char far *) tempbuf;
    seg2page(&buf;_pageaddr,tempbufptr);
    
    Related Topics:
         page2seg
    

    seg2phys

    Purpose:

    Converts a segment:offset into a translated 32-bit physical address for the Realtime Interface Co-Processor Portmaster Adapter/A, and a segment:offset to a physical address for the Realtime Interface Co-Processor Multiport Adapter, Model 2. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY seg2phys (segaddr, physaddr);
    char far *segaddr;
    unsigned long *physaddr;
    
    Remarks:
    segaddr  = The segment and offset value to translate.
    physaddr = Translated physical address
    
    The seg2phys function returns an input address error if the address falls within the PROM area. This routine performs the same function and uses the same data format as PROM Services routine (INT CEh, AH = 00).

    Returns:

    Function value = A 20-bit address contained in a
                     32-bit field
            0x0000 = No errors
            0x0001 = Input address error
    
    Example:
    #Include "icadeclt.h"
    
    unsigned long segaddr, physaddr;
    unsigned int error;
    segaddr = 0xC0000000;
    
    error = seg2phys(segaddr, &physaddr;);
                  /* Convert segment:offset into */
                  /* translated physical address */
    
    Related Topics:
         phys2pg
    

    setclockopt

    Purpose:

    Sets DCE or DTE clocking option of the transmitter clock on ports 2 through 5 of a Realtime Interface Co-Processor Multiport/2 6-port synchronous electrical interface board, and ports 0 through 7 on Realtime Interface Co-Processor Portmaster Adapter/A and Realtime Interface Co-Processor Multiport Adapter, Model 2.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY setclockopt (port, option);
    unsigned char port;
    unsigned char option;
    
    Remarks:

    Ports 0 and 1 on the Realtime Interface Co-Processor and Realtime Interface Co-Processor Multiport are set by jumpers. Ports 0 and 1 on the Realtime Interface Co-Processor Multiport/2 are set with the reference diskette at system configuration time. The default for the setclockopt function on power up is DCE clock. This routine performs the same function as Clocking Option Control SVI for Realtime Control Microcode Version 1.51 and Realtime Control Microcode Version 2.01.

    A 0 in the option field sets the DCE clock option; a 1 in the option field sets the DTE clock option.

    This routine sets to 1 or clears to 0 the associated bit in CIO 1 port C. It is assumed that the initial allocation state of CIO 1 port C is preserved. The port is the port number on which to set the clocking option.

    It is the responsibility of the application to compare the returned clocking option with the requested one and if they do not match, set the clocking option correctly in hardware.

    This routine assumes that the initial allocation state of the CIO ports is preserved.

    This routine does not enable interrupts.

    Returns:

    Function value =
      0x0000 = No errors.
      0x0018 = Invalid port; asynchronous port only.
      0x0019 = DCE clock set in hardware.
      0x0119 = DTE clock set in hardware.
      0x0219 = Hardware clocking option cannot be
               read.  Task is running on the
               Realtime Interface Co-Processor or the
               Realtime Interface Co-Processor Multiport
               co-processor adapter.
    
    Example:
    #Include "icadeclt.h"
    
    unsigned int errorcode;
    
    errorcode = setclockopt(2,1);
          /* Set clock option for port 2 to DTE */
    
    Related Topics:
         None
    

    set_time

    Purpose:

    Sets the co-processor adapter time in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY set_time (timestruct)
    struct timeb *timestruct;
    
    Remarks:

    timestruct = Segment/offset of time structure

    The initial time is obtained from the system unit operating system support during Realtime Control Microcode Version 2.01 initialization. The DOS or OS/2 support loader issues a set time command after loading Realtime Control Microcode Version 2.01. The system unit clock and the Realtime Control Microcode Version 2.01 clock is synchronized at initialization. Due to differences between system unit processors and operating systems, the two clocks cannot be guaranteed to be perfectly synchronized. Realtime Control Microcode Version 2.01 does not attempt to correct the clock differential.

    This routine does not enable interrupts.

    The format of the time structure is shown below. It is identical to the structure used by the C ftime() function. By using this format, the C library time functions can be used to support time conversions on the Realtime Interface Co-Processor Portmaster Adapter/A adapter.

    struct timeb {
      time_t time;           /* Seconds since 1-1-70*/
      unsigned short millitm;/* Milliseconds        */
      short timezone;        /* Minutes from UTC,   */
                             /* -1 = time zone      */
                             /* undefined           */
      short dstflag;         /* Daylight savings    */
                             /* time flag           */
      };
    
    Returns:
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0013 = Invalid data (milliseconds out
                     of range)
    
    Example:
    #Include "icadeclt.h"
    
    #include 
    struct timeb *timestruct;
    
    set_time(×truct;);
    ctime (×truct;);      /* Convert seconds to */
                              /* current time       */
    
    Related Topics:
         ftime, time
    

    sfw_chn

    Purpose:

    Verifies that a software interrupt is intended for the task.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY sfw_chn(rbptr);
    struct vrbstruct *rbptr;
    
    Remarks:

    The sfw_chn function is called in a software interrupt handler just after the call to the int_ntry function. The function checks the task number for which the software interrupt was intended (found in the AH register). If the interrupt's task number is the same as the current task, sfw_chn returns control to the interrupt handler; otherwise, control is passed to the next owner of the software interrupt. The rbptr parameter should point to the request block used to acquire the software interrupt.

    Note:  Register AH must be filled with the target task number when
           int86() routine is used to cause interrupt.
           This routine cannot be shared by more than one task.
    
    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    struct vrbstruct software_int;
    
    void far software_inthan()
    {
            int_ntry();    /* Save environment    */
            sfw_chn(&software;_int);
                           /* Check task number   */
                           /* Continue if same    */
    
             /* ... Code to handle interrupt ...  */
    
            sfw_exit(0,&software;_int);
                           /* Restore environment */
                           /* and exit            */
    }
    
    Related Topics:
         int_ntry, sfw_exit, svcalloc
    

    sfw_exit

    Purpose:

    Restores the machine environment and exits a software interrupt handler.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY sfw_exit(fast,rbptr);
    unsigned int fast;
    struct vrbstruct *rbptr;
    
    Remarks:

    The sfw_exit function should be the last call in a software interrupt handler. It restores all the registers from their save area on the stack, and passes control either to the next user of the software interrupt or the calling task. The rbptr parameter should point to the resource request block used to acquire the software interrupt. If the fast parameter has a value of 1, control is returned directly to the calling task via the ORI_VECT field in the structure referenced by rbptr. If fast has a value of 0, control is passed to the next handler to share this software interrupt via the OLD_VECT field.

    This routine cannot be shared by more than one task.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    struct vrbstruct software_int;
    
    void far software_inthan()
    {
            int_ntry();    /* Save environment.   */
            sfw_chn(&software;_int);
                           /* Check task number;  */
                           /* continue if same.   */
    
             /* ... code to handle interrupt ...  */
    
            sfw_exit(1,&software;_int);
                           /* Restore environment */
                           /* and exit fast.      */
    }
    
    Related Topics:
         int_ntry, sfw_chn, svcalloc
    

    sti

    Purpose:

    Enables interrupts.

    Format:

    #Include "icadeclt.h"
    
    void ICAENTRY sti(void);
    
    Remarks:

    The sti function enables maskable external interrupts on the 80186 microprocessor. Interrupts can be disabled by calling the cli function.

    Returns:

    This routine does not return an error code.

    Example:

    #Include "icadeclt.h"
    
    sti();
    
    Related Topics:
         cli
    

    svcalloc

    Purpose:

    Acquires one of the Realtime Control Microcode's resources.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcalloc(offset);
    char *offset;
    
    Remarks:

    Resource allocation does not change with Realtime Control Microcode Version 2.01, but resource blocks must remain in addressable 80186 memory.

    The svcalloc allocates a resource such as an interrupt vector, storage block, SCC/CIO package, user queue, communications port, RS-232 port, RS-422 port, SCC port, CIO port, or hardware or software timer. A pointer to the request block is passed as the offset parameter. Only one resource may be acquired per call; the type of resource is determined by the block descriptor byte, which follows the next and prev pointers in the resource request block. This routine performs the same function as SVC 0x46.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0004 = EIB not present
            0x0005 = Access denied
            0x0006 = Port interface mismatch
            0x0007 = Communication controller mismatch
            0x0008 = Insufficient storage
            0x0013 = Invalid data, such as bad task
                     number or block descriptor
            0x0015 = Invalid timer number
            0x0016 = Invalid queue number
            0x001A = Insufficient expanded memory pages
            0x001C = Requested hook access not available
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    struct srbstruct memblock = {0,0,2,0,1,0};
            /* Define storage request block for task 1*/
    
            /* Search in low storage on a paragraph   */
            /* boundary for 10 paragraphs of memory   */
    memblock.HILO = 0;
    memblock.BOUND = 1;
    memblock.SRSIZE = 10;
    
     /* Acquire storage segment stored in SRSEG field */
    error_code = svcalloc(&memblock;);
    
    Related Topics:
         svcdeall
    

    svcasap

    Purpose:

    Invokes a dispatch cycle.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcasap(void);
    
    Remarks:

    The svcasap function causes a dispatch cycle to occur. This is a means for tasks to give up control during long code paths and allow other tasks to run. If a task does not return control to the Realtime Control Microcode by a call to svcasap or some other SVC, the Realtime Control Microcode forces a time slice within 10 milliseconds to cause a dispatch cycle to occur.

    This routine performs the same function as SVC 0x40.

    Returns:

    Function value =
            0x0000 = Normal completion; no error
            0x0005 = Access denied (when called from
                     an interrupt handler)
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
              /* ... Part 1 of long code path ... */
    
    error_code = svcasap();
    
              /* ... Part 2 of long code path ... */
    
    Related Topics:
         None
    

    svcbuild

    Purpose:

    Simulates a task load from the system unit.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcbuild(task,taskstor,thead);
    unsigned char task;
    struct srbstruct *taskstor;
    struct thstruct far *thead;
    
    Remarks:

    The svcbuild function creates another task on the co-processor adapter. The task parameter is the number of the new task. The taskstor parameter is a pointer to the storage request block to be given to the built task. If this parameter is NULL, the task is built in the building task's storage, and the built task is a child task of the building task. The thead parameter is a pointer to the task header for the task to be built. If the built task is built within the building task, the building task is called the parent task and the built task is called the child task.

    One restriction of the svcbuild function is that a child task may not build another task. A second restriction applies if the built task is built outside of the building task in an allocated storage block. The size in the built task's header must be the size of the storage block in which the task is to be built. If this size is incorrect and the built task is subsequently unloaded, the incorrect amount of storage is returned to the free storage pool. The Realtime Control Microcode cannot detect this error because the built task does not have to reside in storage at "build" time, only at "start" time.

    If a storage resource block is used in the call to allocate memory for the new task, the resource block is removed from the building task's resource block queue. The storage resource block is used to acquire storage in which the new task resides. The built task is a peer rather than a child of the building task in this case.

    This routine performs the same function as SVC 0x39.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler, or a child
                     task attempted to build a task)
            0x0013 = Invalid data (taskstor is
                     non-0 and does not point to a
                     valid storage request block, or
                     thead doesn't point to a
                     paragraph boundary)
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    struct srbstruct newtaskmem = {0,0,2,1,1,0,1,0x100};
                       /* Storage request block      */
                       /* - search low storage       */
                       /* - owner task = 1           */
                       /* - on a paragraph boundary  */
                       /* - size = 0x100 paragraphs  */
    struct thstruct far *newtaskhd;
    
                       /* Allocate new task's memory */
    error_code = svcalloc(&newtaskmem;);
    
       /* "newtaskhd" = far pointer to storage block */
    *(((unsigned int *) &newtaskhd;)+1) = newtaskmem.srseg;
    *((unsigned int *) &newtaskhd;) = 0;
    
         /* Set up task header.  Overlay task header */
         /*  structure over start of memory block    */
    newtaskhd->LMODL = 0x10*0x100;
    newtaskhd->TASK = 2;
    newtaskhd->ZERO1 = 0;
    newtaskhd->TSKID = 0xACE;
    newtaskhd->PRIRTY = 5;
    newtaskhd->ZERO2 = 0;
    newtaskhd->DSEG = newtaskmem.srseg;
    newtaskhd->SSEG = newtaskmem.srseg;
    newtaskhd->SPTR = 0x10*0x100;
    newtaskhd->RBPTR = 0;
              /* ... Fill in CMDPTR and INITPTR to   */
              /*   appropriate interrupt handler ... */
    
                                     /* Build task 2 */
    error_code = svcbuild(2,&newtaskmem;,newtaskhd);
    
    Related Topics:
         svcalloc, svcstart
    

    svccantm

    Purpose:

    Cancels a software timer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svccantm(timer);
    unsigned char timer;
    
    Remarks:

    The svccantm function cancels the use of a software timer, where the timer parameter is the number of the timer to cancel. If the timer is not running, no action is taken.

    Software timers should be allocated with the svcalloc function before they are used. The only difference between the svccantm and cantime functions is that the svccantm function causes a dispatch cycle to occur.

    This routine performs the same function as SVC 0x45.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler)
            0x0015 = Invalid timer number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
    error_code = svccantm((unsigned char) 2);
                      /* Cancel software timer #2 */
    
    Related Topics:
         cantime, svcalloc, svcprdic, svctimer
    

    svcdeall

    Purpose:

    Returns a Realtime Control Microcode resource.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcdeall(offset);
    char *offset;
    
    Remarks:

    The svcdeall function returns a resource, such as an interrupt vector, storage block, user queue, RS-232 port, RS-422 port, SCC port, CIO port, or timer. The offset parameter should point to the resource request block that was originally used to acquire the resource.

    This routine performs the same function as SVC 0x47.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler)
            0x0013 = Invalid data (bad task number,
                     invalid block descriptor, or
                     storage return size greater
                     than block size)
            0x0015 = Invalid timer number
            0x0016 = Invalid queue number
            0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    struct drbstruct dmablock;
    int error_code;
    
             /* ... Fill in "dmablock" fields ... */
    
    error_code = svcalloc(&dmablock;);
                               /* Allocate dma    */
    
                               /* ... Use dma ... */
    
    error_code = svcdeall(&dmablock;);
                               /* Deallocate dma  */
    
    Related Topics:
         svcalloc
    

    svcinitc

    Purpose:

    Indicates to the Realtime Control Microcode that the task's initialization is complete.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcinitc(perm);
    unsigned int perm;
    
    Remarks:

    The svcinitc signals the Realtime Control Microcode that the task has finished initializing. The "initialized" bit is set to 1 in the task's primary status byte in the interface block.

    The task may be marked as permanent by this function. If the perm parameter is 1, then the task is marked as permanent in the task's TCB state byte; a value of 0 indicates that the task is not permanent. Permanent tasks cannot be stopped or unloaded. If a child task is marked as permanent, the parent task is also assigned a permanent status.

    If the task is already initialized, no operation is performed.

    This routine performs the same function as SVC 0x48.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (called from an
                     interrupt handler)
            0x000C = No operation performed, task
                     already initialized
    
    Example:
    #Include "icadeclt.h"
    
    main()
    {
            int error_code;
               /* ... Initialization code ...     */
    
               /* Init complete, a permanent task */
            error_code = svcinitc(1);
    
               /* ... Rest of task "main" ...     */
    }
    
    Related Topics:
         None
    

    svcintrq

    Purpose:

    Causes an interrupt to the system unit.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcintrq(request,retry_count);
    unsigned char request;
    unsigned int retry_count;
    
    Remarks:

    The svcintrq function generates an interrupt to the system unit from the requesting task. Five options may be selected by the bit-sensitive request parameter.

    The format of the request parameter is xxxabcde where the bits have the following meanings:

            If a=1, IPL the system unit (c, d, and e
                    not used)
            If b=1, Infinite retry on interrupt
                    presentation and response;
                    retry_count is ignored
            If b=0, Use retry_count for number of
                    retries
            If c=1, Output buffer busy bit is
                    cleared
            If d=1, Busy bit is cleared
            If e=1, Task is waited after interrupt
            x = Not used
    
    This routine performs the same function as SVC 0x37.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied
            0x0009 = Interrupt busy
            0x000A = No response from system unit
            0x0013 = Invalid retry count of 0
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
        /* Interrupt PC with retry count of 100 */
        /* and turn off busy and output         */
        /* buffer busy bits                     */
    error_code = svcintrq (0x06, 100);
    
    Related Topics:
         None
    

    svcpost

    Purpose:

    Places a task on the dispatch queue.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcpost(post_task,postcode);
    unsigned char post_task;
    unsigned int postcode;
    
    Remarks:

    The svcpost function places the intended task (post_task) on the dispatch queue, if it is not suspended. It also sets the TCB posted flag and writes the postcode parameter to the intended task's TCB post code field. If the task is already posted, only the post code in the TCB is changed. If the task is suspended, the TCB postcode, the TCB posted flag, and the TCB state byte posted bit are set but the task is not put on the dispatch queue until the task is resumed. The posted flag must be reset to 0 by the task for the task to be able to wait itself.

    The following bit format is recommended for postcode. This format does not have to be used because the Realtime Control Microcode does not check the postcode.

    postcode = tttt tttt pppp abcd, where
               tttt tttt = the posting task number
               pppp = user-defined post code
                  a = 1 if posted by I/O interrupt
                        handler
                  b = 1 if posted by timer expiration
                  c = 1 if posted by command subroutine
                  d = 1 if posted by General Post
    
    This routine performs the same function as SVC 0x3F.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
      /* General postcode of 3 to task 2 from task 1 */
    error_code = svcpost(2,0x0131);
    
    Related Topics:
         postcd_r, posti, svcpost
    

    svcprdic

    Purpose:

    Starts a periodic software timer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcprdic(timer,duration, handler);
    unsigned char timer;
    unsigned int duration;
    void (far *handler)(void);
    
    Remarks:

    The svcprdic function starts a software timer that automatically restarts itself when it times out. This timer calls the user's timer vector on each time-out. This timer can be canceled in the same manner as a non-periodic timer with the cantime or svccantm functions.

    The timer parameter contains the number of the timer to start; it should be acquired first with the svcalloc function. The duration parameter should contain the time duration in multiples of 5 milliseconds. For example, a duration of 1 sets a timer duration of 5 milliseconds; a duration of 2 sets a timer duration of 10 milliseconds. The handler parameter should be the name of the subroutine that handles the software timer interrupts.

    This routine performs the same function as SVC 0x43.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler)
            0x0013 = Invalid data (time period
                     is 0)
            0x0015 = Invalid timer number
    
    Example:
    #Include "icadeclt.h"
    
    struct trbstruct softtimer={0,0,7,1,1,0};
    int error_code;
    
    void far soft_timer_handler()
    {
          /*... Code to handle software timer ...  */
    }
    
          /* Allocate software timer               */
    error_code = svcalloc((char *) &softtimer;);
    
         /* Start timer for every 500 milliseconds */
    error_code = svcprdic(1,100,soft_timer_handler);
    
    Related Topics:
         svcalloc, svccantm, svctimer
    

    svcqryfs

    Purpose:

    Queries the Realtime Control Microcode for the free storage information on storage in base storage.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcqryfs(large_block,
                      large_size,free_paragraphs);
    unsigned int *large_block;
    unsigned int *large_size;
    unsigned int *free_paragraphs;
    
    Remarks:

    The svcqryfs function returns the segment of the largest block of free memory in large_block, the number of paragraphs (16 bytes) in the largest block of free memory in large_size, and the total number of paragraphs of free memory in free_paragraphs.

    This routine performs the same function as SVC 0x49.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler)
    
    Example:
    #Include "icadeclt.h"
    
    unsigned int large_seg,
                 large_size,
                 free_par;
    int error_code;
    
    error_code = svcqryfs(&large;_seg,&large;_size,
                          &free;_par);
    
    Related Topics:
         None
    

    svcrdvec

    Purpose:

    Reads the contents of an interrupt vector.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcrdvec(vectnum,seg_off);
    unsigned int vectnum;
    VECTOR *seg_off;
    
    Remarks:

    The svcrdvec function reads the 32-bit vector of the interrupt specified by the vectnum parameter and stores it at the address referenced by the seg_off parameter.

    This routine performs the same function as SVC 0x42.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler)
    
    Example:
    #Include "icadeclt.h"
    
    VECTOR breakvector;
    int error_code;
    
         /* read the breakpoint handler address */
    error_code = svcrdvec(3,&breakvector;);
    
    Related Topics:
         None
    

    svcrsume

    Purpose:

    Cancels the suspended state of a task.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcrsume(task);
    unsigned char task;
    
    Remarks:

    The svcrsume function cancels the suspended state of a task, given by the task parameter. If the task was posted when it was suspended or has been posted since it was suspended, the svcrsume function puts the specified task on the dispatch queue. If the task was not suspended, no operation is performed.

    This routine performs the same function as SVC 0x3E.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler)
            0x000C = Requested action already performed
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char suspended_task;
    
    error_code = svcrsume(suspended_task);
    
    Related Topics:
         resumei, svcsspnd
    

    svcsspnd

    Purpose:

    Suspends a task.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcsspnd(task);
    unsigned char task;
    
    Remarks:

    The svcsspnd function suspends the task given by the task parameter and sets the suspended flag in the task's TCB state byte to 1. If the suspended task is on the dispatch queue, it is removed from the dispatch queue. After a task is suspended, it may be posted; however, this post does not take effect until that task is resumed. To resume a task (that is, to cancel its suspended state), use the svcrsume or resumei function.

    This routine performs the same function as SVC 0x3D.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors.
            0x0005 = Access denied
            0x000C = Requested action already performed
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char task_to_suspend;
    
    error_code = svcsspnd(task_to_suspend);
    
    Related Topics:
         resumei, svcrsume
    

    svcstart

    Purpose:

    Starts a task.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcstart(task);
    unsigned char task;
    
    Remarks:

    The svcstart function starts the task given by the task parameter by building a task control block from the information in the task header. The task had to be previously loaded from the system unit or built by the svcbuild function. The svcstart function causes the task to be entered at its initial entry point.

    If the task is already started, no operation is performed.

    This routine performs the same function as SVC 0x3A.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied
            0x000C = Task is already started
            0x0013 = Invalid data
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    struct srbstruct newtaskmem;
    struct thstruct far *newtaskhd;
    
                /* Build and start task 3.       */
                /* Assume memory and task header */
                /* are already set up.           */
    
    error_code = svcbuild(3,&newtaskmem;,newtaskhd);
    error_code = svcstart(3);
    
    Related Topics:
         svcbuild
    

    svcstop

    Purpose:

    Stops a task.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcstop(task);
    unsigned char task;
    
    Remarks:

    The svcstop function stops a task given by the task parameter and removes the task's TCB from TCBTAB. All resources except the storage in which the task resides are returned to the Realtime Control Microcode. If the task is already stopped, svcstop performs no operation. A stopped task may be restarted by the svcstart function or a start command from a system unit application. The svcstop function also puts the task in the loaded state. All child tasks of the specified task are unloaded.

    This routine performs the same function as SVC 0x3B.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler, or task
                     is permanent)
            0x000C = Task is already stopped
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char task_to_stop;
    
    error_code = svcstop(task_to_stop);
    
    Related Topics:
         svcstart
    

    svctimer

    Purpose:

    Starts a one-shot software timer.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svctimer(timer,duration,
                                   handler);
    unsigned char timer;
    unsigned int duration;
    void (far *handler)(void);
    
    Remarks:

    The svctimer function starts a software timer specified by the timer parameter. The duration parameter sets the timer length in multiples of 5 milliseconds; for example, a value of 1 represents 5 milliseconds and a value of 2 represents 10 milliseconds. Valid values of the duration parameter are in the range of 0x0001 through 0xFFFF. The handler parameter is a 32-bit address of the interrupt handler that responds to the software timer interrupt.

    Software timers should be acquired with the svcalloc function before being used.

    This routine performs the same function as SVC 0x44.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (call from an
                     interrupt handler, or timer
                     is not owned by task)
            0x0013 = Invalid timer period
            0x0015 = Invalid timer number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
    void far soft_timer_handler()
    {  /* Handler for software timer interrupt  */  }
    
       /* Set timer 0 for 100 milliseconds with */
       /* handler as "soft_timer_handler".      */
    error_code = svctimer(0,20,soft_timer_handler);
    
    Related Topics:
         cantime, svcalloc, svccantm, svcprdic
    

    svctres

    Purpose:

    Terminates a task but does not remove it from storage.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svctres(void);
    
    Remarks:

    The svctres function causes the calling task to be terminated, but to remain in co-processor adapter storage. After successful completion of the svctres function, the task may not be started, stopped, posted, suspended, resumed, waited, or unloaded. The task has no task control block. A parent or child task may not be terminated with this function. The requesting task must not own any user interrupt vectors. This function may be used for installing interrupt handlers. One example of this would be a Time-of-Day routine.

    This routine performs the same function as SVC 0x41.

    Returns:

    If no error occurs, control does not return to the task after the call. The following error code is returned as the function return value in the case of an error:

    Function value =
            0x0000 = No errors
            0x0005 = Access denied (no calls from
                     an interrupt handler, or task
                     is a parent or child, or task
                     owns a user interrupt vector)
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
         /* ... Code to initialize, acquire a CIO */
         /*     timer before terminating ...      */
    
    error_code = svctres();
    
                 /* ... only reach this point if  */
                 /*     an error occurred ...     */
    
    Related Topics:
         None
    

    svcunld

    Purpose:

    Unloads a task.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcunld(task);
    unsigned char task;
    
    Remarks:

    The svcunld function unloads the task given by the task parameter, from co-processor adapter storage. If the task is not already stopped, it is stopped as described in the svcstop function. The task's resident storage is then returned to the free memory pool and the loaded bit in the task's primary status byte in the interface block is reset to 0. If any errors are detected, the command is not performed.

    This routine performs the same function as SVC 0x38.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied
            0x0014 = Invalid task number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char task_to_unload;
    
    error_code = svcunld(task_to_unload);
    
    Related Topics:
         svcstop
    

    svcwait

    Purpose:

    Puts a task in the wait state.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY svcwait(clear);
    int clear;
    
    Remarks:

    The svcwait function places the calling task in an idle or wait state. It is then ready for another task or one of its own interrupt handlers to request its services with the svcpost or posti functions. If the posted flag in the task's TCB is non-0, the wait request is a no-op; that is, control returns to the task without going to a wait state. If the clear parameter has a value of 1, the posted flag is cleared after the next post; if it has a value of 0, the posted flag is not cleared after the next post.

    This routine performs the same function as SVC 0x3C.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned int postcode;
    
    error_code = svcwait(1);/* Wait and clear Posted*/
                            /* Flag                 */
    
    postcode = postcd_r();  /* Read the post code   */
    
    Related Topics:
         clr_pf, postcd_r, posti, svcpost
    

    time

    Purpose:

    Returns the elapsed seconds since 01/01/70. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    time_t ICAENTRY time(timeptr)
    time_t *timeptr;
    
    Remarks:

    timeptr = storage location for time

    This routine is identical to the C ftime and time library routines, except that the time is read from the co-processor adapter rather than the system unit.

    The return value is stored in the location given by timeptr. If timeptr is NULL, the return value is not stored.

    Returns:

    This routine does not return an error code.

    timeptr        = time unless timeptr is NULL.
    function value = time
    
    Example:
    #Include 
    
    time_t time (timeptr)
    time_t *timeptr;
    
    unsigned long ltime;
    time(<ime;);   /* Get number of seconds since  */
                    /* 01/01/1970.                  */
    ctime(<ime;);  /* Convert number of seconds to */
                    /* current time.                */
    
    Related Topics:
         ftime, set_time
    

    unallocpgcnt

    Purpose:

    Returns the number of unallocated pages and the total number of expanded memory pages. This routine is available only in Realtime Control Microcode Version 2.01, on a Realtime Interface Co-Processor Portmaster Adapter/A with expanded memory.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY unallocpgcnt (unallocpg, emmpg)
    unsigned int *unallocpg;
    unsigned int *emmpg;
    
    Remarks:
    unallocpg      = number of unallocated expanded
                     memory pages
    emmpg          = total number of expanded memory
                     pages
    
    Returns:
    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0005 = Access denied
    
    Example:
    #Include "icadeclt.h"
    
    unsigned int unalloc_emmpages;
    unsigned int tot_emmpages;
    unsigned int rc;
    
    rc = unallocpgcnt(&unalloc;_emmpages, &tot;_emmpages);
    
    Related Topics:
         None
    

    u_q_add

    Purpose:

    Adds an element to a user queue.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY u_q_add(queue_no,elemaddr);
    unsigned char queue_no;
    char far *elemaddr;
    
    Remarks:
    queue_no = Queue number
    elemaddr = Physical address of the new queue element
    
    The element may reside within the expanded memory page frame in Realtime Control Microcode Version 2.01.

    The u_q_add function adds an element, referenced by the elemaddr parameter, to the end of the queue indicated by the queue_no parameter. The queue element is a structure of variable format. The only restriction is that the first field must be a far (32-bit) pointer to point to the next queue element. The user queue should be allocated with the svcalloc function before its use.

    This routine performs the same function as SVI 0x6C.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0016 = Invalid queue number
            0x0200 = No error, first entry in this
                     queue
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    struct qrbstruct queue = {0,0,5,1,2,0};
                   /* Request block for queue 1    */
                   /* from task 2.                 */
    struct qelem {
            struct qelem far *next;
            char data[100] = "Sample data";
            } elem1;
    
                   /* Acquire queue #1 for task 2. */
    error_code = svcalloc((char *) &queue;);
    
                   /* Add "elem1" to queue #1.     */
    error_code = u_q_add(1,(unsigned char far *)&elem1;);
    
    Related Topics:
         svcalloc, u_q_rcv, u_q_rem, u_q_addp
    

    u_q_addp

    Purpose:

    Adds an element to a user queue. This routine is available only in Realtime Control Microcode Version 2.01.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY u_q_addp (queue_no, elemaddr)
    unsigned char queue_no;
    unsigned long elemaddr;
    
    Remarks:
    queue_no = Queue number
    elemaddr = Physical address of the new queue element
    
    The u_q_addp function is identical to u_q_add SVI, except that it takes the 32-bit physical address of an element rather than an 80186 logical address.

    For Realtime Control Microcode Version 2.01 only, if the physical address passed to this routine resides within unallocated expanded memory, it is queued, but an invalid data (0x13) warning code is be returned.

    This routine does not enable interrupts.

    Returns:

    Function value =
            0x0000 = No errors
            0x0001 = Invalid entry parameter
            0x0011 = Physical address mapped but
                     unallocated (Realtime Control
                     Microcode Version 2.01 only)
            0x0012 = Address out of range
            0x0013 = Invalid data (32-bit address
                     exceeds physical memory amount)
            0x0016 = Invalid queue number (queue is
                     not allocated or queue number
                     is out of range)
            0x0200 = This is the first entry in
                     this queue
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char queue_no;
    unsigned long elemaddr;
    
    u_q_addp (queue_no, elemaddr);
    
    Related Topics:
         u_q_add, u_q_rcv, u_q_rem
    

    u_q_rcv

    Purpose:

    Gets the address of the first element of a user queue.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY u_q_rcv(queue_no, qelem);
    unsigned char queue_no;
    unsigned char far **qelem;
    
    Remarks:

    The u_q_rcv function gets a far (32-bit) pointer to the first queue element on the queue indicated by the queue_no parameter. The qelem parameter is used to pass back the address of the next queue element, which is not removed from the queue. With Realtime Control Microcode Version 2.01, if the first element is above base memory, u_q_rcv returns a warning error and the 32-bit physical address of the queue element. The task may then use the map_physpg SVI to map the queue element into the expanded memory page frame.

    This routine performs the same function as SVI 0x6A.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0012 = Queue element is above base memory
            0x0016 = Invalid queue number (queue
                     number is not allocated or
                     queue number is out of range)
            0x0100 = Queue is empty
    
    Example:
    #Include "icadeclt.h"
    
    unsigned char far *first_qelem;
    int error_code;
    
    error_code = u_q_rcv(7,&first;_qelem);
            /* Get ptr to next element of queue */
            /* 7 and store in "first_qelem"     */
    
    Related Topics:
         u_q_add, u_q_addp, u_q_rem
    

    u_q_rem

    Purpose:

    Removes the top element of a user queue.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY u_q_rem(queue_no,qelem);
    unsigned char queue_no;
    unsigned char far **qelem;
    
    Remarks:

    The u_q_rem function removes the head of the queue indicated by the queue_no parameter. The address of the queue element is returned by the qelem parameter. With Realtime Control Microcode Version 2.01, if the first element is above base memory, u_q_rcv returns a warning error and the 32-bit physical address of the queue element. The task may then use the map_physpg SVI to map the queue element into the expanded memory page frame.

    This routine performs the same function as SVI 0x6E.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0012 = Queue element is above base memory
            0x0016 = Invalid queue number
            0x0100 = Queue is empty
            0x0200 = No error, this was the last
                     element in the queue
            0x0212 = Last entry and queue element
                     is above base memory
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    unsigned char far *head_qelem;
    
    error_code = u_q_rem(6,&head;_qelem);
                 /* Get head element of queue 6 */
    
    Related Topics:
         u_q_addp, u_q_add, u_q_rcv
    

    writecio

    Purpose:

    Writes a value to the specified CIO port data register.

    Format:

    #Include "icadeclt.h"
    
    int ICAENTRY writecio(port,select,value);
    unsigned char port;
    unsigned char select;
    unsigned char value;
    
    Remarks:

    The writecio function writes to the data register of a CIO port. No check is made to ensure that the requestor is the owner of the port. No checks are made to ensure that a write is requested for an output bit. Data polarity resolution is the responsibility of the requestor. This routine should only be used for CIO ports, communication ports or SCC/CIO packages.

    The port parameter indicates which CIO data register to write:

       0 = CIO 0, Port A         12 = CIO 4, Port B
       1 = CIO 0, Port B         13 = CIO 4, Port C
       2 = CIO 1, Port A         14 = CIO 5, Port A
       3 = CIO 1, Port B         15 = CIO 5, Port B
       4 = CIO 1, Port C         16 = CIO 5, Port C
       5 = CIO 2, Port A         17 = CIO 6, Port A
       6 = CIO 2, Port B         18 = CIO 6, Port B
       7 = CIO 2, Port C         19 = CIO 6, Port C
       8 = CIO 3, Port A         20 = CIO 7, Port A
       9 = CIO 3, Port B         21 = CIO 7, Port B
      10 = CIO 3, Port C         22 = CIO 7, Port C
      11 = CIO 4, Port A
    
    The writecio function should be used when the CIO is allocated as a resource. It is normally used to interface with a special purpose electrical interface board; in this case, the bit definitions for the select and value parameters depend on the particular EIB. Although the CIO port data registers are often used in conjunction with an SCC for modem control, this function should not be used for setting modem controls.

    This routine performs the write function of the Read/Write CIO bits SVI.

    Returns:

    Function value =
            0x0000 = Normal completion; no error
            0x0005 = Access denied
            0x0018 = Invalid port number
    
    Example:
    #Include "icadeclt.h"
    
    int error_code;
    
    error_code = writecio (3, 0x000F, 0x0000);
          /* Writes CIO port 3 lower nibble only */
          /* all 0's.                            */
    
    Related Topics:
         readcio
    

    xmitcntl

    Purpose:

    Enables and disables the transmit function of a port.

    Format:

    #include "icadeclt.h"
    
    int ICAENTRY xmitcntl(port,request);
    unsigned char port;
    unsigned char request;
    
    Remarks:

    The xmitcntl function enables or disables the transmit function of the specified port. This routine should be used only for SCC/CIO packages, RS-232 ports, or RS-422 ports. It is the responsibility of the application to verify that the installed electrical interface board is appropriate for the service requested.

    This routine does not enable interrupts.

    The format of the request parameter is as follows:

            0x0000 = Disable
            0x0001 = Enable
    
    This routine performs the same function as the Transmit Control SVI.

    Returns:

    Function value =
            0x0000 = Normal completion; no errors
            0x0005 = Access denied (transmit control
                     not supported on port)
            0x0018 = Invalid port number
    
    Example:
    #include "icadeclt.h"
    
    int error_code;
    
    error_code = xmitcntl (2, 0x0001);
                     /* Request enable of port 2 */
                     /* transmit function.       */
    
    Related Topics:
         None
    

    Appendix A. Sample Programs

    The Realtime Interface Co-Processor C Language Support product provides two sample programs that can be used as a learning tool and as a means of verifying the Realtime Interface Co-Processor C Language Support software.


    Sample Program 1

    Sample program 1 is a demonstration program, in which the sample files consist of icacdemo.c, a C task that sends data to the system unit, and icacdisp.exe, a system unit program that displays the task's data.

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

    Microsoft C 6.0 Optimizing Compiler:
    
      cl /AM /G1 /Zp icacdemo.c /c
      link icaheadc+icacdemo/NOD /NOE,icacdemo,,icams60m+icatskm+mlibca;
    
    IBM C/2 1.1 Compiler:
    
      cc /AM /G1 /Zp icacdemo;
      link icaheadc+icacdemo/NOD /NOE,icacdemo,,icac2m+icatskm+mlibcar;
    
    The same compile and link options are used for C 7.0 and C 8.0 Microsoft C\C++.

    These two commands generate the executable task module, icacdemo.exe. Enter the following command to execute the sample task, substituting the desired hexadecimal values for and . The program icacdisp.exe loads the demo task on card <coproc> as task <tasknum>.

      icacdisp <coproc> <tasknum>
    
    The demonstration programs should then display the Realtime Control Microcode version number, the co-processor adapter memory size, and the interface board IDs on the screen. The following is an example of this display:
      Realtime Interface Co-Processor C Language Support
      Sample Program
    
      Realtime Control Microcode version = 1.51
      Co-processor adapter memory size = 256K
      Interface board 0 ID = C2
      Interface board 1 ID = C2
    
    If no interface board is installed, the ID byte has a value of 0xFF.

    Sample Program 2

    Sample program 2 shows how to build peer tasks. This example is contained in the files childxmp.c, childc.c, childsub.asm, childlib.asm, and childemo.exe.

    The first file, childxmp.c, contains the main body of the task source. The file childc.c contains two subroutines--BuildChild() and BuildPeer()--that build other tasks; they may be used and modified in user source. The file childsub.asm contains routines that should be copied for each task that is to be built; a unique copy of each of the three routines is needed for each child/peer task. The file childlib.asm contains subroutines for getting the size of the data area, calculating the correct stack pointer value, and copying the building task's data into the built task's data area; these routines are used by BuildChild() and BuildPeer(). The file childemo.exe contains the system unit program.

    The example may be compiled and linked with the following commands:

    Microsoft C 6.0 Optimizing Compiler:
    
      cl /AM /Zp /Ze /Gs /G1 childxmp.c /c
      masm childlib;
      masm childsub;
      link icaheadc+childxmp+childsub+childlib/NOD /NOE,childxmp,,
          icams60m+icatskm+mlibca;
    
    IBM C/2 1.1 Compiler:
    
      cc /AM /Gs /G1 childxmp;
      masm childlib;
      masm childsub;
      link icaheadc+childxmp+childsub+childlib/NOD /NOE,childxmp,,
          icac2m+icatskm+mlibcar;
    
    The same compile and link options are used for C 7.0 and C 8.0 Microsoft C\C++.

    The resultant file (childxmp.exe) builds a peer task with a task number one greater than its own and waits for a post from the built task. When the post is received, it stores the string "Peer built, post received" in its input buffer.

    In the example, a second copy of the building task's data area was created. The code area was shared by the building task and the built task. This feature is useful for tasks that run the same code but require separate data areas.

    To run the example, enter the following commands:

         icainth
         icaload 0 icaaim.com 0
         childemo 0 1
    

    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, X.25 Interface Co-Processor, Realtime Interface Co-Processor Portmaster Adapter/A, or Realtime Interface Co-Processor Multiport Adapter, Model 2

    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