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 / dos2udip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  38.7 KB  |  1,472 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.  * 800-292-9263
  23.  *****************************************************************************
  24.  * DOS386 changes were merged into:
  25.  *       $Id: dos2udip.c,v 1.2 1993/12/23 04:44:38 cassidy Exp $
  26.  *       $Id: @(#)dos2udip.c    2.11, AMD
  27.  */
  28.  
  29.     /* TIPIPCId components */
  30. #define TIPIPCIdCompany    0x0001    /* Company ID from AMD, others should change this */
  31. #define TIPIPCIdVersion    0x124    /* Version */
  32. #ifdef DOS386
  33. #define TIPIPCIdProduct    0x3    /* Product ID for DOS386 IPC */
  34. #else
  35. #define TIPIPCIdProduct    0x2    /* Product ID for non-DOS386 IPC */
  36. #endif
  37.  
  38. #include <stdio.h>
  39. #include <dos.h>
  40.  
  41. #ifdef HAVE_STDLIB_H
  42. # include <stdlib.h>
  43. #endif
  44.  
  45. #ifdef HAVE_STRING_H
  46. # include <string.h>
  47. #else
  48. # include <strings.h>
  49. #endif
  50.  
  51. #include <udiproc.h>
  52. #include <udidos.h>
  53. static FILE *      fpstdout = stdout;    /* where we write the information */
  54.  
  55. #ifndef DOS386
  56. #pragma check_stack( off )
  57. #pragma check_pointer( off )
  58.  
  59.     /********************************************************
  60.      * In non-DOS386 mode, a standard C PTR is just a far real ptr
  61.      * so FARCPTR_TO_REALPTR and REALPTR_TO_FARCPTR are pass-thru
  62.      ********************************************************/
  63. #define FARCPTR_TO_REALPTR(p) p
  64. #define REALPTR_TO_FARCPTR(p) p
  65.  
  66. #define IPCFar far    /* qualifier for pointer that can reach the real data used by IPC */
  67. #define REALNULL NULL
  68. typedef void far * FARCPTR;
  69.  
  70. #else 
  71. #include "malloc.h"
  72. #include "alloca.h"
  73. #include "pharlap.h"
  74. #include "realcopy.h"
  75.  
  76. #define IPCFar _far    /* qualifier for pointer that can reach the real data used by IPC */
  77. #define REALNULL (REALPTR) 0
  78. typedef void _far * FARCPTR;
  79.  
  80.  
  81.     /********************************************************
  82.      * In DOS386 protected mode, we have two types of pointers, near and far
  83.      * near is a 32-bit pointer, ie a 32-bit offset from DS.
  84.      * far is a 48-bit pointer, with an explicit segment register.
  85.      * We want to be able to convert real mode pointers (16-bit seg, 16-bit ofst)
  86.      * into these near and far protected mode pointers and vice versa.
  87.      *
  88.      * It is always possible to convert a real mode pointer to a far prot ptr.
  89.      * (Pharlap provides an explicit segment that maps to the low 1 meg of memory).
  90.      ********************************************************/
  91. FARCPTR  REALPTR_TO_FARCPTR(REALPTR p);
  92.  
  93.     /********************************************************
  94.      * The ability to convert from a real mode pointer to a near protected
  95.      * pointer depends on being able to map converntional memory onto the
  96.      * end of our data segment.  This is NOT possible under DPMI 0.90
  97.      * If we're not under DPMI 0.90,
  98.      * REALPTR_TO_NEARCPTR takes a real ptr, and returns its offset
  99.      * in the SS_DATA segment (using the fact that the 1 meg of real
  100.      * memory was mapped to the SS_DATA by dx_map_physical).
  101.      *
  102.      ********************************************************/
  103. #define REALPTR_TO_NEARCPTR(rp) ((void *)(&conventional_memory[LINEARIZE(rp)]))
  104.  
  105.  
  106.     /**********************************************************
  107.      *  LINEARIZE converts a segment:ofst pointer into a linear
  108.      *  addr between 0 and 1meg
  109.      *********************************************************/
  110. #define LINEARIZE(rp) ((RP_SEG(rp)<<4) + RP_OFF(rp))
  111.  
  112.     /********************************************************
  113.      * FARCPTR_TO_REALPTR converts a far protected ptr to a real ptr.
  114.      * Naturally, only certain protected pointers can be converted
  115.      * into real pointers (they must map to something in the
  116.      * first 1 meg of memory).  If it can't be converted, it's
  117.      * a fatal error.  This is a routine rather than a macro.
  118.      * If we need to convert a near prot ptr to a real ptr,
  119.      * this can be done by simply casting it to a far
  120.      * 
  121.      ********************************************************/
  122. REALPTR FARCPTR_TO_REALPTR(FARPTR p);
  123.  
  124. extern USHORT GetCS();
  125. extern USHORT GetDS();
  126.  
  127.  
  128. #endif   /* DOS386 */
  129.  
  130. /****************** External Prototypes *****************************/
  131.  
  132. extern void TIPPrintUsage(char *arg);
  133.  
  134. #ifndef DOS386
  135. extern UDIError UDIASMDisconnect UDIParams((
  136.   UDISessionId        Session,        /* In */
  137.   UDIBool        Terminate,        /* In */
  138.   DOSTerm              far *TermStruct     /* In - not seen in UDIP */
  139.   ));
  140. extern UDIError UDIASMConnect UDIParams((
  141.   char            *Configuration,        /* In */
  142.   UDISessionId        *Session,        /* Out */
  143.   DOSTerm              far *TermStruct     /* In - not seen in UDIP */
  144.   ));
  145.  
  146. #endif
  147.  
  148. /****************** Internal Prototypes *****************************/
  149.  
  150. UDIError UDICCapabilities UDIParams((
  151.   UDIUInt32    *TIPId,            /* Out */
  152.   UDIUInt32    *TargetId,        /* Out */
  153.   UDIUInt32    DFEId,            /* In */
  154.   UDIUInt32    DFE,            /* In */
  155.   UDIUInt32    *TIP,            /* Out */
  156.   UDIUInt32    *DFEIPCId,        /* Out */
  157.   UDIUInt32    *TIPIPCId,        /* Out */
  158.   char        *TIPString        /* Out */
  159.   ));
  160.  
  161. static unsigned short GetPSP( void );
  162. static void SetPSP( unsigned short PSPSegment );
  163. static unsigned int ComputeTSRSize(void *topofstack);
  164. static void SetupEnvironment(void);
  165. static void TerminateTIP UDIParams((DOSTerm           IPCFar *TermStruct));
  166.  
  167.  
  168. /****************** External and Static Data *****************************/
  169. static int ConnectCount;
  170.  
  171. #ifdef DOS386
  172.  
  173. char    *conventional_memory;    /* pointer to first byte of conventinal memory */
  174.                                 /* if 0, then conventional mem not mapped */
  175. USHORT  our_tsr_psp;        /* TIP's original PSP */
  176. USHORT  dos_ext_psp;        /* Dos extender PSP (TIP's parent) */
  177. extern  REALPTR  call_prot;    /* These are in the module dostip.asm */
  178. extern  USHORT   code_selector;
  179. extern  USHORT   data_selector;
  180. extern  USHORT    segregblock[4];
  181. extern  int end_real;        /* marks end of stuff that must be placed in low mem */
  182. int * stack_table[3];        /* used when we need to get a new stack frame
  183.                  * to establish C context on each UDI call 
  184.                  * but only if conventional memory didn't map */
  185. REALPTR     real_basep;        /* returned by realcopy */
  186. FARPTR     prot_basep;        /* returned by realcopy */
  187. USHORT     rmem_adrp;        /* returned by realcopy */
  188.  
  189. extern char TIPName[];            /* in DOS386, defined in rmdata in dosdfe.asm */
  190. extern struct UDIVecRec TIPVecRec;    /* in DOS386, defined in rmdata in dosdfe.asm */
  191.  
  192.  
  193.  
  194. #else    /* non-DOS386 static and external data */
  195.  
  196. char TIPName[ FILENAME_MAX ];        /* in non-386 version, TIPName defined right here */
  197. struct UDIVecRec TIPVecRec = {        /* in non-386 version, TIPVecRec defined right here */
  198.     UDIDOSTIPRecognizer,    /* Initialized in main */
  199.     NULL,            /* Pointer to next TIP */
  200.     NULL,            /* Pointer to previous TIP */
  201.     TIPName,            /* Name of the executable we were loaded as */
  202.     UDIASMConnect,
  203.     UDIASMDisconnect,
  204.     UDISetCurrentConnection,
  205.     UDICCapabilities,
  206.     UDIGetErrorMsg,
  207.     UDIGetTargetConfig,
  208.     UDICreateProcess,
  209.     UDISetCurrentProcess,
  210.     UDIDestroyProcess,
  211.     UDIInitializeProcess,
  212.     UDIRead,
  213.     UDIWrite,
  214.     UDICopy,
  215.     UDIExecute,
  216.     UDIStep,
  217.     UDIStop,
  218.     UDIWait,
  219.     UDISetBreakpoint,
  220.     UDIQueryBreakpoint,
  221.     UDIClearBreakpoint,
  222.     UDIGetStdout,
  223.     UDIGetStderr,
  224.     UDIPutStdin,
  225.     UDIStdinMode,
  226.     UDIPutTrans,
  227.     UDIGetTrans,
  228.     UDITransMode
  229.    };
  230. #endif
  231.  
  232. struct UDIVecRec IPCFar * pTIPVecRec;    /* pointer to TIPVecRec */
  233.                     /* in DOS386, this points to real memory */
  234. static RealUDIVecRecPtr IPCFar * UDIVecP;
  235.  
  236. static int loaded_from_exp_file = 0;
  237.  
  238.  
  239. void do_exit(int errcode)
  240. {
  241.   /* this routine normally just calls exit but in the special case
  242.    * of DOS386 mode AND we were loaded from a .exp file, then we want
  243.    * to exit in a different way by calling exp_return
  244.    */
  245. #ifdef DOS386
  246. extern void _exp_return(int err);
  247.     if (loaded_from_exp_file)
  248.     _exp_return(errcode);
  249.     else
  250. #endif
  251.         /* normal non-DOS386 and non-exp_file exit */
  252.     exit(errcode);
  253. }
  254.  
  255.  
  256. void do_dos_keep(int errcode, int tsrsize)
  257. {
  258.   /* similar logic to do_exit above, but this time for dos_keep
  259.    */
  260. #ifdef DOS386
  261. extern void _exp_return(int err);
  262.     if (loaded_from_exp_file)
  263.     _exp_return(errcode);
  264.     else
  265. #endif
  266.         /* normal non-DOS386 and non-exp_file dos_keep */
  267.         _dos_keep( 0, tsrsize );
  268. }
  269.  
  270. void get_tip_name(int argc, char *argv[])
  271. {
  272.   /* This routine normally gets the Tipname from argv[1], but
  273.    * in the special case of DOS386 and loaded as an exp file,
  274.    * it gets the name from the stack
  275.    */
  276.  
  277. #ifdef DOS386
  278.     extern  char * _top;
  279.  
  280.     if ((GetCS() & 0xfffc) != SS_CODE) {
  281.         /* a CS that is not SS_CODE indicates that we were
  282.        loaded as a .exp file.  In that case, we don't
  283.        want to exit or do a TSR, instead we want to return
  284.        back to the DFE using _exp_return.
  285.         */
  286.           loaded_from_exp_file = TRUE;
  287.     strcpy(TIPName, _top+16);
  288.     return;
  289.     }
  290. #endif
  291.     
  292.     if ((argc!= 2)  || (argv[1][0] == '-')) {
  293.     TIPPrintUsage(argv[1]);
  294.     do_exit( 1 );
  295.     }
  296.  
  297.     strcpy( TIPName, argv[1] );
  298. }
  299.  
  300.  
  301. #ifdef DOS386
  302. REALPTR FARCPTR_TO_REALPTR(FARCPTR p)    /* converts a FAR PROT ptr to a REALPTR */
  303. {
  304. REALPTR  dummyrp;
  305. int   err;
  306.  
  307.         /* returns a real mode pointer given a prot mode pointer p */
  308.     err = _dx_toreal(p, 0, &dummyrp);
  309.     if (err) {
  310.        printf("Fatal Error _dx_toreal(%04x:%08x)\n", FP_SEG(p), FP_OFF(p));
  311.        do_exit(err);
  312.     }
  313.     else
  314.        return(dummyrp);
  315.     
  316. }
  317.  
  318.  
  319. FARCPTR  REALPTR_TO_FARCPTR(REALPTR rp)
  320. {
  321. FARCPTR   dummyfp;
  322.     FP_SET(dummyfp, LINEARIZE(rp), SS_DOSMEM);
  323.     return(dummyfp);
  324. }
  325.  
  326. /*****************
  327.  * Routine used to create and initialize a stack for C context stack switching
  328.  * (used only when conventional memory can't be mapped
  329.  ****************/
  330. static void create_stack(int stack_index, int size_in_bytes)
  331. {
  332. int *p;
  333. int  index_to_last_int;
  334.  
  335.     /* malloc appropriate size and point stack_table entry to second last word */
  336.     p = (int *)malloc(size_in_bytes);
  337.     if (p == 0) {
  338.         printf("\nTIP: unable to malloc stacks\n");
  339.         do_exit(1);
  340.     }
  341.     index_to_last_int =  (size_in_bytes/sizeof(int)) - 1;
  342.     stack_table[stack_index] = &p[index_to_last_int-1];
  343.  
  344.     /* and set last word to 0 (marked as free) */
  345.     /* set second last word to stack size (used for alloca checking) */
  346.     p[index_to_last_int-1]   = size_in_bytes-8;
  347.     p[index_to_last_int] = 0;
  348. }
  349. #endif
  350.  
  351.  
  352.  
  353. static void TerminateTIP UDIParams((
  354.   DOSTerm              IPCFar *TermStruct     /* In - not seen in UDIP */
  355.   ))
  356. {
  357.     /* Delink ourselves from the linked list of TIPs */
  358.     if (pTIPVecRec->Next != REALNULL)
  359.     ((struct UDIVecRec IPCFar *)REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = pTIPVecRec->Prev;
  360.     if (pTIPVecRec->Prev != REALNULL)
  361.     ((struct UDIVecRec IPCFar *)REALPTR_TO_FARCPTR(pTIPVecRec->Prev))->Next = pTIPVecRec->Next;
  362.     else
  363.     *UDIVecP = pTIPVecRec->Next;    /* no previous TIP, set the interrupt vector
  364.                        to point to our Next TIP */
  365.  
  366. #ifdef DOS386
  367. {
  368.     if (loaded_from_exp_file)     /* if we were loaded from an exp file, skip all this PSP stuff */
  369.     return;
  370.  
  371.     /* Under DOSEXT, our PSP is parented by the DOSEXTENDER's PSP */
  372.     /* We want to modify the DOSEXT's PSP to point to the DFE info */
  373. REALPTR ptr_dos_ext_psp_parent;
  374. REALPTR ptr_dos_ext_psp_termaddr;
  375.  
  376.     /* Set the dos_ext_psp's Parent PSP to the current PSP (ie, the DFE PSP)*/
  377.     RP_SET(ptr_dos_ext_psp_parent,0x16, dos_ext_psp);
  378.     *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp_parent))) = GetPSP();
  379.  
  380.     /* Set the dos_ext_psp's Terminate address to reasonable address in
  381.        current PSP (DFE)'s program space */
  382.     RP_SET(ptr_dos_ext_psp_termaddr,0xa, dos_ext_psp);
  383.     *((ULONG _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp_termaddr))) = (ULONG) TermStruct->TermFunc;
  384. }
  385. #else
  386.     /* Set our TSR's PSP's Parent PSP to the current PSP */
  387.     fflush(fpstdout);
  388.  
  389.     *(unsigned _far *)(((long)_psp << 16) + 0x16) = GetPSP();
  390.  
  391.     /* Set our TSR's PSP's Terminate address to reasonable address in
  392.        current PSP's program space */
  393.     /*(void _far (_far *) (void))(((long)_psp << 16) + 0xa) = ExitAddr;*/
  394.     *(void (_far *(_far *))(void))(((long)_psp << 16) + 0xa) =
  395.     TermStruct->TermFunc;
  396. #endif
  397.  
  398.     /* Change DOS's notion of what the current PSP is to be our TSR's PSP */
  399. #ifdef DOS386
  400.     SetPSP(our_tsr_psp); 
  401.     /* Under Dosext, termination will chain back from our_psp to DOSEXT PSP */
  402.     /* and then back to the DFE (since we modified the DOSEXT PSP above)    */
  403. #else
  404.     SetPSP(_psp );
  405. #endif
  406.  
  407.     /* Terminate the program by using DOSTerminate 0x21/0x4c. Execution
  408.        will resume at the Terminate address set above with ALL REGISTERS
  409.        UNKNOWN especially SS:SP, DS, ES, etc */
  410.     bdos( 0x4c, 0, 0 );
  411.     }
  412.  
  413. UDIError UDICConnect UDIParams((
  414.   char            *Configuration,        /* In */
  415.   UDISessionId        *Session,        /* Out */
  416.   DOSTerm              IPCFar *TermStruct     /* In - not seen in UDIP */
  417.   ))
  418. {
  419.     UDIError err;
  420.  
  421.     if ((err = UDIConnect( Configuration, Session )) <= UDINoError)
  422.     ConnectCount++;
  423.  
  424.     if (ConnectCount == 0) {    /* Terminate the unused TIP */
  425.     /* Save the error status in the TermStruct */
  426.     TermStruct->retval = err;
  427.  
  428.     TerminateTIP( TermStruct );    /* Never returns */
  429.     }
  430.  
  431.     return err;
  432.     }
  433.  
  434. UDIError UDICDisconnect UDIParams((
  435.   UDISessionId        Session,        /* In */
  436.   UDIBool        Terminate,        /* In */
  437.   DOSTerm              IPCFar *TermStruct     /* In - not seen in UDIP */
  438.   ))
  439. {
  440.     UDIError err;
  441.  
  442.     /* Disconnect via the real TIP */
  443.     if ((err = UDIDisconnect( Session, Terminate )) == UDINoError)
  444.     ConnectCount--;
  445.  
  446.     if (Terminate != UDIContinueSession && ConnectCount == 0) {
  447.     /* Terminate the unused TIP */
  448.     /* Save the error status in the TermStruct */
  449.     TermStruct->retval = err;
  450.  
  451.     TerminateTIP( TermStruct );    /* Never returns */
  452.     }
  453.  
  454.     return err;
  455.     }
  456.  
  457. UDIError UDICCapabilities UDIParams((
  458.   UDIUInt32    *TIPId,            /* Out */
  459.   UDIUInt32    *TargetId,        /* Out */
  460.   UDIUInt32    DFEId,            /* In */
  461.   UDIUInt32    DFE,            /* In */
  462.   UDIUInt32    *TIP,            /* Out */
  463.   UDIUInt32    *DFEIPCId,        /* Out */
  464.   UDIUInt32    *TIPIPCId,        /* Out */
  465.   char        *TIPString        /* Out */
  466.   ))
  467. {
  468.     UDIError err;
  469.  
  470.     err = UDICapabilities( TIPId, TargetId, DFEId, DFE, TIP,
  471.                 DFEIPCId, TIPIPCId, TIPString );
  472.  
  473.     *TIPIPCId = (((UDIUInt32)TIPIPCIdCompany) << 16) |
  474.             (TIPIPCIdProduct << 12) | TIPIPCIdVersion;
  475.  
  476.     return err;
  477.     }
  478.  
  479.  
  480. static RealUDIVecRecPtr IPCFar * AllocateIntVect()
  481. {
  482.     RealUDIVecRecPtr IPCFar * VecP;
  483.  
  484.     /* Try and find a vector that is unused */
  485.     for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));
  486.      VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));
  487.      VecP++) {
  488.     if (*VecP == REALNULL)
  489.         return VecP;
  490.     }
  491.  
  492.     return NULL;
  493.     }
  494.  
  495. static RealUDIVecRecPtr IPCFar * FindIntVect()
  496. {
  497.     RealUDIVecRecPtr IPCFar * VecP;
  498.     union rec recognizer;
  499.  
  500.     InitRecognizer( &recognizer );
  501.  
  502.     /* Try and find a vector that matches the passed in recognizer */
  503.     for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));
  504.      VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));
  505.      VecP++) {
  506.     if ((*VecP != REALNULL) && ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(*VecP))->recognizer.l == recognizer.l)
  507.             return VecP;
  508.     }
  509.      
  510.     return NULL;
  511. }
  512.  
  513. static void SetupEnvironment(void)
  514. {
  515. #ifndef DOS386
  516.         /* if not DOS386, nothing to do except set up the
  517.            pointer to TIPVecRec
  518.            */
  519.         pTIPVecRec = &TIPVecRec;
  520.  
  521. #else        /* setup code for DOS386 */
  522. FARPTR  dummyfp;
  523. REALPTR dummyrp;
  524. ULONG   dummyint;
  525. REALPTR IPCFar *p;
  526. REALPTR ptr_dos_ext_psp;
  527. int     err;
  528. int    i;
  529.  
  530.     /**************************************************************
  531.      * There are some initialization things that we might as well do before
  532.      * we do the realcopy down below.  Here we do some initialization
  533.      * of TIPVecRec and the code_selector and data_selector and call_prot
  534.      * routine address that are then used by the real mode code.
  535.      ****************************************************************/
  536.  
  537.     _dx_rmlink_get(&call_prot, &dummyrp, &dummyint, &dummyfp);
  538.     code_selector = GetCS();
  539.     data_selector = GetDS();
  540.     for (i=0; i<4; i++)
  541.         segregblock[i] = data_selector;
  542.     
  543.     /******************************************************
  544.      * Map first 1 meg of physical memory into our ds: address space
  545.      * This is 256 4K pages starting at physical address 0.
  546.      * The pointer conventional_memory is its mapped offset in our data space
  547.      * If this mapping cannot be done (because we are running under DPMI 0.90)
  548.      * then we will have to access dos memory using far pointers and do some
  549.      * copies of data down in the d386 routines.
  550.      ********************************************************/ 
  551.     err = _dx_map_phys(data_selector, (ULONG) 0, (ULONG) 256, (ULONG *)&conventional_memory);
  552.     if (err) 
  553.         conventional_memory = NULL;
  554.  
  555. #ifdef DEBUG
  556.         if (err) 
  557.         printf("TIP: Unable to map conventional memory %d\n", err);
  558.     else 
  559.         printf("TIP: Successfully mapped conventional memory\n");
  560. #endif
  561.  
  562.         if (!conventional_memory) {
  563.        /* mapping conventional memory did not work */
  564.        /* need to set up stacks to switch to at UDI call time */
  565.         create_stack(0, 64000);
  566.         create_stack(1, 10000);
  567.         stack_table[2] =  0;    /* end of list */
  568.       }
  569.  
  570.         /* do a realcopy to copy all the things that must be reachable
  571.        * from real mode into a real mode segment.  For simplicity,
  572.        * we just always assume that REALBREAK might not work.
  573.        * This is only used at TIP INIT time and the performance impact is negligent.
  574.        */
  575.          err = realcopy(0,              /* real mode stuff was linked first */
  576.                         end_real,         /* where the real mode stuff ends */
  577.             &real_basep,
  578.             &prot_basep,
  579.             &rmem_adrp);
  580.  
  581.         if (err) {
  582.             printf("\nTIP: realcopy call failed;\n");
  583.                 printf(  "     Probable cause: insufficient free conventional memory.\n");
  584.                 do_exit(1);
  585.         }
  586.  
  587.  
  588.         /* The prot_basep that was returned above must now be used
  589.        to access from protected mode the data elements that were
  590.        copied above.  In particular, we create a pointer to the
  591.        copied TIPVecRec and use that.
  592.      */
  593.         pTIPVecRec = (struct UDIVecRec IPCFar *) (prot_basep + (ULONG) &TIPVecRec);
  594.  
  595.          
  596.  
  597.     /**************************************************************
  598.      * The real_basep that was returned from realcopy must be used as
  599.      * the code segment pointer of all the real mode routines.
  600.      * and so must be patched into TIPVecRec.
  601.      * real_basep is returned by realcopy such that the offset parts
  602.      * (as assembled in in the module dostip.asm) can remain unchanged.
  603.      * So we just need to patch the real_basep seg into each of those pointers
  604.      ***************************************************************/
  605.     for (p = (REALPTR IPCFar *)&pTIPVecRec->exeName;
  606.          p<= (REALPTR IPCFar *)&pTIPVecRec->UDITransMode; p++) {
  607.         RP_SET(*p, RP_OFF(*p), RP_SEG(real_basep)); 
  608.     }
  609.  
  610.     /*****************************************************
  611.        Store our PSP (real segment) away for later termination
  612.        and also the dos extender's PSP (our parent).  We get this by 
  613.        building a real pointer with seg = our_tsr_psp, ofst = 0x16,
  614.        and then derefencing that
  615.     *****************************************************/
  616.     our_tsr_psp = GetPSP();
  617.     RP_SET(ptr_dos_ext_psp, 0x16, our_tsr_psp);
  618.     dos_ext_psp = *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp)));
  619.  
  620. #endif    /* end of DOS386 setup code */
  621. }
  622.  
  623.  
  624. static unsigned int ComputeTSRSize(void *topofstack)
  625. {
  626. #ifndef DOS386
  627.     /* Real mode program, compute program size */
  628.     /* Huge pointers force compiler to do segment arithmetic for us. */
  629. static char _huge *tsrstack;
  630. static char _huge *tsrbottom;
  631.     /* Initialize stack and bottom of program. */
  632.     tsrstack = (char huge *)topofstack;
  633.     FP_SEG( tsrbottom ) = _psp;
  634.     FP_OFF( tsrbottom ) = 0;
  635.  
  636.     /* Program size is:
  637.      *       top of stack
  638.      *     - bottom of program (converted to paragraphs) (using huge math)
  639.      *     + one extra paragraph
  640.      */
  641.     return((unsigned int) (((tsrstack - tsrbottom) >> 4) + 1));
  642. #else
  643.     /*********************
  644.      In DOS386 mode, the TSR size consists of the real memory that
  645.      is used by the Pharlap DOS extender and the small amount of real memory
  646.      used by UDI.  The number 6400 seems to be a good guess for now.
  647.      This might have to be adjusted with newer versions of Dos extender, etc.
  648.      I wonder if there is some way to compute this number accurately.
  649.          **********************/
  650.     return(6400);    /* our best guess for now */
  651. #endif
  652. }
  653.  
  654. main(int argc, char *argv[])
  655. {
  656.     unsigned tsrsize;
  657.  
  658.     get_tip_name(argc, argv);    /* get name from argv or whereever */
  659.  
  660. #ifdef TSRDEBUG
  661.     {
  662.     int i;
  663.     printf( "Invoked with %d arguments\n", argc );
  664.     for (i = 0; i < argc; i++)
  665.     printf( "%s ", argv[i] );
  666.     printf( "\n" );
  667.     }
  668. #endif
  669.  
  670.     InitRecognizer(&TIPVecRec.recognizer );
  671.  
  672.     SetupEnvironment();        /* do some setup specific to DOS or DOS386 */
  673.  
  674.  
  675.     /* See if the interrupt vector has already been selected for us */
  676.     if ((UDIVecP = FindIntVect()) == NULL) {
  677.     if ((UDIVecP = AllocateIntVect()) == NULL)
  678.         return -1;    /* No interrupt vectors available */
  679.     }
  680.     else {    /* Interrupt vector already allocated */
  681.     pTIPVecRec->Next = *UDIVecP;        /* always store a real ptr there */
  682.     ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = FARCPTR_TO_REALPTR(pTIPVecRec);
  683.     }
  684.  
  685.     *UDIVecP = FARCPTR_TO_REALPTR(pTIPVecRec);
  686.  
  687.     tsrsize = ComputeTSRSize(&argv);    /* pass it pointer to argv (top of stack) */
  688.  
  689.     /* We are now ready to support DFEs. If we wish to debug back-ends,
  690.        though, we are probably running CodeView with the TIP right now
  691.        and don't want to really TSR because CV will shut down at that
  692.        point. Instead, let's spawn a new DOS shell from which we can
  693.        start a DFE (after setting a breakpoint in the TIP somewhere).
  694.     */
  695. #ifdef TSRDEBUG
  696.     system( getenv( "COMSPEC" ) );
  697. #else
  698.     do_dos_keep(0, tsrsize);
  699. #endif
  700.  
  701.     return 0;
  702. }
  703.  
  704.  
  705. #define GET_PSP_DOS2    0x51
  706. #define GET_PSP_DOS3    0x62
  707. #define SET_PSP     0x50
  708.  
  709. static unsigned short GetPSP( void )
  710. {
  711.     union REGS regs;
  712.  
  713.     if (_osmajor == 2)
  714.     return 0;
  715. #ifdef DOS386
  716.     regs.h.ah = GET_PSP_DOS2;    /* Phar Lap requires we use this to get real segment */
  717. #else
  718.     regs.h.ah = GET_PSP_DOS3;
  719. #endif
  720.     intdos( ®s, ®s );
  721.     return regs.x.bx;
  722. }
  723.  
  724. static void SetPSP( unsigned short PSPSegment )
  725. {
  726.     union REGS regs;
  727.  
  728.     regs.h.ah = SET_PSP;
  729.     regs.x.bx = PSPSegment;
  730.     intdos( ®s, ®s );
  731. }
  732.  
  733.  
  734. #ifdef DOS386
  735. /*============================ DOS386 glue routines ====================================*/
  736.  
  737. /****************************************************************
  738.  * In DPMI Compatibility mode, when we get to this point, the only
  739.  * thing that is on the stack is the saved far stack pointer (which actually
  740.  * points back to the real mode stack).   Remember in pmstub in dostip.asm,
  741.  * we switched stack pointers so that SS = DS for C level requirements.
  742.  *
  743.  * The INCOMING_PARAMS macro defines a packed structure which expresses what the
  744.  * real mode stack really looks like when we get to each dos386 glue routine. 
  745.  * The STACK_PAD is all the extra stuff that was on the stack because of the switching
  746.  * from real to protected mode, etc.
  747.  * The packed structure can be used to express where things really are on the stack
  748.  * because the DFE's MSC compiler will push things differently from the hc386 compiler.
  749.  ********************************************************************/
  750. typedef _packed struct {
  751.     FARPTR  ret_to_dosext;
  752.     USHORT    zero_word;
  753.     USHORT  saved_di;
  754.     USHORT  saved_si;
  755.     USHORT  saved_bp;
  756.     USHORT  saved_ds;
  757.     ULONG    ret_to_dfe;
  758. } STACK_PAD;
  759.  
  760. /* The following macro defines the packed structure for the incoming parameters
  761.  * including the STACK_PAD stuff noted above.  It is used by those few d386_
  762.  * routines that do not need converted pointers to avoid non-use warnings
  763.  */
  764. #define INCOMING_PARAMS_NO_PTR(params)  \
  765.     _packed struct {        \
  766.         STACK_PAD padding;            \
  767.         params            \
  768.     } _far *in  = rm_stk_ptr;     \
  769.  
  770.  
  771. /* The following macro defines the packed structure for the incoming parameters
  772.  * (see above) and also defines a local structure for storing the converted local
  773.  * pointers.  Most d386_ routines use this macro.
  774.  */
  775. #define INCOMING_PARAMS(params)       \
  776.     INCOMING_PARAMS_NO_PTR(params)     \
  777.     struct {            \
  778.         params            \
  779.         int dummy;     /* to avoid warnings and for local count */          \
  780.     } local ;    /* local structure for holding converted pointers */  \
  781.     int  stackspace = stacksize;    \
  782.  
  783.  
  784.  
  785. /**************************************************************
  786.  * The following macros handle the creation of near C pointers from real pointers
  787.  * so that the real UDI routines can be called with near C pointers.
  788.  * Different macros are called for IN pointers vs. OUT pointers and
  789.  * for PREPROCESSING (before the real UDI call) and POSTPROCESSING (cleanup
  790.  * after returning from the real UDI call).
  791.  *
  792.  * If conventional_memory has been mapped, the following happens
  793.  *    PREPROCESS (IN or OUT ptr) sets local.var pointer to the mapped pointer
  794.  *                   nothing to copy so count is ignored
  795.  *    POSTPROCESS           nothing to do 
  796.  *
  797.  * If conventional_memory has not been mapped, then
  798.  *    PREPROCESS (IN ptr)        does alloca of count to get local pointer
  799.  *                   copies data into local allocated area
  800.  *    PREPROCESS (OUT ptr)        does alloca of count to get local pointer
  801.  *                   no copy of data yet.
  802.  *    POSTPROCESS (OUT ptr)       copies data from local allocated area back to real mem
  803.  * 
  804.  * Note that a few UDI routines have pointers that are both IN and OUT
  805.  */
  806.  
  807.     /* the following is used in a couple of places in the macros */
  808. #define ALLOC_LOCAL(var, count) \
  809.     if ((stackspace -= count) <= 500) return(UDIErrorIPCLimitation); \
  810.     local.var = alloca(count); 
  811.  
  812. #define INPTR_PREPROCESS_COUNT(var,count)  \
  813.     if (conventional_memory) { \
  814.     local.var = REALPTR_TO_NEARCPTR(in->var); \
  815.     } \
  816.     else { \
  817.     local.dummy = count;    /* avoid double evaluation if count is expression */   \
  818.     ALLOC_LOCAL(var, local.dummy); \
  819.     movedata(SS_DOSMEM, LINEARIZE(in->var), data_selector, (unsigned int) local.var, local.dummy); \
  820.     }
  821.  
  822.  
  823. #define INPTR_PREPROCESS(var) INPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))
  824.  
  825. #define OUTPTR_PREPROCESS_COUNT(var,count)  \
  826.     if (conventional_memory)  \
  827.     local.var = REALPTR_TO_NEARCPTR(in->var); \
  828.     else { \
  829.     ALLOC_LOCAL(var,count); \
  830.     }
  831.  
  832. #define OUTPTR_PREPROCESS(var) OUTPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))
  833.  
  834. #define OUTPTR_POSTPROCESS_COUNT(var,count)  \
  835.     if (!conventional_memory) {\
  836.     movedata(data_selector, (unsigned int)local.var, SS_DOSMEM, LINEARIZE(in->var), count); \
  837.     }
  838.  
  839. #define OUTPTR_POSTPROCESS(var) OUTPTR_POSTPROCESS_COUNT(var, sizeof(*(in->var)))
  840.  
  841.  
  842.  
  843. /* The following routine computes the length of a string that
  844.  * is pointed to by a real pointer.  This is only needed when
  845.  * we cannot map real mode memory at the end of the DS.
  846.  */
  847. int realptr_strlen(REALPTR rp) 
  848. {
  849. char _far *farp;
  850. char _far *start;
  851.  
  852.     farp = (char _far *) REALPTR_TO_FARCPTR(rp);   /* need to use a far c ptr */
  853.     start = farp;
  854.     while (*farp++);       /* advance until a 0 located */
  855.     return(FP_OFF(farp) - FP_OFF(start));
  856. }
  857.  
  858. /*========================  Glue Routines ============================================*/
  859.  
  860.  
  861. UDIError d386_UDIConnect (void _far * rm_stk_ptr, int stacksize)
  862. INCOMING_PARAMS(
  863.   char        *Configuration;        /* In  */
  864.   UDISessionId    *Session;        /* Out */
  865.   DOSTerm           *TermStruct;     /* In - not seen in UDIP */
  866. )
  867. UDIError err;
  868.  
  869.     INPTR_PREPROCESS_COUNT(Configuration, realptr_strlen((REALPTR)(in->Configuration))+1);
  870.     OUTPTR_PREPROCESS(Session);
  871.  
  872.     err = UDICConnect(       /* for UDIConnect, special case, call UDICConnect in dos2udip.c */
  873.     local.Configuration,
  874.     local.Session,
  875.     REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)
  876.     );
  877.  
  878.     OUTPTR_POSTPROCESS(Session);
  879.     return(err);
  880. }
  881.  
  882. UDIError d386_UDIDisconnect (void _far * rm_stk_ptr, int stacksize)
  883. {
  884. INCOMING_PARAMS(
  885.   UDISessionId    Session;        /* In */
  886.   UDIBool    Terminate;
  887.   DOSTerm           *TermStruct;         /* In - not seen in UDIP */
  888. )
  889. UDIError err;
  890.  
  891.     local.dummy = 0;                    /* avoids warning */
  892.     err = UDICDisconnect(        /* need to call UDICDisconnect */
  893.     in->Session,
  894.     in->Terminate,
  895.     REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)
  896.     );
  897.     return(err);
  898.         
  899. }
  900.  
  901.  
  902. UDIError d386_UDISetCurrentConnection  (void _far * rm_stk_ptr, int stacksize)
  903. {
  904. INCOMING_PARAMS_NO_PTR(
  905.   UDISessionId    Session;        /* In */
  906. )
  907.     return(UDISetCurrentConnection(in->Session));
  908. }
  909.  
  910.  
  911. UDIError d386_UDICapabilities  (void _far * rm_stk_ptr, int stacksize)
  912. {
  913. INCOMING_PARAMS(
  914.   UDIUInt32    *TIPId;            /* Out */
  915.   UDIUInt32    *TargetId;        /* Out */
  916.   UDIUInt32    DFEId;            /* In */
  917.   UDIUInt32    DFE;            /* In */
  918.   UDIUInt32    *TIP;            /* Out */
  919.   UDIUInt32    *DFEIPCId;        /* Out */
  920.   UDIUInt32    *TIPIPCId;        /* Out */
  921.   char        *TIPString;        /* Out */
  922. )
  923. UDIError err;
  924.  
  925.     OUTPTR_PREPROCESS(TIPId);
  926.     OUTPTR_PREPROCESS(TargetId);
  927.     OUTPTR_PREPROCESS(TIP);
  928.     OUTPTR_PREPROCESS(DFEIPCId);
  929.     OUTPTR_PREPROCESS(TIPIPCId);
  930.     OUTPTR_PREPROCESS_COUNT(TIPString, 100);   /* max TIP string? */
  931.  
  932.     err = UDICCapabilities(        /* another special case call UDICapabilities */
  933.     local.TIPId,
  934.     local.TargetId,
  935.     in->DFEId,
  936.     in->DFE,
  937.     local.TIP,
  938.     local.DFEIPCId,
  939.     local.TIPIPCId,
  940.     local.TIPString
  941.     );
  942.  
  943.     OUTPTR_POSTPROCESS(TIPId);
  944.     OUTPTR_POSTPROCESS(TargetId);
  945.     OUTPTR_POSTPROCESS(TIP);
  946.     OUTPTR_POSTPROCESS(DFEIPCId);
  947.     OUTPTR_POSTPROCESS(TIPIPCId);
  948.     OUTPTR_POSTPROCESS_COUNT(TIPString, strlen(local.TIPString)+1);
  949.  
  950.     return(err);
  951. }
  952.  
  953.  
  954. UDIError d386_UDIGetErrorMsg  (void _far * rm_stk_ptr, int stacksize)
  955. {
  956. INCOMING_PARAMS(
  957.   UDIError    ErrorCode;        /* In */
  958.   UDISizeT    MsgSize;        /* In */
  959.   char        *Msg;            /* Out */
  960.   UDISizeT    *CountDone;        /* Out */
  961. )
  962. UDIError err;
  963.  
  964.     OUTPTR_PREPROCESS_COUNT(Msg, in->MsgSize);
  965.     OUTPTR_PREPROCESS(CountDone);
  966.     
  967.     err = UDIGetErrorMsg(
  968.     in->ErrorCode,
  969.     in->MsgSize,
  970.     local.Msg,        /* pointers made local */
  971.     local.CountDone
  972.     );
  973.  
  974.     OUTPTR_POSTPROCESS_COUNT(Msg, *(local.CountDone)+1);
  975.     OUTPTR_POSTPROCESS(CountDone);
  976.     return(err);
  977. }
  978.  
  979.  
  980.  
  981. UDIError d386_UDIGetTargetConfig (void _far * rm_stk_ptr, int stacksize)
  982. {
  983. INCOMING_PARAMS(
  984.   UDIMemoryRange *KnownMemory;        /* Out */
  985.   UDIInt    *NumberOfRanges;    /* In/Out */
  986.   UDIUInt32    *ChipVersions;        /* Out */
  987.   UDIInt    *NumberOfChips;        /* In/Out */
  988. )
  989. UDIError err;
  990.  
  991.     INPTR_PREPROCESS(NumberOfRanges);
  992.     INPTR_PREPROCESS(NumberOfChips);
  993.     OUTPTR_PREPROCESS_COUNT(KnownMemory, *(local.NumberOfRanges) * sizeof(UDIMemoryRange));
  994.     OUTPTR_PREPROCESS_COUNT(ChipVersions, *(local.NumberOfChips) * sizeof(UDIUInt32));
  995.  
  996.     err = UDIGetTargetConfig(
  997.       local.KnownMemory,
  998.       local.NumberOfRanges,
  999.       local.ChipVersions,
  1000.       local.NumberOfChips
  1001.     );
  1002.  
  1003.     OUTPTR_POSTPROCESS(NumberOfRanges);
  1004.     OUTPTR_POSTPROCESS(NumberOfChips);
  1005.     OUTPTR_POSTPROCESS_COUNT(KnownMemory, *(local.NumberOfRanges) * sizeof(UDIMemoryRange));
  1006.     OUTPTR_POSTPROCESS_COUNT(ChipVersions, *(local.NumberOfChips) * sizeof(UDIUInt32));
  1007.  
  1008.     return(err);
  1009. }
  1010.  
  1011. UDIError d386_UDICreateProcess (void _far * rm_stk_ptr, int stacksize)
  1012. {
  1013. INCOMING_PARAMS(
  1014.   UDIPId    *PId;            /* Out */
  1015. )
  1016. UDIError err;
  1017.  
  1018.     OUTPTR_PREPROCESS(PId);
  1019.  
  1020.     err = UDICreateProcess(
  1021.     local.PId
  1022.     );
  1023.  
  1024.     OUTPTR_POSTPROCESS(PId);
  1025.     return(err);
  1026. }
  1027.  
  1028. UDIError d386_UDISetCurrentProcess (void _far * rm_stk_ptr, int stacksize)
  1029. {
  1030. INCOMING_PARAMS_NO_PTR(
  1031.   UDIPId    PId;            /* In */
  1032.   )
  1033.  
  1034.     return(UDISetCurrentProcess(
  1035.     in->PId
  1036.     ));
  1037. }
  1038.  
  1039. UDIError d386_UDIDestroyProcess (void _far * rm_stk_ptr, int stacksize)
  1040. {
  1041. INCOMING_PARAMS_NO_PTR(
  1042.   UDIPId    PId;            /* In */
  1043.   )
  1044.  
  1045.     return(UDIDestroyProcess(
  1046.     in->PId
  1047.     ));
  1048. }
  1049.  
  1050.  
  1051.  
  1052. UDIError d386_UDIInitializeProcess (void _far * rm_stk_ptr, int stacksize)
  1053. {
  1054. INCOMING_PARAMS(
  1055.   UDIMemoryRange *ProcessMemory;    /* In */
  1056.   UDIInt    NumberOfRanges;        /* In */
  1057.   UDIResource    EntryPoint;        /* In */
  1058.   CPUSizeT    *StackSizes;        /* In */
  1059.   UDIInt    NumberOfStacks;        /* In */
  1060.   char        *ArgString;        /* In */
  1061.   )
  1062. UDIError err;
  1063.  
  1064.     INPTR_PREPROCESS_COUNT(ProcessMemory, in->NumberOfRanges * sizeof(UDIMemoryRange));
  1065.     INPTR_PREPROCESS_COUNT(StackSizes, in->NumberOfStacks * sizeof(CPUSizeT));
  1066.     INPTR_PREPROCESS_COUNT(ArgString, realptr_strlen((REALPTR)(in->ArgString))+1);
  1067.  
  1068.     err = UDIInitializeProcess(
  1069.     local.ProcessMemory,
  1070.     in->NumberOfRanges,
  1071.     in->EntryPoint,
  1072.     local.StackSizes,
  1073.     in->NumberOfStacks,
  1074.     local.ArgString
  1075.     );
  1076.  
  1077.     return(err);
  1078. }
  1079.  
  1080.  
  1081.  
  1082. UDIError d386_UDIRead (void _far * rm_stk_ptr, int stacksize)
  1083. {
  1084. INCOMING_PARAMS(
  1085.   UDIResource    From;            /* In */
  1086.   UDIHostMemPtr    To;            /* Out */
  1087.   UDICount    Count;            /* In */
  1088.   UDISizeT    Size;            /* In */
  1089.   UDICount    *CountDone;        /* Out */
  1090.   UDIBool    HostEndian;        /* In */
  1091.   )
  1092. UDIError err;
  1093.  
  1094.     OUTPTR_PREPROCESS_COUNT(To, in->Count * in->Size);
  1095.     OUTPTR_PREPROCESS(CountDone);
  1096.  
  1097.     err = UDIRead(
  1098.     in->From,
  1099.     local.To,
  1100.     in->Count,
  1101.     in->Size,
  1102.     local.CountDone,
  1103.     in->HostEndian
  1104.     );
  1105.  
  1106.     OUTPTR_POSTPROCESS_COUNT(To, *(local.CountDone) * in->Size);
  1107.     OUTPTR_POSTPROCESS(CountDone);
  1108.  
  1109.     return(err);
  1110. }
  1111.  
  1112.  
  1113.  
  1114. UDIError d386_UDIWrite  (void _far * rm_stk_ptr, int stacksize)
  1115. {
  1116. INCOMING_PARAMS(
  1117.   UDIHostMemPtr    From;            /* In */
  1118.   UDIResource    To;            /* In */
  1119.   UDICount    Count;            /* In */
  1120.   UDISizeT    Size;            /* In */
  1121.   UDICount    *CountDone;        /* Out */
  1122.   UDIBool    HostEndian;        /* In */
  1123.   )
  1124. UDIError err;
  1125.  
  1126.     INPTR_PREPROCESS_COUNT (From, in->Count * in->Size);
  1127.     OUTPTR_PREPROCESS(CountDone);
  1128.  
  1129.     err = UDIWrite(
  1130.     local.From,
  1131.     in->To,
  1132.     in->Count,
  1133.     in->Size,
  1134.     local.CountDone,
  1135.     in->HostEndian
  1136.     );
  1137.  
  1138.     OUTPTR_POSTPROCESS(CountDone);
  1139.  
  1140.     return(err);
  1141.  
  1142. }
  1143.  
  1144.  
  1145. UDIError d386_UDICopy (void _far * rm_stk_ptr, int stacksize)
  1146. {
  1147. INCOMING_PARAMS(
  1148.   UDIResource    From;            /* In */
  1149.   UDIResource    To;            /* In */
  1150.   UDICount    Count;            /* In */
  1151.   UDISizeT    Size;            /* In */
  1152.   UDICount    *CountDone;        /* Out */
  1153.   UDIBool    Direction;        /* In */
  1154.  )
  1155. UDIError err;
  1156.  
  1157.     OUTPTR_PREPROCESS(CountDone);
  1158.  
  1159.     err = UDICopy(
  1160.     in->From,
  1161.     in->To,
  1162.     in->Count,
  1163.     in->Size,
  1164.     local.CountDone,
  1165.     in->Direction
  1166.     );
  1167.  
  1168.     OUTPTR_POSTPROCESS(CountDone);
  1169.  
  1170.     return(err);
  1171. }
  1172.  
  1173.  
  1174. UDIError d386_UDIExecute (void _far * rm_stk_ptr, int stacksize)
  1175. {
  1176. /* no incoming parameters */
  1177.  
  1178.     return(UDIExecute());
  1179. }
  1180.  
  1181.  
  1182. UDIError d386_UDIStep  (void _far * rm_stk_ptr, int stacksize)
  1183. {
  1184. INCOMING_PARAMS_NO_PTR(
  1185.   UDIUInt32    Steps;            /* In */
  1186.   UDIStepType   StepType;        /* In */
  1187.   UDIRange      Range;            /* In */
  1188.   )
  1189. UDIError err;
  1190.  
  1191.     err = UDIStep(
  1192.     in->Steps,
  1193.     in->StepType,
  1194.     in->Range
  1195.     );
  1196.  
  1197.     return(err);
  1198. }
  1199.  
  1200.  
  1201.  
  1202. UDIVoid d386_UDIStop   (void _far * rm_stk_ptr, int stacksize)
  1203. {
  1204. /* no incoming parameters, no return value */
  1205.     UDIStop();
  1206. }
  1207.  
  1208.  
  1209.  
  1210.  
  1211. UDIError d386_UDIWait  (void _far * rm_stk_ptr, int stacksize)
  1212. {
  1213. INCOMING_PARAMS(
  1214.   UDIInt32    MaxTime;        /* In */
  1215.   UDIPId    *PId;            /* Out */
  1216.   UDIUInt32    *StopReason;        /* Out */
  1217.   )
  1218. UDIError err;
  1219.  
  1220.     OUTPTR_PREPROCESS(PId);
  1221.     OUTPTR_PREPROCESS(StopReason);
  1222.  
  1223.     err = UDIWait(
  1224.     in->MaxTime,
  1225.     local.PId,
  1226.     local.StopReason
  1227.     );
  1228.  
  1229.     OUTPTR_POSTPROCESS(PId);
  1230.     OUTPTR_POSTPROCESS(StopReason);
  1231.  
  1232.     return(err);
  1233. }
  1234.  
  1235.  
  1236.  
  1237. UDIError d386_UDISetBreakpoint  (void _far * rm_stk_ptr, int stacksize)
  1238. {
  1239. INCOMING_PARAMS(
  1240.   UDIResource    Addr;            /* In */
  1241.   UDIInt32    PassCount;        /* In */
  1242.   UDIBreakType    Type;            /* In */
  1243.   UDIBreakId    *BreakId;        /* Out */
  1244.   )
  1245. UDIError err;
  1246.  
  1247.     OUTPTR_PREPROCESS(BreakId);
  1248.  
  1249.     err = UDISetBreakpoint(
  1250.     in->Addr,
  1251.     in->PassCount,
  1252.     in->Type,
  1253.     local.BreakId
  1254.     );
  1255.  
  1256.     OUTPTR_POSTPROCESS(BreakId);
  1257.  
  1258.     return(err);
  1259. }
  1260.  
  1261.  
  1262. UDIError d386_UDIQueryBreakpoint   (void _far * rm_stk_ptr, int stacksize)
  1263. {
  1264. INCOMING_PARAMS(
  1265.   UDIBreakId    BreakId;        /* In */
  1266.   UDIResource    *Addr;            /* Out */
  1267.   UDIInt32    *PassCount;        /* Out */
  1268.   UDIBreakType    *Type;        /* Out */
  1269.   UDIInt32    *CurrentCount;        /* Out */
  1270.   )
  1271. UDIError err;
  1272.  
  1273.     OUTPTR_PREPROCESS(Addr);
  1274.     OUTPTR_PREPROCESS(PassCount);
  1275.     OUTPTR_PREPROCESS(Type);
  1276.     OUTPTR_PREPROCESS(CurrentCount);
  1277.  
  1278.     err = UDIQueryBreakpoint(
  1279.     in->BreakId,
  1280.     local.Addr,
  1281.     local.PassCount,
  1282.     local.Type,
  1283.     local.CurrentCount
  1284.     );
  1285.  
  1286.     OUTPTR_POSTPROCESS(Addr);
  1287.     OUTPTR_POSTPROCESS(PassCount);
  1288.     OUTPTR_POSTPROCESS(Type);
  1289.     OUTPTR_POSTPROCESS(CurrentCount);
  1290.  
  1291.     return(err);
  1292. }
  1293.  
  1294.  
  1295.  
  1296. UDIError d386_UDIClearBreakpoint (void _far * rm_stk_ptr, int stacksize)
  1297. {
  1298. INCOMING_PARAMS_NO_PTR(
  1299.   UDIBreakId    BreakId;        /* In */
  1300.   )
  1301.     return(UDIClearBreakpoint(
  1302.     in->BreakId
  1303.     ));
  1304.  
  1305. }
  1306.  
  1307. UDIError d386_UDIGetStdout (void _far * rm_stk_ptr, int stacksize)
  1308. {
  1309. INCOMING_PARAMS(
  1310.   UDIHostMemPtr    Buf;            /* Out */
  1311.   UDISizeT    BufSize;        /* In */
  1312.   UDISizeT    *CountDone;        /* Out */
  1313.   )
  1314. UDIError err;
  1315.  
  1316.     OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
  1317.     OUTPTR_PREPROCESS(CountDone);
  1318.  
  1319.     err = UDIGetStdout(
  1320.     local.Buf,
  1321.     in->BufSize,
  1322.     local.CountDone
  1323.     );
  1324.  
  1325.     OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
  1326.     OUTPTR_POSTPROCESS(CountDone);
  1327.  
  1328.     return(err);
  1329. }
  1330.  
  1331.  
  1332. UDIError d386_UDIGetStderr (void _far * rm_stk_ptr, int stacksize)
  1333. {
  1334. INCOMING_PARAMS(
  1335.   UDIHostMemPtr    Buf;            /* Out */
  1336.   UDISizeT    BufSize;        /* In */
  1337.   UDISizeT    *CountDone;        /* Out */
  1338.   )
  1339. UDIError err;
  1340.  
  1341.     OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
  1342.     OUTPTR_PREPROCESS(CountDone);
  1343.  
  1344.     err = UDIGetStderr(
  1345.     local.Buf,
  1346.     in->BufSize,
  1347.     local.CountDone
  1348.     );
  1349.  
  1350.     OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
  1351.     OUTPTR_POSTPROCESS(CountDone);
  1352.  
  1353.     return(err);
  1354. }
  1355.  
  1356.  
  1357.  
  1358. UDIError d386_UDIPutStdin (void _far * rm_stk_ptr, int stacksize)
  1359. {
  1360. INCOMING_PARAMS(
  1361.   UDIHostMemPtr    Buf;            /* In */
  1362.   UDISizeT    Count;            /* In */
  1363.   UDISizeT    *CountDone;        /* Out */
  1364.   )
  1365. UDIError err;
  1366.  
  1367.     INPTR_PREPROCESS_COUNT(Buf, in->Count);
  1368.     OUTPTR_PREPROCESS(CountDone);
  1369.  
  1370.     err = UDIPutStdin(
  1371.     local.Buf,
  1372.     in->Count,
  1373.     local.CountDone
  1374.     );
  1375.  
  1376.     OUTPTR_POSTPROCESS(CountDone);
  1377.  
  1378.     return(err);
  1379. }
  1380.  
  1381.  
  1382. UDIError d386_UDIStdinMode (void _far * rm_stk_ptr, int stacksize)
  1383. {
  1384. INCOMING_PARAMS(
  1385.   UDIMode    *Mode;            /* Out */
  1386.  )
  1387. UDIError err;
  1388.  
  1389.     OUTPTR_PREPROCESS(Mode);
  1390.  
  1391.     err = UDIStdinMode(
  1392.     local.Mode
  1393.     );
  1394.  
  1395.     OUTPTR_POSTPROCESS(Mode);
  1396.  
  1397.     return(err);
  1398. }
  1399.  
  1400. UDIError d386_UDIPutTrans (void _far * rm_stk_ptr, int stacksize)
  1401. {
  1402. INCOMING_PARAMS(
  1403.   UDIHostMemPtr    Buf;            /* In */
  1404.   UDISizeT    Count;            /* In */
  1405.   UDISizeT    *CountDone;        /* Out */
  1406.   )
  1407. UDIError err;
  1408.  
  1409.     INPTR_PREPROCESS_COUNT(Buf, in->Count);
  1410.     OUTPTR_PREPROCESS(CountDone);
  1411.  
  1412.     err = UDIPutTrans(
  1413.     local.Buf,
  1414.     in->Count,
  1415.     local.CountDone
  1416.     );
  1417.  
  1418.     OUTPTR_POSTPROCESS(CountDone);
  1419.  
  1420.     return(err);
  1421. }
  1422.  
  1423.  
  1424. UDIError d386_UDIGetTrans (void _far * rm_stk_ptr, int stacksize)
  1425. {
  1426. INCOMING_PARAMS(
  1427.   UDIHostMemPtr    Buf;            /* Out */
  1428.   UDISizeT    BufSize;        /* In */
  1429.   UDISizeT    *CountDone;        /* Out */
  1430.   )
  1431. UDIError err;
  1432.  
  1433.     OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
  1434.     OUTPTR_PREPROCESS(CountDone);
  1435.  
  1436.     err = UDIGetTrans(
  1437.     local.Buf,
  1438.     in->BufSize,
  1439.     local.CountDone
  1440.     );
  1441.  
  1442.     OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
  1443.     OUTPTR_POSTPROCESS(CountDone);
  1444.  
  1445.     return(err);
  1446. }
  1447.  
  1448.  
  1449. UDIError d386_UDITransMode (void _far * rm_stk_ptr, int stacksize)
  1450. {
  1451. INCOMING_PARAMS(
  1452.   UDIMode    *Mode;            /* Out */
  1453.  )
  1454. UDIError err;
  1455.  
  1456.     OUTPTR_PREPROCESS(Mode);
  1457.  
  1458.     err = UDITransMode(
  1459.     local.Mode
  1460.     );
  1461.  
  1462.     OUTPTR_POSTPROCESS(Mode);
  1463.  
  1464.     return(err);
  1465. }
  1466.  
  1467. #endif
  1468. /*==================== End of DOS386 glue routines ====================================*/
  1469.  
  1470.  
  1471.