home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / utils / amd-udi / udi / dos386c.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  48.9 KB  |  1,786 lines

  1. /******************************************************************************
  2.  * Copyright 1991 Advanced Micro Devices, Inc.
  3.  *
  4.  * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
  5.  * specifically  grants the user the right to modify, use and distribute this
  6.  * software provided this notice is not removed or altered.  All other rights
  7.  * are reserved by AMD.
  8.  *
  9.  * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
  10.  * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
  11.  * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
  12.  * USE OF THIS SOFTWARE.
  13.  *
  14.  * Comments about this software should be directed to udi@amd.com. If access
  15.  * to electronic mail isn't available, send mail to:
  16.  *
  17.  * Advanced Micro Devices, Inc.
  18.  * 29K Support Products
  19.  * Mail Stop 573
  20.  * 5900 E. Ben White Blvd.
  21.  * Austin, TX 78741
  22.  *****************************************************************************
  23.  *       $Id: dos386c.c,v 1.2 1993/12/23 04:44:41 cassidy Exp $
  24.  *       $Id: @(#)dos386c.c    1.9, AMD
  25.  */
  26.  
  27. /* DOS386 specific constructs and functions.  These assume the use of
  28.  * the 386|DOS-Extender from Pharlap.
  29.  *
  30.  * This file contains functions which serve as an intermediate between
  31.  * protected mode UDI function calls made by the DFE and the possibly
  32.  * real-mode function called in the TIP.  These functions assume that
  33.  * the interface between the TIP and the DFE is real-mode and that the
  34.  * DFE is protected mode, flat model (32 bit linear addresses).
  35.  *
  36.  * Note:
  37.  * This code allocates a section of real-mode memory using
  38.  * a call to _dx_real_alloc.  Protected mode far pointers (48-bit)
  39.  * must be used to access this memory area.
  40.  *
  41.  * For every UDI function named UDIx..x, there is a function in this
  42.  * module named UDIPx..x, where the "P" indicates that this is a protected
  43.  * mode interface function.  A protected mode DFE needs to call the
  44.  * UDIPx..x equivalent of the call to the TIP UDI function.  The call
  45.  * parameters are the same as the UDI call except that the address of the
  46.  * TIP UDI function is always the first parameter to the UDIPx..x 
  47.  * function.
  48.  *
  49.  * Each function follows the format outlined below:
  50.  *
  51.  * UDIError UDIPx..x(REALPTR function_address [, UDI function parameters])
  52.  * {
  53.  *     Allocate pointers into the conventional memory area used for
  54.  *        parameter passing (PPM) for all parameters which are
  55.  *        passed-by-reference.  Each of these pointers is given
  56.  *        the same name as a parameter with "Ptr" appended to it.
  57.  *
  58.  *    Create a packed structure for parameter passing if there is more
  59.  *        than one parameter to the function.  Each member of this
  60.  *        structure (always named params) has the same name as the
  61.  *        corresponding parameter to the UDIP... call.
  62.  *
  63.  *    Set the parameter pointers to the appropriate offsets in the PPM.
  64.  *        The protected mode pointer to the first parameter is always
  65.  *        rm_address (the real mode equivalent to this pointer is
  66.  *        rm_buffer_addr).
  67.  *
  68.  *    Copy the data from protected mode (possibly extended) memory to
  69.  *        the location indicated by the correct pointer 
  70.  *
  71.  *    Copy the passed-by-value parameters directly into the params
  72.  *        structure.  Convert the protected mode version of the
  73.  *        pointers into the PPM area to real-mode pointers and
  74.  *        assign them to their corresponding params data member.
  75.  *
  76.  *    Call the real-mode function, pushing the params structure onto 
  77.  *        the stack.  Generally this involves the use of the macro
  78.  *        REALCALL, however functions with no parameters call 
  79.  *        _dx_call_real explicitly.  The size of the params structure
  80.  *        is determined by the macro WORDSIZE.
  81.  *
  82.  *    Check for an error returned from _dx_call_real.  If there is one
  83.  *        report it and die (how uncouth!).
  84.  *
  85.  *    Copy all "out" parameters into their local (non-conventional 
  86.  *        memory eqivalents.  In functions with "count" parameters,
  87.  *        make sure that the count value makes sense and only 
  88.  *        copy as much as is allowed by the buffer size.
  89.  *    
  90.  *    The return value of the UDI TIP function is in the ax register of
  91.  *        the regs structure, return this as the value of the UDIP
  92.  *        function.
  93.  * }
  94.  *
  95.  *
  96.  * UDIPRead, UDIPWrite, UDIPPutStdOut, UDIPGetStdOut, 
  97.  * UDIPGetStderr, UDIPPutTrans and UDIPGetTrans differ from the other
  98.  * UDIP functions in that they allow looping within the UDIP layer
  99.  * call to the TIP.  This looping is done so that the size of the
  100.  * real mode buffer area does not limit the size of the data transfer
  101.  * since all data passed by reference *must* be copied into the real
  102.  * mode buffer area and the TIP can only return as much information
  103.  * as can fit in this real mode buffer (unlike the situation for a 
  104.  * real mode DFE where the DFE and the TIP write to the same memory).
  105.  *
  106.  * The calls all use the same logic, outlined below:
  107.  *
  108.  *
  109.  * Set the CurrentCount equal to the total number of items to 
  110.  * be transfered (CurrentCount = *Count).
  111.  *
  112.  * Set the total number of items transfered so far to zero (TotalDone = 0)
  113.  *
  114.  * Set up moving pointers into the From and To transfer areas to keep
  115.  * track of where the current transfer should be read and/or written.
  116.  * (CurrentTo = To; CurrentFrom = From)
  117.  *
  118.  * do 
  119.  *    Set a pointer to the end of the memory that would be required
  120.  *    to do the complete transfer.
  121.  *
  122.  *    If the pointer is outside of the buffer area (determined by
  123.  *    call the BufferSizeCheck), then we need to adjust the
  124.  *    size of the requested transfer.
  125.  *
  126.  *       Set the pointer to the last item to the last valid location
  127.  *       in the real mode buffer area.
  128.  *
  129.  *       Set the value of CurrentCount to the maximum number of data
  130.  *       items that can be transfered, based on the Size parameter.
  131.  *
  132.  *    Call the TIP function with CurrentCount instead of *Count,
  133.  *    CurrentTo instead of To and CurrentFrom instead of From.
  134.  *
  135.  *    Set the CurrentDone equal to the CountDone returned by the
  136.  *    function call.
  137.  *
  138.  *    Update the pointers into the From and To transfer areas to the
  139.  *    end of the just completed transfer (CurrentFrom += CurrentDone
  140.  *    * Size, CurrentTo += CurrentDone * Size)
  141.  *
  142.  *    Increment the TotalDone by the number of items transfered in
  143.  *    the last call (TotalDone += CurrentDone)
  144.  *
  145.  * while transfer is not complete (TotalDone < *Count)
  146.  *
  147.  */
  148.  
  149.  
  150.  
  151. #define _DOS386C_C
  152.  
  153. #include <dos.h>
  154. #include <process.h>
  155. #include <stdio.h>
  156. #include <string.h>
  157. #include <stdlib.h>
  158. #include <ctype.h>
  159. #include <udiproc.h>
  160.  
  161. #include <pharlap.h>
  162. #include <udidos.h>
  163. #include <stdarg.h>
  164.  
  165.  
  166. #include <dos386c.h>
  167.  
  168.  
  169. #define REAL_BUFFER_SIZE 0x1000
  170. #define PRINT_ON  1
  171. #define PRINT_OFF 0
  172.  
  173. #define WORDSIZE(param) ((sizeof(param)/2) + (sizeof(param) %2))
  174.  
  175. #define REALCALL(x,y) _dx_call_real(x, &real_regs, WORDSIZE(y), y)
  176.  
  177. #define FUNC_VAL ((UDIError) real_regs.eax)
  178.  
  179. #define SIZE_ERROR(Done, Size, function_name) printf("Return size (%d) > Buffer size (%d) in function %s\n",Done,Size,function_name)
  180.  
  181. /*
  182.  * 4/93 MDT
  183.  * The following defines are used to allow UDI 1.2 functions to identify
  184.  * themselves to the compiler and the user when UDI 1.3 is defined.  These
  185.  * are needed to differentiate the 1.2 versions of some functions (UDIPConnect)
  186.  * from their 1.3 versions.
  187.  */
  188. #if defined __STDC__ || defined _MSC_VER
  189. #define XCAT(a,b) a##b
  190. #else
  191. #define XCAT(a,b) a/**/b
  192. #endif
  193.  
  194. #ifdef UDI13 
  195.  
  196. #define UDI12FUNCVER _12
  197. #define UDI12FUNCVERSTR " (1.2)"
  198. #define CAT(a,b) XCAT(a,b)
  199.  
  200. #else /* not UDI 1.3 */
  201.  
  202. #define UDI12FUNCVER dummy    /* Have to pass two arguments to CAT */ 
  203. #define UDI12FUNCVERSTR ""
  204. #define CAT(a,b) a        /* Don't actually want to concatenate anything */
  205.  
  206. #endif /* UDI 1.3 */
  207.  
  208.  
  209. /* Needed by call to _dx_real_call, but no values need to be set
  210.  * since TIP is compiled assuming it doesn't know anything about the
  211.  * values in the registers.
  212.  */
  213. RMC_BLK  real_regs;    
  214.  
  215.  
  216.  
  217. /* Pointers to use for handling conventional memory buffer area.  This
  218.  * area is used to pass parameters to and from real-mode procedures.
  219.  */
  220. REALPTR    rm_buffer_addr;        /* real-mode pointer to parameter buffer area.     */
  221. ULONG        rm_buffer_size;        /* size of paramter buffer area.                   */
  222.  
  223. USHORT _far    *rm_address;        /* pointer to paramter buffer area.                */
  224. USHORT _far    *rm_end_address;    /* the last valid address of the parameter buffer  */
  225.  
  226.  
  227. int        buffer_allocated=0;    /* used to denote that the status of the buffer    */
  228.  
  229.  
  230.  
  231.  
  232. REALPTR PROT_TO_REAL(FARPTR p)        /* converts a PROT ptr to a REALPTR */
  233. {
  234. REALPTR  dummyrp;
  235. FARPTR   dummyfp;
  236. int   err;
  237.  
  238.     /* returns a real mode pointer given a prot mode pointer p */
  239.  
  240. //    FP_SET(dummyfp,p,data_selector);
  241.     dummyfp = p;
  242.     err = _dx_toreal(dummyfp, 0, &dummyrp);
  243.     if (err) {
  244.        printf("Fatal Error _dx_toreal (0x%lX)\n", (ULONG) p);
  245.        exit(err);
  246.     }
  247.     return(dummyrp);
  248.     
  249. } /* PROT_TO_REAL */
  250.  
  251.  
  252.  
  253. FARPTR REAL_TO_PROT(REALPTR rp)  /* converts a REALPTR to a FARPTR */
  254. {
  255. FARPTR    dummyfp;
  256.  
  257.     FP_SET(dummyfp,LINEARIZE(rp),SS_DOSMEM);
  258.     return (dummyfp); 
  259.  
  260. } /* REAL_TO_PROT */
  261.  
  262.  
  263.  
  264. FARPTR NEARPTR_TO_FARPTR(void *ptr)
  265. /* Convert a near (32 bit linear) pointer to a far (48 bit) pointer. */
  266. {
  267.     FARPTR dummyfptr;
  268.  
  269.     FP_SET(dummyfptr, ptr, data_selector);
  270.  
  271.     return(dummyfptr);
  272.  
  273. } /* NEARPTR_TO_FARPTR() */
  274.  
  275.  
  276. long BufferSizeCheck(FARPTR ptr, char *function_name, int print_message)
  277. /* Check passed ptr to make sure that it points to a valid location in
  278.  * the real-mode parameter passing buffer.  If not, just report an
  279.  * error for now.
  280.  */
  281. {
  282.     if ((long)ptr < (long)rm_address) {
  283.         printf("Invalid address for real mode parameters in function: %s\n",function_name);
  284.         exit(1);
  285.     }
  286.     if ((long)ptr > (long)rm_end_address) {
  287.         if (print_message) {
  288.             printf("Parameters too large for passing to real mode in function: %s\n",function_name);
  289.             printf("Value of ptr - rm_end_address:%ld\n",(long)(ptr - (FARPTR)rm_end_address));
  290.         }
  291.         return (long)((long)ptr - (long)rm_end_address);
  292.     }
  293.  
  294.     return 0;    /* passed the size check */
  295.  
  296. } /* BufferSizeCheck() */
  297.  
  298.  
  299. void CheckRealError(int Err, char *func_name) {
  300.  
  301.     if (Err) {
  302.         printf("DOS386 real mode call error: %s\n",func_name);
  303.         exit(1);
  304.     } /* if */
  305.  
  306. } /* CheckRealError() */
  307.  
  308.  
  309.  
  310.  
  311. UDIError CAT(UDIPConnect,UDI12FUNCVER)(
  312.             REALPTR UDIConnectAddr, 
  313.             char *Configuration,        /* In  */
  314.             UDISessionId *Session,        /* Out */
  315.             DOSTerm _far *TermStruct)    /* In  */
  316. {
  317.     int            err;
  318.     UDISessionId _far    *SessionPtr;
  319.     UDIError         ConnectErr;
  320.     USHORT            rm_seg,rm_size;
  321.  
  322.     _Packed struct {
  323.         REALPTR        Configuration;
  324.         REALPTR      Session;
  325.         REALPTR        TermStruct;
  326.     } params;
  327.  
  328.  
  329.     if (!buffer_allocated) {
  330.         /* Need to get address of conventional memory area for passing parameters.
  331.          * This will set it for future use everywhere, not just in this function. 
  332.          * rm_address is the protected (32 bit) pointer to the real mode parameter.
  333.          * passing area.  rm_buffer_addr is the real mode pointer to the same buffer.
  334.          */
  335.         err = _dx_real_alloc(REAL_BUFFER_SIZE,&rm_seg,&rm_size);
  336.  
  337.         if (err) {
  338.             printf("Unable to allocate real-mode parameter transfer area (_dx_real_alloc)\n");
  339.             exit(0);
  340.         }
  341.         /* rm_seg is the real mode paragraph (segment).
  342.          * Build rm_buffer_addr to be the full real mode pointer (seg:ofst)
  343.          */
  344.         RP_SET(rm_buffer_addr, 0, rm_seg);
  345.         /*
  346.          * rm_address will be the protected pointer to that same buffer
  347.          */
  348.         rm_address       = (USHORT _far *)REAL_TO_PROT(rm_buffer_addr);
  349.         rm_end_address   = (USHORT _far *) (((char _far *)rm_address) + REAL_BUFFER_SIZE*16);
  350.         buffer_allocated = 1;
  351.     }
  352.     
  353.     
  354.     /* Get pointers to locations where passed by reference parameters 
  355.      * will be stored in the parameter passing buffer area.  The first
  356.      * parameter is always at rm_buffer (= rm_buffer_addr in real mode).
  357.      */
  358.  
  359.     /* NOTE: see comments under UDIPDisconnect for explanation of why
  360.      * we don't copy TermStruct even though it's an in parameter.
  361.      */
  362.     SessionPtr = (UDISessionId _far *)((char _far *)rm_address + strlen(Configuration)+1);
  363.                        
  364.     if (BufferSizeCheck((FARPTR)(SessionPtr + sizeof(UDISessionId)),"UDIPConnect" UDI12FUNCVERSTR,PRINT_ON)) {
  365.         return UDIErrorIPCInternal;
  366.     } /* if */
  367.  
  368.     /* Move input parameters which are passed by reference into paramter buffer area. */
  369.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(Configuration),strlen(Configuration)+1);
  370.     _fmemmove(SessionPtr,NEARPTR_TO_FARPTR(Session),sizeof(UDISessionId));
  371.  
  372.  
  373.     /* Put actual parameters into packed structure for passing to real
  374.      * mode function.
  375.      */
  376.     params.Configuration = rm_buffer_addr;
  377.     params.Session       = PROT_TO_REAL((FARPTR) SessionPtr);
  378.     params.TermStruct    = PROT_TO_REAL((FARPTR)TermStruct);
  379.  
  380.  
  381.     /* Call the real-mode function with the address of the function,
  382.      * the number of bytes in the packed structure and the address of
  383.      * the structure.
  384.      */
  385.  
  386.     ConnectErr = REALCALL(UDIConnectAddr,params);
  387.  
  388.     CheckRealError(ConnectErr,"UDIConnect" UDI12FUNCVERSTR);
  389.  
  390.     /* Copy output parameters from parameter passing area back to protected space
  391.      */
  392.     _fmemmove(NEARPTR_TO_FARPTR(Session),SessionPtr,sizeof(UDISessionId));
  393.  
  394.  
  395.     return FUNC_VAL;
  396.  
  397.  
  398. } /* UDIPConnect (UDI 1.2) */
  399.  
  400.  
  401. #ifdef UDI13
  402.  
  403. /* 4/93 MDT - This function is needed only for UDI 1.3 and greater 
  404.  *            implementations.  This code should be checked when the
  405.  *            final specification for UDI 1.3 becomes available.
  406.  */
  407.  
  408. UDIError UDIPConnect_13(
  409.     REALPTR     UDIConnectAddr, 
  410.     char        *Configuration,     /* In  */
  411.     UDISessionId    *Session,         /* Out */
  412.     DOSTerm     *TermStruct,        /* In  */
  413.     UDIUInt32    DFEIPCId,        /* In  1.3 */
  414.     UDIUInt32    *TIPIPCId,        /* Out 1.3 */
  415.     struct UDIDFEVecRec *DFEVecRec        /* In  1.3 */
  416.     )
  417. {
  418.     int            err;
  419.     UDISessionId _far    *SessionPtr;
  420.     UDIUInt32 _far        *TIPIPCIdPtr;
  421.     UDIError         ConnectErr;
  422.     USHORT            rm_seg,rm_size;
  423.  
  424.     _Packed struct {
  425.         REALPTR        Configuration;
  426.         REALPTR      Session;
  427.         REALPTR        TermStruct;
  428.         UDIUInt32    DFEIPCId;
  429.         REALPTR        TIPIPCId;
  430.         REALPTR        DFEVecRec;
  431.     } params;
  432.  
  433.     
  434.     if (!buffer_allocated) {
  435.         /* Need to get address of conventional memory area for passing parameters.
  436.          * This will set it for future use everywhere, not just in this function. 
  437.          * rm_address is the protected (32 bit) pointer to the real mode parameter.
  438.          * passing area.  rm_buffer_addr is the real mode pointer to the same buffer.
  439.          */
  440.         err = _dx_real_alloc(REAL_BUFFER_SIZE,&rm_seg,&rm_size);
  441.         if (err) {
  442.             printf("Unable to allocate real-mode parameter transfer area (_dx_real_alloc)\n");
  443.             exit(0);
  444.         }
  445.         /* rm_seg is the real mode paragraph (segment).
  446.          * Build rm_buffer_addr to be the full real mode pointer (seg:ofst)
  447.          */
  448.         RP_SET(rm_buffer_addr, 0, rm_seg);
  449.         /*
  450.          * rm_address will be the protected pointer to that same buffer
  451.          */
  452.         rm_address       = REAL_TO_PROT(rm_buffer_addr);
  453.         rm_end_address   = (USHORT *) (((char *)rm_address) + REAL_BUFFER_SIZE*16);
  454.         buffer_allocated = 1;
  455.     }
  456.     
  457.     
  458.     /* Get pointers to locations where passed by reference parameters 
  459.      * will be stored in the parameter passing buffer area.  The first
  460.      * parameter is always at rm_buffer (= rm_buffer_addr in real mode).
  461.      */
  462.  
  463.     /* NOTE: see comments under UDIPDisconnect for explanation of why
  464.      * we don't copy TermStruct even though it's an in parameter.
  465.      */
  466.     SessionPtr = (UDISessionId _far *)((char _far *)rm_address + strlen(Configuration)+1);
  467.     TIPIPCIdPtr = (UDIUInt32 _far *) (SessionPtr + sizeof(UDISessionId));
  468.     
  469.     if (BufferSizeCheck((FARPTR)(TIPIPCIdPtr + sizeof(UDIUInt32)),"UDIPConnect (1.3)")) {
  470.         return UDIErrorIPCInternal;
  471.     }
  472.  
  473.     /* Move input parameters which are passed by reference into paramter buffer area. */
  474.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(Configuration),strlen(Configuration)+1);
  475.  
  476.     /* Put actual parameters into packed structure for passing to real
  477.      * mode function.
  478.      */
  479.     params.Configuration = rm_buffer_addr;
  480.     params.Session       = PROT_TO_REAL((FARPTR)SessionPtr);
  481.     params.TermStruct    = PROT_TO_REAL((FARPTR)TermStruct);
  482.     params.DFEIPCId         = DFEIPCId;
  483.     params.TIPIPCId         = PROT_TO_REAL(TIPIPCIdPtr);
  484.     params.DFEVecRec     = PROT_TO_REAL((FARPTR)DFEVecRec);
  485.  
  486.  
  487.     /* Call the real-mode function with the address of the function,
  488.      * the number of bytes in the packed structure and the address of
  489.      * the structure.
  490.      */
  491.  
  492.     ConnectErr = REALCALL(UDIConnectAddr,params);
  493.  
  494.     CheckRealError(ConnectErr,"UDIConnect (1.3)");
  495.  
  496.     /* Copy output parameters from parameter passing area back to protected space
  497.      */
  498.     _fmemmove(NEARPTR_TO_FARPTR(Session),SessionPtr,sizeof(UDISessionId));
  499.     _fmemmove(NEARPTR_TO_FARPTR(TIPIPCId),TIPIPCIdPtr,sizeof(UDIUInt32));
  500.  
  501.     return FUNC_VAL;
  502.  
  503.  
  504. } /* UDIPConnect_13 */
  505.  
  506. #endif /* UDI13 */
  507.  
  508.  
  509. #define TIPSTRLEN 80
  510.  
  511.  
  512. UDIError CAT(UDIPCapabilities,UDI12FUNCVER) (
  513.     REALPTR        UDICapabilitiesAddr,
  514.     UDIUInt32    *TIPId,            /* Out */
  515.     UDIUInt32    *TargetId,        /* Out */
  516.     UDIUInt32    DFEId,            /* In */
  517.     UDIUInt32    DFE,            /* In */
  518.     UDIUInt32    *TIP,            /* Out */
  519.     UDIUInt32    *DFEIPCId,        /* Out */
  520.     UDIUInt32    *TIPIPCId,        /* Out */
  521.     char        *TIPString        /* Out */
  522.       )
  523. {
  524.     UDIUInt32 _far    *TargetIdPtr;
  525.     UDIUInt32 _far    *TIPPtr;
  526.     UDIUInt32 _far    *DFEIPCIdPtr;
  527.     UDIUInt32 _far    *TIPIPCIdPtr;
  528.     UDIUInt32 _far    *TIPStringPtr;
  529.     UDIUInt32 _far    *endPtr;
  530.     UDIError     Err;
  531.  
  532.     /* Structure for passing parameters to real mode function in TIP */
  533.     _Packed struct {
  534.         REALPTR        TIPId;
  535.         REALPTR        TargetId;
  536.         UDIUInt32    DFEId;
  537.         UDIUInt32    DFE;
  538.         REALPTR        TIP;
  539.         REALPTR        DFEIPCId;
  540.         REALPTR        TIPIPCId;
  541.         REALPTR        TIPString;
  542.     } params;
  543.  
  544.  
  545.     /* Get pointers to locations where passed by reference parameters 
  546.      * will be stored in the parameter passing buffer area.  The first
  547.      * parameter is always at rm_address.
  548.      */
  549.  
  550.     TargetIdPtr = (UDIUInt32 _far *)((char _far *)rm_address + sizeof(UDIUInt32));
  551.     TIPPtr = TargetIdPtr + sizeof(UDIUInt32);
  552.     DFEIPCIdPtr = TIPPtr + sizeof(UDIUInt32);
  553.     TIPIPCIdPtr = DFEIPCIdPtr + sizeof(UDIUInt32);
  554.     TIPStringPtr = TIPIPCIdPtr + sizeof(UDIInt32);
  555.     endPtr = TIPStringPtr + TIPSTRLEN;
  556.  
  557.     if (BufferSizeCheck((FARPTR)endPtr,"UDICapabilities" UDI12FUNCVERSTR,PRINT_ON)) {
  558.         return UDIErrorIPCLimitation;        
  559.     } /* if */
  560.     
  561.     /* Move parameters into paramter buffer area. */
  562.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(TIPId),sizeof(UDIUInt32));     
  563.     _fmemmove(TargetIdPtr,NEARPTR_TO_FARPTR(TargetId),sizeof(UDIUInt32));
  564.     _fmemmove(TIPPtr,NEARPTR_TO_FARPTR(TIP),sizeof(UDIUInt32));
  565.     _fmemmove(DFEIPCIdPtr,NEARPTR_TO_FARPTR(DFEIPCId),sizeof(UDIUInt32));
  566.     _fmemmove(TIPIPCIdPtr,NEARPTR_TO_FARPTR(TIPIPCId),sizeof(UDIInt32));
  567.     _fmemmove(TIPStringPtr,NEARPTR_TO_FARPTR(TIPString),TIPSTRLEN);
  568.  
  569.  
  570.     params.TIPId = rm_buffer_addr;
  571.     params.TargetId = PROT_TO_REAL((FARPTR)TargetIdPtr);
  572.     params.DFEId = DFEId;
  573.     params.DFE = DFE;
  574.     params.TIP = PROT_TO_REAL((FARPTR)TIPPtr);
  575.     params.DFEIPCId = PROT_TO_REAL((FARPTR)DFEIPCIdPtr);
  576.     params.TIPIPCId = PROT_TO_REAL((FARPTR)TIPIPCIdPtr);
  577.     params.TIPString = PROT_TO_REAL((FARPTR)TIPStringPtr);
  578.  
  579.  
  580.     Err = REALCALL(UDICapabilitiesAddr,params);
  581.  
  582.     CheckRealError(Err,"UDICapabilities" UDI12FUNCVERSTR);
  583.  
  584.     _fmemmove(NEARPTR_TO_FARPTR(TargetId),TargetIdPtr,sizeof(UDIUInt32));
  585.     _fmemmove(NEARPTR_TO_FARPTR(TIP),TIPPtr,sizeof(UDIUInt32));
  586.     _fmemmove(NEARPTR_TO_FARPTR(DFEIPCId),DFEIPCIdPtr,sizeof(UDIUInt32));
  587.     _fmemmove(NEARPTR_TO_FARPTR(TIPIPCId),TIPIPCIdPtr,sizeof(UDIInt32));
  588.     _fmemmove(NEARPTR_TO_FARPTR(TIPString),TIPStringPtr,TIPSTRLEN);
  589.     _fmemmove(NEARPTR_TO_FARPTR(TIPId),(UDIUInt32 _far *)rm_address,sizeof(UDIUInt32));
  590.  
  591.     return FUNC_VAL;
  592.  
  593. }  /* UDIPCapabilities() */
  594.  
  595.  
  596.  
  597. #ifdef UDI13
  598.  
  599. /* UDI 1.3 version of UDIPCapabilities */
  600. UDIError UDIPCapabilities_13 (
  601.     REALPTR        UDICapabilitiesAddr,
  602.     UDIUInt32    *TIPId,            /* Out */
  603.     UDIUInt32    *TargetId,        /* Out */
  604.     UDIUInt32    DFEId,            /* In */
  605.     UDIUInt32    DFE,            /* In */
  606.     UDIUInt32    *TIP,            /* Out */
  607.     UDIUInt32    *DFEIPCId,        /* Out */
  608.     UDIUInt32    *TIPIPCId,        /* Out */
  609.     char        *TIPString,        /* Out */
  610.     UDISizeT    BufSize,        /* In  1.3 */
  611.     UDISizeT    *CountDone,        /* Out 1.3 */
  612.     UDISessionId    connection_id
  613.       )
  614. {
  615.     UDIUInt32 _far    *TargetIdPtr;
  616.     UDIUInt32 _far    *TIPPtr;
  617.     UDIUInt32 _far    *DFEIPCIdPtr;
  618.     UDIUInt32 _far    *TIPIPCIdPtr;
  619.     UDIUInt32 _far    *TIPStringPtr;
  620.     UDIUInt32 _far    *endPtr;
  621.     UDISizeT    *CountDonePtr;
  622.     UDIError     ConnectErr;
  623.  
  624.     /* Structure for passing parameters to real mode function in TIP */
  625.     _Packed struct {
  626.         REALPTR        TIPId;
  627.         REALPTR        TargetId;
  628.         UDIUInt32    DFEId;
  629.         UDIUInt32    DFE;
  630.         REALPTR        TIP;
  631.         REALPTR        DFEIPCId;
  632.         REALPTR        TIPIPCId;
  633.         REALPTR        TIPString;
  634.         UDISizeT    BufSize;
  635.         REALPTR        CountDone;
  636.         UDISessionId    connection_id;
  637.     } params;
  638.  
  639.  
  640.     /* Get pointers to locations where passed by reference parameters 
  641.      * will be stored in the parameter passing buffer area.  The first
  642.      * parameter is always at rm_address.
  643.      */
  644.  
  645.     TargetIdPtr  = (UDIUInt32 _far *)((char _far *)rm_address + sizeof(UDIUInt32));
  646.     TIPPtr       = TargetIdPtr + sizeof(UDIUInt32);
  647.     DFEIPCIdPtr  = TIPPtr + sizeof(UDIUInt32);
  648.     TIPIPCIdPtr  = DFEIPCIdPtr + sizeof(UDIUInt32);
  649.     TIPStringPtr = TIPIPCIdPtr + sizeof(UDIInt32);
  650.     CountDonePtr = (UDISizeT _far *) (TIPStringPtr + strlen(TIPString) + 1);
  651.     endPtr       = (UDIUInt32 _far *) (CountDonePtr + sizeof(UDISizeT));
  652.  
  653.     if (BufferSizeCheck((FARPTR)endPtr,"UDICapabilities (1.3)",PRINT_ON) {
  654.         return UDIErrorIPCLimitation;
  655.     } /* if */
  656.  
  657.     
  658.     /* Move parameters into paramter buffer area. */
  659.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(TIPId),sizeof(UDIUInt32));            /* TIPId */
  660.     _fmemmove(TargetIdPtr, NEARPTR_TO_FARPTR(TargetId),sizeof(UDIUInt32));
  661.     _fmemmove(TIPPtr, NEARPTR_TO_FARPTR(TIP),sizeof(UDIUInt32));
  662.     _fmemmove(DFEIPCIdPtr, NEARPTR_TO_FARPTR(DFEIPCId),sizeof(UDIUInt32));
  663.     _fmemmove(TIPIPCIdPtr, NEARPTR_TO_FARPTR(TIPIPCId),sizeof(UDIInt32));
  664.     _fmemmove(TIPStringPtr, NEARPTR_TO_FARPTR(TIPString),strlen(TIPString)+1);
  665.     _fmemmove(CountDonePtr, NEARPTR_TO_FARPTR(CountDone),sizeof(UDISizeT));
  666.  
  667.  
  668.     params.TIPId         = rm_buffer_addr;
  669.     params.TargetId      = PROT_TO_REAL((FARPTR)TargetIdPtr);
  670.     params.DFEId         = DFEId;
  671.     params.DFE           = DFE;
  672.     params.TIP           = PROT_TO_REAL((FARPTR)TIPPtr);
  673.     params.DFEIPCId      = PROT_TO_REAL((FARPTR)DFEIPCIdPtr);
  674.     params.TIPIPCId      = PROT_TO_REAL((FARPTR)TIPIPCIdPtr);
  675.     params.TIPString     = PROT_TO_REAL((FARPTR)TIPStringPtr);
  676.     params.BufSize         = BufSize;
  677.     params.CountDone     = PROT_TO_REAL((FARPTR)CountDonePtr);
  678.     params.connection_id = connection_id;
  679.  
  680.  
  681.     ConnectErr = REALCALL(UDICapabilitiesAddr,params);
  682.  
  683.     CheckRealError(ConnectErr,"UDICapabilities (1.3)");
  684.  
  685.  
  686.     _fmemmove(NEARPTR_TO_FARPTR(TIPId),     rm_address,   sizeof(UDIUInt32));
  687.     _fmemmove(NEARPTR_TO_FARPTR(TargetId),  TargetIdPtr,  sizeof(UDIUInt32));
  688.     _fmemmove(NEARPTR_TO_FARPTR(TIP),       TIPPtr,       sizeof(UDIUInt32));
  689.     _fmemmove(NEARPTR_TO_FARPTR(DFEIPCId),  DFEIPCIdPtr,  sizeof(UDIUInt32));
  690.     _fmemmove(NEARPTR_TO_FARPTR(TIPIPCId),  TIPIPCIdPtr,  sizeof(UDIInt32));
  691.     _fmemmove(NEARPTR_TO_FARPTR(TIPString), TIPStringPtr, strlen(TIPString)+1);
  692.     _fmemmove(NEARPTR_TO_FARPTR(CountDone), CountDonePtr, sizeof(CountDone));
  693.  
  694.     if (*CountDone <= BufSize)
  695.         _fmemmove(NEARPTR_TO_FARPTR(TIPString),TIPStringPtr,*CountDone);
  696.     else {
  697.         _fmemmove(NEARPTR_TO_FARPTR(TIPString),TIPStringPtr,BufSize);
  698.         SIZE_ERROR(*CountDone, BufSize, "UDIPCapabilities (1.3)");
  699.     }
  700.  
  701.  
  702.  
  703.     return FUNC_VAL;
  704.  
  705. }  /* UDIPCapabilities_13() */
  706.  
  707. #endif /* UDI13 */
  708.  
  709.  
  710. UDIError UDIPGetErrorMsg(
  711.     REALPTR        UDIGetErrorMessageAddr,
  712.     UDIError    ErrorCode,        /* In  */
  713.     UDISizeT    MsgSize,        /* In  */
  714.     char        *Msg,            /* Out */
  715.     UDISizeT    *CountDone        /* Out */
  716.     )
  717. {
  718.     UDIError    Err;
  719.     UDISizeT _far    *CountDonePtr;
  720.     long        Buffer_Adjustment;
  721.  
  722.     _Packed struct {
  723.         UDIError    ErrorCode;
  724.         UDISizeT    MsgSize;
  725.         REALPTR        Msg;
  726.         REALPTR        CountDone;
  727.     } params;
  728.  
  729.  
  730.     CountDonePtr = (UDISizeT _far *)(rm_address + MsgSize);
  731.  
  732.     if ((Buffer_Adjustment = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDISizeT)),"UDIPGetErrorMsg",PRINT_ON))) {
  733.         if (MsgSize <= Buffer_Adjustment)
  734.             return UDIErrorIPCLimitation;
  735.         MsgSize -= Buffer_Adjustment;
  736.     } /* if */
  737.  
  738.     /* Don't need to copy anything into the real mode parameter 
  739.      * buffer area for this call since there are no pointer "in"
  740.      * parameters.                     
  741.      */
  742.  
  743.     params.ErrorCode = ErrorCode;
  744.     params.MsgSize   = MsgSize;
  745.     params.Msg       = rm_buffer_addr;
  746.     params.CountDone = PROT_TO_REAL((FARPTR)CountDonePtr);
  747.  
  748.     Err = REALCALL(UDIGetErrorMessageAddr,params);
  749.  
  750.     CheckRealError(Err,"UDIGetErrorMessage");
  751.  
  752.     _fmemmove(NEARPTR_TO_FARPTR(CountDone),CountDonePtr,sizeof(UDISizeT));
  753.     if (*CountDone <= MsgSize)
  754.         _fmemmove(NEARPTR_TO_FARPTR(Msg),rm_address,*CountDone);
  755.     else {
  756.         _fmemmove(NEARPTR_TO_FARPTR(Msg),rm_address,MsgSize);
  757.         SIZE_ERROR(*CountDone, MsgSize, "UDIPGetErrorMessage");
  758.     }
  759.     
  760.     return FUNC_VAL;
  761.  
  762. } /* UDIPGetErrorMessage */
  763.  
  764.  
  765.  
  766. UDIError UDIPSetCurrentConnection(
  767.     REALPTR        UDISetCurrentConnectionAddr,
  768.     UDISessionId    Session            /* In  */
  769.     )
  770. {
  771.     UDIError    Err;
  772.  
  773.     Err = REALCALL(UDISetCurrentConnectionAddr,Session);
  774.  
  775.     CheckRealError(Err,"UDISetCurrentConnection");
  776.  
  777.     return FUNC_VAL;
  778.  
  779. } /* UDIPSetCurrentConnection() */
  780.  
  781.  
  782.  
  783. UDIError UDIPDisconnect(
  784.     REALPTR        UDIDisconnectAddr,
  785.     UDISessionId    Session,        /* In  */
  786.     UDIBool        Terminate,        /* In  */
  787.     DOSTerm _far    *TermStruct    /* In  */
  788.     )
  789. {
  790.     UDIError    Err;
  791.     DOSTerm         t;
  792.  
  793.     _Packed struct {
  794.         UDISessionId    Session;
  795.         UDIBool        Terminate;
  796.         REALPTR        Term;
  797.     } params;
  798.  
  799.     _fmemmove(NEARPTR_TO_FARPTR(&t),TermStruct,sizeof(TermStruct));
  800.  
  801.     /* The only pointer to be passed is a pointer to TermStruct
  802.      * but since TermStruct is already in real memory, we do
  803.      * not want to copy it (The TIP must store its registers into
  804.      * the original TermStruct, not the copy)
  805.      */
  806.  
  807.     /* For this call just need to pack everything into a structure,
  808.      * then do the call since there are no "out" parameters and no
  809.      * pointers to "in" parameters.
  810.      */
  811.     params.Session   = Session;
  812.     params.Terminate = Terminate;
  813.     params.Term      = PROT_TO_REAL((FARPTR)TermStruct);    /* just convert to real */
  814.  
  815.     Err = REALCALL(UDIDisconnectAddr,params);
  816.  
  817.     CheckRealError(Err,"UDIDisconnect");
  818.  
  819.     return FUNC_VAL;
  820.  
  821. } /* UDIPDisconnect() */
  822.  
  823.  
  824.  
  825. UDIError UDIPGetTargetConfig(
  826.     REALPTR        UDIGetTargetConfigAddr,
  827.     UDIMemoryRange    KnownMemory[],        /* Out */
  828.     UDIInt        *NumberOfRanges,    /* In/Out */
  829.     UDIUInt32    ChipVersions[],        /* Out */
  830.     UDIInt        *NumberOfChips        /* In/Out */
  831.     )
  832. {
  833.     _Packed struct {
  834.         REALPTR        KnownMemory;
  835.         REALPTR        NumberOfRanges;
  836.         REALPTR        ChipVersions;
  837.         REALPTR        NumberOfChips;
  838.     } params;
  839.  
  840.     UDIError        Err;
  841.     UDIInt _far        *NumberOfRangesPtr;
  842.     UDIUInt32 _far        *ChipVersionsPtr;
  843.     UDIInt _far        *NumberOfChipsPtr;
  844.  
  845.     /* Get addresses in parameter passing buffer to store parameters
  846.      * which are passed-by-reference.
  847.      */
  848.      NumberOfRangesPtr = (UDIInt _far *) (rm_address + *NumberOfRanges * sizeof(UDIMemoryRange));
  849.      ChipVersionsPtr   = (UDIUInt32 _far *) (NumberOfRangesPtr + sizeof(UDIInt));
  850.      NumberOfChipsPtr  = (UDIInt _far *) (ChipVersionsPtr + *NumberOfChips * sizeof(UDIUInt32));
  851.  
  852.  
  853.  
  854.     if (BufferSizeCheck((FARPTR)(NumberOfChipsPtr + sizeof(UDIInt)),"UDIPGetTargetConfig",PRINT_ON)) {
  855.         return UDIErrorIPCLimitation;
  856.     } /* if */
  857.  
  858.     /* Copy parameters which are passed-by-reference to parameter
  859.      * passing buffer.  Only "In" data needs to be copied. 
  860.      */
  861.      _fmemmove(NumberOfRangesPtr,NEARPTR_TO_FARPTR(NumberOfRanges),sizeof(UDIInt));
  862.      _fmemmove(NumberOfChipsPtr,NEARPTR_TO_FARPTR(NumberOfChips),sizeof(UDIInt));
  863.  
  864.     /* Put data into packed structure. */
  865.     params.KnownMemory    = rm_buffer_addr;
  866.     params.NumberOfRanges = PROT_TO_REAL((FARPTR)NumberOfRangesPtr);
  867.     params.ChipVersions   = PROT_TO_REAL((FARPTR)ChipVersionsPtr);
  868.     params.NumberOfChips  = PROT_TO_REAL((FARPTR)NumberOfChipsPtr);
  869.  
  870.     Err = REALCALL(UDIGetTargetConfigAddr,params);
  871.  
  872.     CheckRealError(Err,"UDIGetTargetConfig");
  873.  
  874.     /* Put data back into protected mode program address. */
  875.     _fmemmove(NEARPTR_TO_FARPTR(KnownMemory),rm_address,*NumberOfRanges * sizeof(UDIMemoryRange));
  876.     _fmemmove(NEARPTR_TO_FARPTR(NumberOfRanges),NumberOfRangesPtr, sizeof(UDIInt));
  877.     _fmemmove(NEARPTR_TO_FARPTR(ChipVersions), ChipVersionsPtr, *NumberOfChips * sizeof(UDIUInt32));
  878.     _fmemmove(NEARPTR_TO_FARPTR(NumberOfChips), NumberOfChipsPtr, sizeof(UDIInt));
  879.  
  880.     return FUNC_VAL;
  881.  
  882. } /* UDIPGetTargetConfig() */
  883.  
  884.  
  885.  
  886. UDIError UDIPCreateProcess(
  887.     REALPTR        UDICreateProcessAddr,
  888.     UDIPId        *PId            /* Out */
  889.     )
  890. {
  891.     UDIError    Err;
  892.  
  893.  
  894.     if (BufferSizeCheck((FARPTR)(rm_address + sizeof(UDIPId)),"UDIPCreateProcess",PRINT_ON)) {
  895.         return UDIErrorIPCLimitation;
  896.     } /* if */
  897.  
  898.     /* Copy passed-by-reference information to parameter passing buffer. */
  899.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(PId),sizeof(UDIPId));
  900.  
  901.     /* Don't need to create structure since there is only one parameter. */
  902.     Err = REALCALL(UDICreateProcessAddr,rm_buffer_addr);
  903.  
  904.     CheckRealError(Err,"UDICreateProcess");
  905.  
  906.     /* Copy "out" data back to protected mode program address. */
  907.     _fmemmove(NEARPTR_TO_FARPTR(PId),rm_address,sizeof(UDIPId));
  908.  
  909.     return FUNC_VAL;
  910.  
  911. } /* UDIPCreateProcess() */
  912.  
  913.  
  914.  
  915. UDIError UDIPSetCurrentProcess(
  916.     REALPTR        UDISetCurrentProcessAddr,
  917.     UDIPId        PId            /* In  */
  918.     )
  919. {
  920.     UDIError    Err;
  921.  
  922.     
  923.     Err = REALCALL(UDISetCurrentProcessAddr,PId);
  924.  
  925.     CheckRealError(Err,"UDISetCurrentProcess");
  926.  
  927.     return FUNC_VAL;
  928.  
  929. } /* UDIPSetCurrentProcess() */
  930.  
  931.  
  932.  
  933. UDIError UDIPInitializeProcess(
  934.     REALPTR        UDIInitializeProcessAddr,
  935.     UDIMemoryRange    ProcessMemory[],    /* In  */
  936.     UDIInt        NumberOfRanges,        /* In  */
  937.     UDIResource    EntryPoint,        /* In  */
  938.     CPUSizeT    *StackSizes,        /* In  */
  939.     UDIInt        NumberOfStacks,        /* In  */
  940.     char        *ArgString        /* In  */
  941.     )
  942. {
  943.     _Packed struct {
  944.         REALPTR        ProcessMemory;
  945.         UDIInt        NumberOfRanges;
  946.         UDIResource    EntryPoint;
  947.         REALPTR        StackSizes;
  948.         UDIInt        NumberOfStacks;
  949.         REALPTR        ArgString;
  950.     } params;
  951.  
  952.     /* Pointers to variables stored in the parameter passing buffer. */
  953.     CPUSizeT _far    *StackSizesPtr;
  954.     char _far    *ArgStringPtr;
  955.     UDIError    Err;
  956.  
  957.  
  958.     StackSizesPtr = (CPUSizeT _far *) (rm_address + NumberOfRanges*sizeof(UDIMemoryRange));
  959.     ArgStringPtr  = (char _far *) (StackSizesPtr + NumberOfStacks * sizeof(CPUSizeT));
  960.  
  961.     if (BufferSizeCheck((FARPTR)(ArgStringPtr + strlen(ArgString) + 1),"UDIPInitializeProcess",PRINT_ON)) {
  962.         return UDIErrorIPCLimitation;
  963.     } /* if */
  964.  
  965.     /* Move things passed by reference into the parameter passing buffer. */
  966.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(ProcessMemory),NumberOfRanges*sizeof(UDIMemoryRange));
  967.     _fmemmove(StackSizesPtr,NEARPTR_TO_FARPTR(StackSizes),NumberOfStacks * sizeof(CPUSizeT));
  968.     _fmemmove(ArgStringPtr, NEARPTR_TO_FARPTR(ArgString), strlen(ArgString)+1);
  969.  
  970.     /* Fill the packed array for passing to the real mode function. */
  971.     params.ProcessMemory  = rm_buffer_addr;
  972.     params.NumberOfRanges = NumberOfRanges;
  973.     params.EntryPoint     = EntryPoint;
  974.     params.StackSizes     = PROT_TO_REAL((FARPTR)StackSizesPtr);
  975.     params.NumberOfStacks = NumberOfStacks;
  976.     params.ArgString      = PROT_TO_REAL((FARPTR)ArgStringPtr);
  977.     
  978.     /* Call the real mode function. */
  979.     Err = REALCALL(UDIInitializeProcessAddr,params);
  980.  
  981.     CheckRealError(Err,"UDIInitializeProcess");
  982.  
  983.     /* Don't need to copy anything back since all of the parameters are
  984.      * "in" only.
  985.      */
  986.  
  987.     return FUNC_VAL;
  988.  
  989. } /* UDIPInitializeProcess() */
  990.  
  991.  
  992.  
  993. UDIError UDIPDestroyProcess(
  994.     REALPTR        UDIDestroyProcessAddr,
  995.     UDIPId        PId            /* In  */
  996.     )
  997. {
  998.  
  999.     UDIError    Err;
  1000.  
  1001.     Err = REALCALL(UDIDestroyProcessAddr,PId);
  1002.  
  1003.     CheckRealError(Err,"UDIDestroyProcess");
  1004.  
  1005.     return FUNC_VAL;
  1006.  
  1007. } /* UDIPDestroyProcess() */
  1008.  
  1009.  
  1010.  
  1011. UDIError UDIPRead(
  1012.     REALPTR        UDIReadAddr,
  1013.     UDIResource    From,            /* In  */
  1014.     UDIHostMemPtr    To,            /* Out */
  1015.     UDICount    Count,            /* In  */
  1016.     UDISizeT    Size,            /* In  */
  1017.     UDICount    *CountDone,        /* Out */
  1018.     UDIBool        HostEndian        /* In  */
  1019.     )
  1020. {
  1021.     _Packed struct {
  1022.         UDIResource    From;
  1023.         REALPTR        To;
  1024.         UDICount    Count;
  1025.         UDISizeT    Size;
  1026.         REALPTR        CountDone;
  1027.         UDIBool        HostEndian;
  1028.     } params;
  1029.  
  1030.     UDIError    Err;
  1031.     UDICount _far    *CountDonePtr;
  1032.  
  1033.     /* Looping control variables */
  1034.     UDICount    TotalDone=0;    /* Total number of items xfered so far */
  1035.     UDICount    CurrentCount;    /* Number of items to be xfered this pass */
  1036.     UDIResource    CurrentFrom;    /* Current pointer into From area */
  1037.     char *        CurrentTo;    /* Current pointer into To area */
  1038.     UDICount    BufAdjust;    /* size of buffer overflow in bytes */
  1039.     UDICount    CurrentDone;    /* The actual number of items xfered this pass */
  1040.  
  1041.  
  1042.     CurrentTo    = (char *) To;
  1043.     CurrentFrom  = From;
  1044.     CurrentCount = Count;
  1045.     do {
  1046.         CountDonePtr = (UDICount _far *) (rm_address + CurrentCount * Size);
  1047.  
  1048.         /* Check to see if transfer needs to be broken into smaller pieces */
  1049.         BufAdjust = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDICount)),"UDIPRead",PRINT_OFF); 
  1050.         if (BufAdjust)  {
  1051.             CurrentCount = (rm_end_address - rm_address - sizeof(UDICount)) / Size ;
  1052.             CountDonePtr = (UDICount _far *) (rm_end_address - sizeof(UDICount));
  1053.         }
  1054.         
  1055.         /* Copy parameters into packed structure. */
  1056.         params.From       = CurrentFrom;
  1057.         params.To         = rm_buffer_addr;
  1058.         params.Count      = CurrentCount;
  1059.         params.Size       = Size;
  1060.         params.CountDone  = PROT_TO_REAL((FARPTR)CountDonePtr);
  1061.         params.HostEndian = HostEndian;
  1062.  
  1063.         Err = REALCALL(UDIReadAddr,params);
  1064.  
  1065.         CheckRealError(Err,"UDIRead");
  1066.  
  1067.         _fmemmove(NEARPTR_TO_FARPTR(&CurrentDone),CountDonePtr,sizeof(UDICount));
  1068.  
  1069.         /* Increment the TotalDone by the actual number of items xfered as
  1070.          * returned from the function.
  1071.          */
  1072.         TotalDone += CurrentDone;
  1073.  
  1074.         if ((CurrentDone <= CurrentCount) && (CurrentDone >= 0))
  1075.             _fmemmove(NEARPTR_TO_FARPTR(CurrentTo),rm_address,CurrentDone * Size);
  1076.         else {
  1077.             _fmemmove(NEARPTR_TO_FARPTR(CurrentTo),rm_address, CurrentCount * Size);
  1078.             SIZE_ERROR(CurrentDone, CurrentCount, "UDIPRead");
  1079.         }
  1080.  
  1081.         /* Update looping variables for possible next pass */
  1082.         CurrentFrom.Offset += CurrentCount * Size;
  1083.         CurrentTo += CurrentCount * Size;
  1084.         CurrentCount = Count - TotalDone; 
  1085.  
  1086.     } while ((TotalDone < Count) & (FUNC_VAL == UDINoError));
  1087.  
  1088.     *CountDone = TotalDone;
  1089.  
  1090.     return FUNC_VAL;
  1091.  
  1092. } /* UDIPRead() */
  1093.  
  1094.  
  1095. UDIError UDIPWrite(
  1096.     REALPTR        UDIWriteAddr,
  1097.     UDIHostMemPtr    From,            /* In  */
  1098.     UDIResource    To,            /* In  */
  1099.     UDICount    Count,            /* In  */
  1100.     UDISizeT    Size,            /* In  */
  1101.     UDICount    *CountDone,        /* Out */
  1102.     UDIBool        HostEndian        /* In  */
  1103.     )
  1104. {
  1105.     _Packed struct {
  1106.         REALPTR        From;
  1107.         UDIResource    To;
  1108.         UDICount    Count;
  1109.         UDISizeT    Size;
  1110.         REALPTR        CountDone;
  1111.         UDIBool        HostEndian;
  1112.     } params;
  1113.  
  1114.     UDIError    Err;
  1115.     UDICount _far    *CountDonePtr;
  1116.  
  1117.     /* Looping control variables */
  1118.     UDICount    TotalDone=0;    /* Total number of items xfered so far */
  1119.     UDICount    CurrentCount;    /* Number of items to be xfered this pass */
  1120.     char *        CurrentFrom;    /* Current pointer into From area */
  1121.     UDIResource    CurrentTo;    /* Current pointer into To area */
  1122.     UDICount    BufAdjust;    /* size of buffer overflow in bytes */
  1123.     UDICount    CurrentDone;    /* The actual number of items xfered this pass */
  1124.  
  1125.  
  1126.     CurrentTo    = To;
  1127.     CurrentFrom  = (char *) From;
  1128.     CurrentCount = Count;
  1129.  
  1130.     do {
  1131.         CountDonePtr = (UDICount _far *) (rm_address + Size * Count);
  1132.  
  1133.         /* Check to see if transfer needs to be broken into smaller pieces. */
  1134.         BufAdjust = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDICount)),"UDIPWrite",PRINT_ON);
  1135.         if (BufAdjust) {
  1136.             CurrentCount = (rm_end_address - rm_address - sizeof(UDICount)) / Size;
  1137.             CountDonePtr = (UDICount _far *) (rm_end_address - sizeof(UDICount));
  1138.         } /* if */
  1139.  
  1140.         /* Move data passed by reference into the parameter passing buffer
  1141.          * area in conventional memory. 
  1142.          */
  1143.         _fmemmove(rm_address, NEARPTR_TO_FARPTR(CurrentFrom), Size * CurrentCount);
  1144.  
  1145.         /* Move data to packed structure for passing to real mode function. */
  1146.         params.From      = rm_buffer_addr;
  1147.         params.To      = CurrentTo;
  1148.         params.Count      = CurrentCount;
  1149.         params.Size      = Size;
  1150.         params.CountDone  = PROT_TO_REAL((FARPTR)CountDonePtr);
  1151.         params.HostEndian = HostEndian;
  1152.  
  1153.         Err = REALCALL(UDIWriteAddr,params);
  1154.     
  1155.         CheckRealError(Err,"UDIWrite");
  1156.         
  1157.         /* Move "out" data back into protected mode memory area. */
  1158.         _fmemmove(NEARPTR_TO_FARPTR(&CurrentDone),CountDonePtr,sizeof(UDICount));
  1159.  
  1160.         /* Increment the ToralDone by the actual number of items xfered as
  1161.          * returned from the function.
  1162.          */
  1163.         TotalDone += CurrentDone;
  1164.  
  1165.         /* Update looping variables for possible next pass */
  1166.         CurrentFrom += CurrentCount * Size;
  1167.         CurrentTo.Offset += CurrentCount * Size;
  1168.         CurrentCount = Count - TotalDone;
  1169.  
  1170.     } while ((TotalDone < Count) & (FUNC_VAL == UDINoError));
  1171.  
  1172.     /* Return the total number of items xfered */
  1173.     *CountDone = TotalDone;
  1174.  
  1175.     return FUNC_VAL;
  1176.  
  1177. } /* UDIPWrite() */
  1178.  
  1179.  
  1180. UDIError UDIPCopy(
  1181.     REALPTR        UDICopyAddr,
  1182.     UDIResource    From,            /* In  */
  1183.     UDIResource    To,            /* In  */
  1184.     UDICount    Count,            /* In  */
  1185.     UDISizeT    Size,            /* In  */
  1186.     UDICount    *CountDone,        /* Out */
  1187.     UDIBool        Direction        /* In  */
  1188.     )
  1189. {
  1190.     _Packed struct {
  1191.         UDIResource    From;
  1192.         UDIResource    To;
  1193.         UDICount    Count;
  1194.         UDISizeT    Size;
  1195.         REALPTR        CountDone;
  1196.         UDIBool        Direction;
  1197.     } params;
  1198.  
  1199.     UDIError    Err;
  1200.  
  1201.     /* Copy data into packed structure for passing to real mode funciton. */
  1202.     params.From    = From;
  1203.     params.To    = To;
  1204.     params.Count    = Count;
  1205.     params.Size    = Size;
  1206.     params.CountDone= rm_buffer_addr;
  1207.     params.Direction= Direction;
  1208.  
  1209.     Err = REALCALL(UDICopyAddr,params);
  1210.  
  1211.     CheckRealError(Err,"UDICopy");
  1212.  
  1213.     _fmemmove(NEARPTR_TO_FARPTR(CountDone), rm_address, sizeof(UDICount));
  1214.  
  1215.     return FUNC_VAL;
  1216.  
  1217. } /* UDIPCopy() */
  1218.  
  1219.  
  1220.  
  1221. UDIError UDIPExecute(
  1222.     REALPTR        UDIExecuteAddr
  1223.     )
  1224. {
  1225.     UDIError    Err;
  1226.  
  1227.     Err = _dx_call_real(UDIExecuteAddr, &real_regs, 0);
  1228.  
  1229.     CheckRealError(Err,"UDIExecute");
  1230.  
  1231.     return FUNC_VAL;
  1232.  
  1233. } /* UDIPExecute() */
  1234.  
  1235.  
  1236.  
  1237. UDIError UDIPStep(
  1238.     REALPTR        UDIStepAddr,
  1239.     UDIUInt32    Steps,            /* In  */
  1240.     UDIStepType    StepType,        /* In  */
  1241.     UDIRange    Range            /* In  */
  1242.     )
  1243. {
  1244.     UDIError    Err;
  1245.  
  1246.     _Packed struct {
  1247.         UDIUInt32    Steps;
  1248.         UDIStepType    StepType;
  1249.         UDIRange    Range;
  1250.     } params;
  1251.  
  1252.     /* Since nothing is passed by reference, don't need to use
  1253.      * buffer transfer area.
  1254.      */
  1255.  
  1256.     /* Copy passed parameters into packed structure */
  1257.     params.Steps    = Steps;
  1258.     params.StepType = StepType;
  1259.     params.Range    = Range;
  1260.  
  1261.     Err = REALCALL(UDIStepAddr,params);
  1262.  
  1263.     CheckRealError(Err,"UDIStep");
  1264.  
  1265.     return FUNC_VAL;
  1266.  
  1267. } /* UDIPStep() */
  1268.  
  1269.  
  1270.  
  1271. UDIError UDIPStop(
  1272.     REALPTR        UDIStopAddr
  1273.     )
  1274. {
  1275.     UDIError    Err;
  1276.  
  1277.     Err = _dx_call_real(UDIStopAddr, &real_regs, 0);
  1278.  
  1279.     CheckRealError(Err,"UDIStop");
  1280.  
  1281.     return FUNC_VAL;
  1282.  
  1283. } /* UDIPStop() */
  1284.  
  1285.  
  1286.  
  1287. UDIError UDIPWait(
  1288.     REALPTR        UDIWaitAddr,
  1289.     UDIInt32    MaxTime,        /* In  */
  1290.     UDIPId        *PId,            /* Out */
  1291.     UDIUInt32    *StopReason        /* Out */
  1292.     )
  1293. {
  1294.     UDIError    Err;
  1295.     UDIUInt32 _far    *StopReasonPtr;
  1296.  
  1297.     _Packed struct {
  1298.         UDIInt32    MaxTime;
  1299.         REALPTR        PId;
  1300.         REALPTR        StopReason;
  1301.     } params;
  1302.  
  1303.     /* Since only "out" parameters are passed by reference, don't
  1304.      * need to copy anything into the parameter passing buffer before
  1305.      * the call.  Do need to set up pointer for StopReason though.
  1306.      */
  1307.     StopReasonPtr = (UDIUInt32 _far *) (rm_address + sizeof(UDIPId));
  1308.  
  1309.     if (BufferSizeCheck((FARPTR)(StopReasonPtr + sizeof(UDIUInt32)),"UDIPWait",PRINT_ON)) {
  1310.         return UDIErrorIPCLimitation;
  1311.     } /* if */
  1312.  
  1313.     params.MaxTime    = MaxTime;
  1314.     params.PId        = rm_buffer_addr;
  1315.     params.StopReason = PROT_TO_REAL((FARPTR)StopReasonPtr);
  1316.  
  1317.     Err = REALCALL(UDIWaitAddr,params);
  1318.  
  1319.     CheckRealError(Err,"UDIWait");
  1320.  
  1321.     /* Need to copy "out" parameter data back into protected mode
  1322.      * address space. 
  1323.      */
  1324.     _fmemmove(NEARPTR_TO_FARPTR(PId),rm_address,sizeof(UDIPId));
  1325.     _fmemmove(NEARPTR_TO_FARPTR(StopReason),StopReasonPtr,sizeof(UDIUInt32));
  1326.  
  1327.     return FUNC_VAL;
  1328.  
  1329. } /* UDIPWait() */
  1330.  
  1331.  
  1332.  
  1333. UDIError UDIPSetBreakpoint(
  1334.     REALPTR        UDISetBreakpointAddr,
  1335.     UDIResource    Addr,              /* In  */
  1336.     UDIInt32    PassCount,        /* In  */
  1337.     UDIBreakType    Type,            /* In  */
  1338.     UDIBreakId    *BreakId        /* Out */
  1339.     )
  1340. {
  1341.     UDIError    Err;
  1342.  
  1343.     _Packed struct {
  1344.         UDIResource    Addr;
  1345.         UDIInt32    PassCount;
  1346.         UDIBreakType    Type;
  1347.         REALPTR        BreakId;
  1348.     } params;
  1349.  
  1350.     if (BufferSizeCheck((FARPTR)(rm_address + sizeof(UDIBreakId)),"UDIPSetBreakpoint",PRINT_ON)) {
  1351.         return UDIErrorIPCLimitation;
  1352.     } /* if */
  1353.  
  1354.     /* Since only "out" parameters are passed by reference, don't
  1355.      * need to copy anything into the parameter passing buffer before
  1356.      * the call.  
  1357.      */
  1358.     params.Addr      = Addr;
  1359.     params.PassCount = PassCount;
  1360.     params.Type      = Type;
  1361.     params.BreakId   = rm_buffer_addr;
  1362.  
  1363.     Err = REALCALL(UDISetBreakpointAddr,params);
  1364.  
  1365.     CheckRealError(Err,"UDISetBreakpoint");
  1366.  
  1367.     /* Need to copy "out" parameter data back into protected mode
  1368.      * address space. 
  1369.      */
  1370.     _fmemmove(NEARPTR_TO_FARPTR(BreakId),rm_address,sizeof(UDIBreakId));
  1371.  
  1372.     return FUNC_VAL;
  1373.  
  1374. } /* UDIPSetBreakpoint() */
  1375.  
  1376.  
  1377.  
  1378. UDIError UDIPQueryBreakpoint(
  1379.     REALPTR        UDIQueryBreakpointAddr,
  1380.     UDIBreakId    BreakId,        /* In  */
  1381.     UDIResource    *Addr,            /* Out */
  1382.     UDIInt32    *PassCount,        /* Out */
  1383.     UDIBreakType    *Type,            /* Out */
  1384.     UDIInt32    *CurrentCount        /* Out */
  1385.     )
  1386. {
  1387.     UDIError        Err;
  1388.     UDIInt32 _far        *PassCountPtr;
  1389.     UDIBreakType _far    *TypePtr;
  1390.     UDIInt32 _far        *CurrentCountPtr;
  1391.  
  1392.     _Packed struct {
  1393.         UDIBreakId    BreakId;
  1394.         REALPTR        Addr;
  1395.         REALPTR        PassCount;
  1396.         REALPTR        Type;
  1397.         REALPTR        CurrentCount;
  1398.     } params;
  1399.  
  1400.     /* Since all passed-by-reference variables are "out", don't need
  1401.      * to copy data to parameter passing buffer.  Do need to set up
  1402.      * pointers for real-mode function to use though.
  1403.      */
  1404.     PassCountPtr    = (UDIInt32 _far *) (rm_address + sizeof(UDIResource));
  1405.     TypePtr         = (UDIBreakType _far *) (PassCountPtr + sizeof(UDIInt32));
  1406.     CurrentCountPtr = (UDIInt32 _far *) (TypePtr + sizeof(UDIBreakType));
  1407.  
  1408.     if (BufferSizeCheck((FARPTR)(CurrentCountPtr + sizeof(UDIBreakType)),"UDIPQueryBreakpoint",PRINT_ON)) {
  1409.         return UDIErrorIPCLimitation;
  1410.     } /* if */
  1411.  
  1412.     params.BreakId      = BreakId;
  1413.     params.Addr         = rm_buffer_addr;
  1414.     params.PassCount    = PROT_TO_REAL((FARPTR)PassCountPtr);
  1415.     params.Type         = PROT_TO_REAL((FARPTR)TypePtr);
  1416.     params.CurrentCount = PROT_TO_REAL((FARPTR)CurrentCountPtr);
  1417.  
  1418.     Err = REALCALL(UDIQueryBreakpointAddr,params);
  1419.  
  1420.     CheckRealError(Err,"UDIQueryBreakpoint");
  1421.  
  1422.     /* Copy returned values back into protected mode variables. */
  1423.     _fmemmove(NEARPTR_TO_FARPTR(Addr),rm_address,sizeof(UDIResource));
  1424.     _fmemmove(NEARPTR_TO_FARPTR(PassCount),PassCountPtr,sizeof(UDIInt32));
  1425.     _fmemmove(NEARPTR_TO_FARPTR(Type),TypePtr,sizeof(UDIBreakType));
  1426.     _fmemmove(NEARPTR_TO_FARPTR(CurrentCount),CurrentCountPtr,sizeof(UDIInt32));
  1427.  
  1428.     return FUNC_VAL;
  1429.  
  1430. } /* UDIPQueryBreakpoint() */
  1431.  
  1432.  
  1433.  
  1434. UDIError UDIPClearBreakpoint(
  1435.     REALPTR        UDIClearBreakpointAddr,
  1436.     UDIBreakId    BreakId            /* In  */
  1437.     )
  1438. {
  1439.     UDIError    Err;
  1440.  
  1441.     /* Don't need packed structure since only one parameter is passed. */
  1442.  
  1443.     Err = REALCALL(UDIClearBreakpointAddr,BreakId);
  1444.  
  1445.     CheckRealError(Err,"UDIClearBreakpoint");
  1446.  
  1447.     return FUNC_VAL;
  1448.  
  1449. } /* UDIPClearBreakpoint() */
  1450.  
  1451.  
  1452.  
  1453.  
  1454. UDIError UDIPGetStdout(
  1455.     REALPTR        UDIGetStdoutAddr,
  1456.     UDIHostMemPtr    Buf,            /* Out */
  1457.     UDISizeT    BufSize,        /* In  */
  1458.     UDISizeT    *CountDone        /* Out */
  1459.     )
  1460. {
  1461.     UDIError    Err;
  1462.     UDISizeT _far    *CountDonePtr;
  1463.  
  1464.     char *        CurrentTo;
  1465.     UDISizeT    TotalDone = 0;
  1466.     UDISizeT    CurrentCount;
  1467.     UDISizeT    CurrentDone = 0;
  1468.     long        BufAdjust;
  1469.  
  1470.     _Packed struct {
  1471.         REALPTR        Buf;
  1472.         UDISizeT    BufSize;
  1473.         REALPTR        CountDone;
  1474.     } params;
  1475.  
  1476.     CurrentCount = BufSize;
  1477.     CurrentTo    = (char *) Buf;
  1478.  
  1479.     do {
  1480.         CountDonePtr = (UDISizeT _far *) (rm_address + CurrentCount);
  1481.  
  1482.         BufAdjust = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDISizeT)),"UDIPGetStdout",PRINT_ON);
  1483.         if (BufAdjust) {
  1484.             CurrentCount = (rm_end_address - rm_address - sizeof(UDISizeT));
  1485.             CountDonePtr = (UDISizeT _far * ) (rm_end_address - sizeof(UDISizeT));
  1486.         } /* if */
  1487.  
  1488.         params.Buf       = rm_buffer_addr;
  1489.         params.BufSize   = CurrentCount;
  1490.         params.CountDone = PROT_TO_REAL((FARPTR)CountDonePtr);
  1491.  
  1492.         Err = REALCALL(UDIGetStdoutAddr,params);
  1493.  
  1494.         CheckRealError(Err,"UDIGetStdout");
  1495.  
  1496.         /* Copy returned values back into protected mode variables. */
  1497.         _fmemmove(NEARPTR_TO_FARPTR(&CurrentDone),CountDonePtr,sizeof(UDISizeT));
  1498.  
  1499.         TotalDone += CurrentDone;
  1500.  
  1501.         if (CurrentDone <= CurrentCount) 
  1502.             _fmemmove(NEARPTR_TO_FARPTR(CurrentTo),rm_address,CurrentDone);
  1503.         else {
  1504.             _fmemmove(NEARPTR_TO_FARPTR(CurrentTo),rm_address,CurrentDone);
  1505.             SIZE_ERROR(*CountDone, BufSize, "UDIPGetStdout");
  1506.         }
  1507.  
  1508.         /* Update looping variables for possible next pass */
  1509.         CurrentTo += CurrentDone;
  1510.  
  1511.  
  1512.     } while ((TotalDone < BufSize) & (CurrentDone == CurrentCount) 
  1513.         & (FUNC_VAL == UDINoError));
  1514.  
  1515.     *CountDone = TotalDone;
  1516.  
  1517.     return FUNC_VAL;
  1518.  
  1519. } /* UDIPGetStdout() */
  1520.  
  1521.  
  1522.  
  1523. UDIError UDIPGetStderr(
  1524.     REALPTR        UDIGetStderrAddr,
  1525.     UDIHostMemPtr    Buf,            /* Out */
  1526.     UDISizeT    BufSize,        /* In  */
  1527.     UDISizeT    *CountDone        /* Out */
  1528.     )
  1529. {
  1530.     UDIError    Err;
  1531.     UDISizeT _far    *CountDonePtr;
  1532.     long        Buffer_Adjustment;
  1533.  
  1534.     _Packed struct {
  1535.         REALPTR        Buf;
  1536.         UDISizeT    BufSize;
  1537.         REALPTR        CountDone;
  1538.     } params;
  1539.  
  1540.     /* Since all passed-by-reference variables are "out", don't need
  1541.      * to copy data to parameter passing buffer.  Do need to set up
  1542.      * pointers for real-mode function to use though.
  1543.      */
  1544.     CountDonePtr = (UDISizeT _far *) (rm_address + BufSize);
  1545.  
  1546.     if ((Buffer_Adjustment = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDISizeT)),"UDIPGetStderr",PRINT_ON))) {
  1547.         if (BufSize <= Buffer_Adjustment)
  1548.             return UDIErrorIPCLimitation;
  1549.         BufSize -= Buffer_Adjustment;
  1550.     } /* if */
  1551.  
  1552.     params.Buf       = rm_buffer_addr;
  1553.     params.BufSize   = BufSize;
  1554.     params.CountDone = PROT_TO_REAL((FARPTR)CountDonePtr);
  1555.  
  1556.     Err = REALCALL(UDIGetStderrAddr,params);
  1557.  
  1558.     CheckRealError(Err,"UDIGetStderr");
  1559.  
  1560.     /* Copy returned values back into protected mode variables. */
  1561.     _fmemmove(NEARPTR_TO_FARPTR(CountDone),CountDonePtr,sizeof(UDISizeT));
  1562.     if (*CountDone <= BufSize)
  1563.         _fmemmove(NEARPTR_TO_FARPTR(Buf),rm_address,*CountDone);
  1564.     else {
  1565.         _fmemmove(NEARPTR_TO_FARPTR(Buf),rm_address,BufSize);
  1566.         SIZE_ERROR(*CountDone, BufSize, "UDIPGetStderr");
  1567.     }
  1568.  
  1569.     return FUNC_VAL;
  1570.     
  1571. } /* UDIPGetStderr() */
  1572.  
  1573.  
  1574.  
  1575. UDIError UDIPPutStdin(
  1576.     REALPTR        UDIPutStdinAddr,
  1577.     UDIHostMemPtr    Buf,            /* In  */
  1578.     UDISizeT    Count,            /* In  */
  1579.     UDISizeT    *CountDone        /* Out */
  1580.     )
  1581. {
  1582.     UDIError    Err;
  1583.     UDISizeT _far    *CountDonePtr;
  1584.     long        Buffer_Adjustment;
  1585.  
  1586.     _Packed struct {
  1587.         REALPTR        Buf;
  1588.         UDISizeT    Count;
  1589.         REALPTR        CountDone;
  1590.     } params;
  1591.  
  1592.     /* Get pointers to passed-by-reference variables in parameter
  1593.      * passing buffer. 
  1594.      */
  1595.     CountDonePtr = (UDISizeT _far *) (rm_address + Count);
  1596.  
  1597.     if ((Buffer_Adjustment = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDISizeT)),"UDIPPutStdin",PRINT_ON))) {
  1598.         if (Count <= Buffer_Adjustment)
  1599.             return UDIErrorIPCLimitation;
  1600.         Count -= Buffer_Adjustment;
  1601.     } /* if */
  1602.  
  1603.     /* Copy "in" passed-by-reference variables to parameter passing
  1604.      * buffer.
  1605.      */
  1606.     _fmemmove(rm_address,NEARPTR_TO_FARPTR(Buf),Count);
  1607.  
  1608.     params.Buf       = rm_buffer_addr;
  1609.     params.Count     = Count;
  1610.     params.CountDone = PROT_TO_REAL((FARPTR)CountDonePtr);
  1611.  
  1612.     Err = REALCALL(UDIPutStdinAddr,params);
  1613.  
  1614.     CheckRealError(Err,"UDIPutStdin");
  1615.  
  1616.     /* Copy returned values back into protected mode variables. */
  1617.     _fmemmove(NEARPTR_TO_FARPTR(CountDone),CountDonePtr,sizeof(UDISizeT));
  1618.  
  1619.     return FUNC_VAL;
  1620.  
  1621.  
  1622. } /* UDIPPutStdin() */
  1623.  
  1624.  
  1625.  
  1626. UDIError UDIPStdinMode(
  1627.     REALPTR        UDIStdinModeAddr,
  1628.     UDIMode        *Mode            /* Out */
  1629.     )
  1630. {
  1631.     UDIError    Err;
  1632.  
  1633.     /* Don't need to copy anything in parameter passing area since there
  1634.      * are no "in", passed-by-reference parameters.  
  1635.      * Since there is only a single parameter and that is "out", and
  1636.      * passed-by-reference, can just use the address of the parameter
  1637.      * passing buffer for this.
  1638.      */
  1639.     Err = REALCALL(UDIStdinModeAddr,rm_buffer_addr);
  1640.  
  1641.     CheckRealError(Err,"UDIStdinMode");
  1642.  
  1643.     _fmemmove(NEARPTR_TO_FARPTR(Mode),rm_address,sizeof(UDIMode));
  1644.  
  1645.     return FUNC_VAL;
  1646.  
  1647. } /* UDIPStdinMode() */
  1648.  
  1649.  
  1650.  
  1651. UDIError UDIPPutTrans(
  1652.     REALPTR        UDIPutTransAddr,
  1653.     UDIHostMemPtr    Buf,            /* In  */
  1654.     UDISizeT    Count,            /* In  */
  1655.     UDISizeT    *CountDone        /* Out */
  1656.     )
  1657. {
  1658.     UDIError    Err;
  1659.     UDISizeT _far    *CountDonePtr;
  1660.  
  1661.     char *        CurrentTo;
  1662.     UDISizeT    TotalDone=0;
  1663.     UDISizeT    CurrentCount;
  1664.     UDISizeT    CurrentDone=0;
  1665.     long        BufAdjust;
  1666.  
  1667.     _Packed struct {
  1668.         REALPTR        Buf;
  1669.         UDISizeT    Count;
  1670.         REALPTR        CountDone;
  1671.     } params;
  1672.  
  1673.     CurrentCount = Count;
  1674.     CurrentTo = Buf;
  1675.  
  1676.     do {
  1677.         CountDonePtr = (UDISizeT _far *) (rm_address + CurrentCount);
  1678.  
  1679.         BufAdjust = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDISizeT)),"UDIPPutTrans",PRINT_OFF);
  1680.         if (BufAdjust) {
  1681.             CurrentCount = (rm_end_address - rm_address - sizeof(UDISizeT));
  1682.             CountDonePtr = (UDISizeT _far *) (rm_end_address - sizeof(UDISizeT));
  1683.         } /* if */
  1684.  
  1685.         _fmemmove(rm_address,NEARPTR_TO_FARPTR(Buf),Count);
  1686.  
  1687.         params.Buf       = rm_buffer_addr;
  1688.         params.Count     = CurrentCount;
  1689.         params.CountDone = PROT_TO_REAL((FARPTR)CountDonePtr);
  1690.  
  1691.         Err = REALCALL(UDIPutTransAddr,params);
  1692.  
  1693.         CheckRealError(Err,"UDIPutTrans");
  1694.  
  1695.         /* Copy the contents of the "out" parameters back into their
  1696.          * protected mode counterparts.
  1697.          */
  1698.         _fmemmove(NEARPTR_TO_FARPTR(&CurrentDone),CountDonePtr,sizeof(UDISizeT));
  1699.  
  1700.         TotalDone += CurrentDone;
  1701.  
  1702.     } while ((TotalDone < Count) & (FUNC_VAL == UDINoError));
  1703.  
  1704.     *CountDone = TotalDone;
  1705.     return FUNC_VAL;
  1706.  
  1707. } /* UDIPPutTrans() */
  1708.  
  1709.  
  1710.  
  1711. UDIError UDIPGetTrans(
  1712.     REALPTR        UDIGetTransAddr,
  1713.     UDIHostMemPtr    Buf,            /* Out */
  1714.     UDISizeT    BufSize,        /* In  */
  1715.     UDISizeT    *CountDone        /* Out */
  1716.     )
  1717. {
  1718.     UDIError    Err;
  1719.     UDISizeT _far    *CountDonePtr;
  1720.     long        BufAdjust;
  1721.  
  1722.     _Packed struct {
  1723.         REALPTR        Buf;
  1724.         UDISizeT    BufSize;
  1725.         REALPTR        CountDone;
  1726.     } params;
  1727.  
  1728.     /* Get pointers to passed-by-reference parameters. */
  1729.     CountDonePtr = (UDISizeT _far *) (rm_address + BufSize);
  1730.  
  1731.     if ((BufAdjust = BufferSizeCheck((FARPTR)(CountDonePtr + sizeof(UDISizeT)),"UDIPGetTrans",PRINT_ON))) {
  1732.         if (BufSize <= BufAdjust)
  1733.             return UDIErrorIPCLimitation;
  1734.         BufSize -= BufAdjust;
  1735.     } /* if */
  1736.  
  1737.     params.Buf       = rm_buffer_addr;
  1738.     params.BufSize   = BufSize;
  1739.     params.CountDone = PROT_TO_REAL((FARPTR)CountDonePtr);
  1740.  
  1741.     Err = REALCALL(UDIGetTransAddr,params);
  1742.  
  1743.     CheckRealError(Err,"UDIGetTrans");
  1744.  
  1745.     /* Copy the contents of the "out" parameters back into their
  1746.      * protected mode counterparts.
  1747.      */
  1748.     _fmemmove(NEARPTR_TO_FARPTR(CountDone),CountDonePtr,sizeof(UDISizeT));
  1749.     if (*CountDone <= BufSize)
  1750.         _fmemmove(NEARPTR_TO_FARPTR(Buf),rm_address,*CountDone);
  1751.     else {
  1752.         _fmemmove(NEARPTR_TO_FARPTR(Buf),rm_address,BufSize);
  1753.         SIZE_ERROR(*CountDone, BufSize, "UDIPGetTrans");
  1754.     }
  1755.  
  1756.     return FUNC_VAL;
  1757.  
  1758.  
  1759. } /* UDIPGetTrans() */
  1760.  
  1761.  
  1762. UDIError UDIPTransMode(
  1763.     REALPTR        UDITransModeAddr,
  1764.     UDIMode        *Mode            /* Out */
  1765.     )
  1766. {
  1767.     UDIError    Err;
  1768.  
  1769.     /* Don't need to copy anything in parameter passing area since there
  1770.      * are no "in", passed-by-reference parameters.  
  1771.      * Since there is only a single parameter and that is "out", and
  1772.      * passed-by-reference, can just use the address of the parameter
  1773.      * passing buffer for this.
  1774.      */
  1775.  
  1776.     Err = REALCALL(UDITransModeAddr,rm_buffer_addr);
  1777.  
  1778.     CheckRealError(Err,"UDITransMode");
  1779.  
  1780.     _fmemmove(NEARPTR_TO_FARPTR(Mode),rm_address,sizeof(UDIMode));
  1781.  
  1782.     return FUNC_VAL;
  1783.  
  1784. } /* UDIPTransMode() */
  1785.  
  1786.