OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [utils/] [amd-udi/] [udi/] [dos2udip.c] - Diff between revs 578 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 578 Rev 1765
/******************************************************************************
/******************************************************************************
 * Copyright 1991 Advanced Micro Devices, Inc.
 * Copyright 1991 Advanced Micro Devices, Inc.
 *
 *
 * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
 * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
 * specifically  grants the user the right to modify, use and distribute this
 * specifically  grants the user the right to modify, use and distribute this
 * software provided this notice is not removed or altered.  All other rights
 * software provided this notice is not removed or altered.  All other rights
 * are reserved by AMD.
 * are reserved by AMD.
 *
 *
 * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
 * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
 * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
 * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
 * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
 * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
 * USE OF THIS SOFTWARE.
 * USE OF THIS SOFTWARE.
 *
 *
 * Comments about this software should be directed to udi@amd.com. If access
 * Comments about this software should be directed to udi@amd.com. If access
 * to electronic mail isn't available, send mail to:
 * to electronic mail isn't available, send mail to:
 *
 *
 * Advanced Micro Devices, Inc.
 * Advanced Micro Devices, Inc.
 * 29K Support Products
 * 29K Support Products
 * Mail Stop 573
 * Mail Stop 573
 * 5900 E. Ben White Blvd.
 * 5900 E. Ben White Blvd.
 * Austin, TX 78741
 * Austin, TX 78741
 * 800-292-9263
 * 800-292-9263
 *****************************************************************************
 *****************************************************************************
 * DOS386 changes were merged into:
 * DOS386 changes were merged into:
 *       $Id: dos2udip.c,v 1.1.1.1 2002-01-16 10:26:06 markom Exp $
 *       $Id: dos2udip.c,v 1.1.1.1 2002-01-16 10:26:06 markom Exp $
 *       $Id: @(#)dos2udip.c    2.11, AMD
 *       $Id: @(#)dos2udip.c    2.11, AMD
 */
 */
 
 
        /* TIPIPCId components */
        /* TIPIPCId components */
#define TIPIPCIdCompany 0x0001  /* Company ID from AMD, others should change this */
#define TIPIPCIdCompany 0x0001  /* Company ID from AMD, others should change this */
#define TIPIPCIdVersion 0x124   /* Version */
#define TIPIPCIdVersion 0x124   /* Version */
#ifdef DOS386
#ifdef DOS386
#define TIPIPCIdProduct 0x3     /* Product ID for DOS386 IPC */
#define TIPIPCIdProduct 0x3     /* Product ID for DOS386 IPC */
#else
#else
#define TIPIPCIdProduct 0x2     /* Product ID for non-DOS386 IPC */
#define TIPIPCIdProduct 0x2     /* Product ID for non-DOS386 IPC */
#endif
#endif
 
 
#include <stdio.h>
#include <stdio.h>
#include <dos.h>
#include <dos.h>
 
 
#ifdef HAVE_STDLIB_H
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
# include <stdlib.h>
#endif
#endif
 
 
#ifdef HAVE_STRING_H
#ifdef HAVE_STRING_H
# include <string.h>
# include <string.h>
#else
#else
# include <strings.h>
# include <strings.h>
#endif
#endif
 
 
#include <udiproc.h>
#include <udiproc.h>
#include <udidos.h>
#include <udidos.h>
static FILE *      fpstdout = stdout;   /* where we write the information */
static FILE *      fpstdout = stdout;   /* where we write the information */
 
 
#ifndef DOS386
#ifndef DOS386
#pragma check_stack( off )
#pragma check_stack( off )
#pragma check_pointer( off )
#pragma check_pointer( off )
 
 
        /********************************************************
        /********************************************************
         * In non-DOS386 mode, a standard C PTR is just a far real ptr
         * In non-DOS386 mode, a standard C PTR is just a far real ptr
         * so FARCPTR_TO_REALPTR and REALPTR_TO_FARCPTR are pass-thru
         * so FARCPTR_TO_REALPTR and REALPTR_TO_FARCPTR are pass-thru
         ********************************************************/
         ********************************************************/
#define FARCPTR_TO_REALPTR(p) p
#define FARCPTR_TO_REALPTR(p) p
#define REALPTR_TO_FARCPTR(p) p
#define REALPTR_TO_FARCPTR(p) p
 
 
#define IPCFar far      /* qualifier for pointer that can reach the real data used by IPC */
#define IPCFar far      /* qualifier for pointer that can reach the real data used by IPC */
#define REALNULL NULL
#define REALNULL NULL
typedef void far * FARCPTR;
typedef void far * FARCPTR;
 
 
#else 
#else 
#include "malloc.h"
#include "malloc.h"
#include "alloca.h"
#include "alloca.h"
#include "pharlap.h"
#include "pharlap.h"
#include "realcopy.h"
#include "realcopy.h"
 
 
#define IPCFar _far     /* qualifier for pointer that can reach the real data used by IPC */
#define IPCFar _far     /* qualifier for pointer that can reach the real data used by IPC */
#define REALNULL (REALPTR) 0
#define REALNULL (REALPTR) 0
typedef void _far * FARCPTR;
typedef void _far * FARCPTR;
 
 
 
 
        /********************************************************
        /********************************************************
         * In DOS386 protected mode, we have two types of pointers, near and far
         * In DOS386 protected mode, we have two types of pointers, near and far
         * near is a 32-bit pointer, ie a 32-bit offset from DS.
         * near is a 32-bit pointer, ie a 32-bit offset from DS.
         * far is a 48-bit pointer, with an explicit segment register.
         * far is a 48-bit pointer, with an explicit segment register.
         * We want to be able to convert real mode pointers (16-bit seg, 16-bit ofst)
         * We want to be able to convert real mode pointers (16-bit seg, 16-bit ofst)
         * into these near and far protected mode pointers and vice versa.
         * into these near and far protected mode pointers and vice versa.
         *
         *
         * It is always possible to convert a real mode pointer to a far prot ptr.
         * It is always possible to convert a real mode pointer to a far prot ptr.
         * (Pharlap provides an explicit segment that maps to the low 1 meg of memory).
         * (Pharlap provides an explicit segment that maps to the low 1 meg of memory).
         ********************************************************/
         ********************************************************/
FARCPTR  REALPTR_TO_FARCPTR(REALPTR p);
FARCPTR  REALPTR_TO_FARCPTR(REALPTR p);
 
 
        /********************************************************
        /********************************************************
         * The ability to convert from a real mode pointer to a near protected
         * The ability to convert from a real mode pointer to a near protected
         * pointer depends on being able to map converntional memory onto the
         * pointer depends on being able to map converntional memory onto the
         * end of our data segment.  This is NOT possible under DPMI 0.90
         * end of our data segment.  This is NOT possible under DPMI 0.90
         * If we're not under DPMI 0.90,
         * If we're not under DPMI 0.90,
         * REALPTR_TO_NEARCPTR takes a real ptr, and returns its offset
         * REALPTR_TO_NEARCPTR takes a real ptr, and returns its offset
         * in the SS_DATA segment (using the fact that the 1 meg of real
         * in the SS_DATA segment (using the fact that the 1 meg of real
         * memory was mapped to the SS_DATA by dx_map_physical).
         * memory was mapped to the SS_DATA by dx_map_physical).
         *
         *
         ********************************************************/
         ********************************************************/
#define REALPTR_TO_NEARCPTR(rp) ((void *)(&conventional_memory[LINEARIZE(rp)]))
#define REALPTR_TO_NEARCPTR(rp) ((void *)(&conventional_memory[LINEARIZE(rp)]))
 
 
 
 
        /**********************************************************
        /**********************************************************
         *  LINEARIZE converts a segment:ofst pointer into a linear
         *  LINEARIZE converts a segment:ofst pointer into a linear
         *  addr between 0 and 1meg
         *  addr between 0 and 1meg
         *********************************************************/
         *********************************************************/
#define LINEARIZE(rp) ((RP_SEG(rp)<<4) + RP_OFF(rp))
#define LINEARIZE(rp) ((RP_SEG(rp)<<4) + RP_OFF(rp))
 
 
        /********************************************************
        /********************************************************
         * FARCPTR_TO_REALPTR converts a far protected ptr to a real ptr.
         * FARCPTR_TO_REALPTR converts a far protected ptr to a real ptr.
         * Naturally, only certain protected pointers can be converted
         * Naturally, only certain protected pointers can be converted
         * into real pointers (they must map to something in the
         * into real pointers (they must map to something in the
         * first 1 meg of memory).  If it can't be converted, it's
         * first 1 meg of memory).  If it can't be converted, it's
         * a fatal error.  This is a routine rather than a macro.
         * a fatal error.  This is a routine rather than a macro.
         * If we need to convert a near prot ptr to a real ptr,
         * If we need to convert a near prot ptr to a real ptr,
         * this can be done by simply casting it to a far
         * this can be done by simply casting it to a far
         *
         *
         ********************************************************/
         ********************************************************/
REALPTR FARCPTR_TO_REALPTR(FARPTR p);
REALPTR FARCPTR_TO_REALPTR(FARPTR p);
 
 
extern USHORT GetCS();
extern USHORT GetCS();
extern USHORT GetDS();
extern USHORT GetDS();
 
 
 
 
#endif   /* DOS386 */
#endif   /* DOS386 */
 
 
/****************** External Prototypes *****************************/
/****************** External Prototypes *****************************/
 
 
extern void TIPPrintUsage(char *arg);
extern void TIPPrintUsage(char *arg);
 
 
#ifndef DOS386
#ifndef DOS386
extern UDIError UDIASMDisconnect UDIParams((
extern UDIError UDIASMDisconnect UDIParams((
  UDISessionId          Session,                /* In */
  UDISessionId          Session,                /* In */
  UDIBool               Terminate,              /* In */
  UDIBool               Terminate,              /* In */
  DOSTerm               far *TermStruct         /* In - not seen in UDIP */
  DOSTerm               far *TermStruct         /* In - not seen in UDIP */
  ));
  ));
extern UDIError UDIASMConnect UDIParams((
extern UDIError UDIASMConnect UDIParams((
  char                  *Configuration,         /* In */
  char                  *Configuration,         /* In */
  UDISessionId          *Session,               /* Out */
  UDISessionId          *Session,               /* Out */
  DOSTerm               far *TermStruct         /* In - not seen in UDIP */
  DOSTerm               far *TermStruct         /* In - not seen in UDIP */
  ));
  ));
 
 
#endif
#endif
 
 
/****************** Internal Prototypes *****************************/
/****************** Internal Prototypes *****************************/
 
 
UDIError UDICCapabilities UDIParams((
UDIError UDICCapabilities UDIParams((
  UDIUInt32     *TIPId,                 /* Out */
  UDIUInt32     *TIPId,                 /* Out */
  UDIUInt32     *TargetId,              /* Out */
  UDIUInt32     *TargetId,              /* Out */
  UDIUInt32     DFEId,                  /* In */
  UDIUInt32     DFEId,                  /* In */
  UDIUInt32     DFE,                    /* In */
  UDIUInt32     DFE,                    /* In */
  UDIUInt32     *TIP,                   /* Out */
  UDIUInt32     *TIP,                   /* Out */
  UDIUInt32     *DFEIPCId,              /* Out */
  UDIUInt32     *DFEIPCId,              /* Out */
  UDIUInt32     *TIPIPCId,              /* Out */
  UDIUInt32     *TIPIPCId,              /* Out */
  char          *TIPString              /* Out */
  char          *TIPString              /* Out */
  ));
  ));
 
 
static unsigned short GetPSP( void );
static unsigned short GetPSP( void );
static void SetPSP( unsigned short PSPSegment );
static void SetPSP( unsigned short PSPSegment );
static unsigned int ComputeTSRSize(void *topofstack);
static unsigned int ComputeTSRSize(void *topofstack);
static void SetupEnvironment(void);
static void SetupEnvironment(void);
static void TerminateTIP UDIParams((DOSTerm           IPCFar *TermStruct));
static void TerminateTIP UDIParams((DOSTerm           IPCFar *TermStruct));
 
 
 
 
/****************** External and Static Data *****************************/
/****************** External and Static Data *****************************/
static int ConnectCount;
static int ConnectCount;
 
 
#ifdef DOS386
#ifdef DOS386
 
 
char    *conventional_memory;   /* pointer to first byte of conventinal memory */
char    *conventional_memory;   /* pointer to first byte of conventinal memory */
                                /* if 0, then conventional mem not mapped */
                                /* if 0, then conventional mem not mapped */
USHORT  our_tsr_psp;            /* TIP's original PSP */
USHORT  our_tsr_psp;            /* TIP's original PSP */
USHORT  dos_ext_psp;            /* Dos extender PSP (TIP's parent) */
USHORT  dos_ext_psp;            /* Dos extender PSP (TIP's parent) */
extern  REALPTR  call_prot;     /* These are in the module dostip.asm */
extern  REALPTR  call_prot;     /* These are in the module dostip.asm */
extern  USHORT   code_selector;
extern  USHORT   code_selector;
extern  USHORT   data_selector;
extern  USHORT   data_selector;
extern  USHORT  segregblock[4];
extern  USHORT  segregblock[4];
extern  int end_real;           /* marks end of stuff that must be placed in low mem */
extern  int end_real;           /* marks end of stuff that must be placed in low mem */
int * stack_table[3];           /* used when we need to get a new stack frame
int * stack_table[3];           /* used when we need to get a new stack frame
                                 * to establish C context on each UDI call
                                 * to establish C context on each UDI call
                                 * but only if conventional memory didn't map */
                                 * but only if conventional memory didn't map */
REALPTR  real_basep;            /* returned by realcopy */
REALPTR  real_basep;            /* returned by realcopy */
FARPTR   prot_basep;            /* returned by realcopy */
FARPTR   prot_basep;            /* returned by realcopy */
USHORT   rmem_adrp;             /* returned by realcopy */
USHORT   rmem_adrp;             /* returned by realcopy */
 
 
extern char TIPName[];                  /* in DOS386, defined in rmdata in dosdfe.asm */
extern char TIPName[];                  /* in DOS386, defined in rmdata in dosdfe.asm */
extern struct UDIVecRec TIPVecRec;      /* in DOS386, defined in rmdata in dosdfe.asm */
extern struct UDIVecRec TIPVecRec;      /* in DOS386, defined in rmdata in dosdfe.asm */
 
 
 
 
 
 
#else   /* non-DOS386 static and external data */
#else   /* non-DOS386 static and external data */
 
 
char TIPName[ FILENAME_MAX ];           /* in non-386 version, TIPName defined right here */
char TIPName[ FILENAME_MAX ];           /* in non-386 version, TIPName defined right here */
struct UDIVecRec TIPVecRec = {          /* in non-386 version, TIPVecRec defined right here */
struct UDIVecRec TIPVecRec = {          /* in non-386 version, TIPVecRec defined right here */
    UDIDOSTIPRecognizer,        /* Initialized in main */
    UDIDOSTIPRecognizer,        /* Initialized in main */
    NULL,                       /* Pointer to next TIP */
    NULL,                       /* Pointer to next TIP */
    NULL,                       /* Pointer to previous TIP */
    NULL,                       /* Pointer to previous TIP */
    TIPName,                    /* Name of the executable we were loaded as */
    TIPName,                    /* Name of the executable we were loaded as */
    UDIASMConnect,
    UDIASMConnect,
    UDIASMDisconnect,
    UDIASMDisconnect,
    UDISetCurrentConnection,
    UDISetCurrentConnection,
    UDICCapabilities,
    UDICCapabilities,
    UDIGetErrorMsg,
    UDIGetErrorMsg,
    UDIGetTargetConfig,
    UDIGetTargetConfig,
    UDICreateProcess,
    UDICreateProcess,
    UDISetCurrentProcess,
    UDISetCurrentProcess,
    UDIDestroyProcess,
    UDIDestroyProcess,
    UDIInitializeProcess,
    UDIInitializeProcess,
    UDIRead,
    UDIRead,
    UDIWrite,
    UDIWrite,
    UDICopy,
    UDICopy,
    UDIExecute,
    UDIExecute,
    UDIStep,
    UDIStep,
    UDIStop,
    UDIStop,
    UDIWait,
    UDIWait,
    UDISetBreakpoint,
    UDISetBreakpoint,
    UDIQueryBreakpoint,
    UDIQueryBreakpoint,
    UDIClearBreakpoint,
    UDIClearBreakpoint,
    UDIGetStdout,
    UDIGetStdout,
    UDIGetStderr,
    UDIGetStderr,
    UDIPutStdin,
    UDIPutStdin,
    UDIStdinMode,
    UDIStdinMode,
    UDIPutTrans,
    UDIPutTrans,
    UDIGetTrans,
    UDIGetTrans,
    UDITransMode
    UDITransMode
   };
   };
#endif
#endif
 
 
struct UDIVecRec IPCFar * pTIPVecRec;   /* pointer to TIPVecRec */
struct UDIVecRec IPCFar * pTIPVecRec;   /* pointer to TIPVecRec */
                                        /* in DOS386, this points to real memory */
                                        /* in DOS386, this points to real memory */
static RealUDIVecRecPtr IPCFar * UDIVecP;
static RealUDIVecRecPtr IPCFar * UDIVecP;
 
 
static int loaded_from_exp_file = 0;
static int loaded_from_exp_file = 0;
 
 
 
 
void do_exit(int errcode)
void do_exit(int errcode)
{
{
  /* this routine normally just calls exit but in the special case
  /* this routine normally just calls exit but in the special case
   * of DOS386 mode AND we were loaded from a .exp file, then we want
   * of DOS386 mode AND we were loaded from a .exp file, then we want
   * to exit in a different way by calling exp_return
   * to exit in a different way by calling exp_return
   */
   */
#ifdef DOS386
#ifdef DOS386
extern void _exp_return(int err);
extern void _exp_return(int err);
    if (loaded_from_exp_file)
    if (loaded_from_exp_file)
        _exp_return(errcode);
        _exp_return(errcode);
    else
    else
#endif
#endif
        /* normal non-DOS386 and non-exp_file exit */
        /* normal non-DOS386 and non-exp_file exit */
        exit(errcode);
        exit(errcode);
}
}
 
 
 
 
void do_dos_keep(int errcode, int tsrsize)
void do_dos_keep(int errcode, int tsrsize)
{
{
  /* similar logic to do_exit above, but this time for dos_keep
  /* similar logic to do_exit above, but this time for dos_keep
   */
   */
#ifdef DOS386
#ifdef DOS386
extern void _exp_return(int err);
extern void _exp_return(int err);
    if (loaded_from_exp_file)
    if (loaded_from_exp_file)
        _exp_return(errcode);
        _exp_return(errcode);
    else
    else
#endif
#endif
        /* normal non-DOS386 and non-exp_file dos_keep */
        /* normal non-DOS386 and non-exp_file dos_keep */
        _dos_keep( 0, tsrsize );
        _dos_keep( 0, tsrsize );
}
}
 
 
void get_tip_name(int argc, char *argv[])
void get_tip_name(int argc, char *argv[])
{
{
  /* This routine normally gets the Tipname from argv[1], but
  /* This routine normally gets the Tipname from argv[1], but
   * in the special case of DOS386 and loaded as an exp file,
   * in the special case of DOS386 and loaded as an exp file,
   * it gets the name from the stack
   * it gets the name from the stack
   */
   */
 
 
#ifdef DOS386
#ifdef DOS386
    extern  char * _top;
    extern  char * _top;
 
 
    if ((GetCS() & 0xfffc) != SS_CODE) {
    if ((GetCS() & 0xfffc) != SS_CODE) {
        /* a CS that is not SS_CODE indicates that we were
        /* a CS that is not SS_CODE indicates that we were
           loaded as a .exp file.  In that case, we don't
           loaded as a .exp file.  In that case, we don't
           want to exit or do a TSR, instead we want to return
           want to exit or do a TSR, instead we want to return
           back to the DFE using _exp_return.
           back to the DFE using _exp_return.
        */
        */
        loaded_from_exp_file = TRUE;
        loaded_from_exp_file = TRUE;
        strcpy(TIPName, _top+16);
        strcpy(TIPName, _top+16);
        return;
        return;
    }
    }
#endif
#endif
 
 
    if ((argc!= 2)  || (argv[1][0] == '-')) {
    if ((argc!= 2)  || (argv[1][0] == '-')) {
        TIPPrintUsage(argv[1]);
        TIPPrintUsage(argv[1]);
        do_exit( 1 );
        do_exit( 1 );
    }
    }
 
 
    strcpy( TIPName, argv[1] );
    strcpy( TIPName, argv[1] );
}
}
 
 
 
 
#ifdef DOS386
#ifdef DOS386
REALPTR FARCPTR_TO_REALPTR(FARCPTR p)   /* converts a FAR PROT ptr to a REALPTR */
REALPTR FARCPTR_TO_REALPTR(FARCPTR p)   /* converts a FAR PROT ptr to a REALPTR */
{
{
REALPTR  dummyrp;
REALPTR  dummyrp;
int   err;
int   err;
 
 
                /* returns a real mode pointer given a prot mode pointer p */
                /* returns a real mode pointer given a prot mode pointer p */
        err = _dx_toreal(p, 0, &dummyrp);
        err = _dx_toreal(p, 0, &dummyrp);
        if (err) {
        if (err) {
           printf("Fatal Error _dx_toreal(%04x:%08x)\n", FP_SEG(p), FP_OFF(p));
           printf("Fatal Error _dx_toreal(%04x:%08x)\n", FP_SEG(p), FP_OFF(p));
           do_exit(err);
           do_exit(err);
        }
        }
        else
        else
           return(dummyrp);
           return(dummyrp);
 
 
}
}
 
 
 
 
FARCPTR  REALPTR_TO_FARCPTR(REALPTR rp)
FARCPTR  REALPTR_TO_FARCPTR(REALPTR rp)
{
{
FARCPTR   dummyfp;
FARCPTR   dummyfp;
        FP_SET(dummyfp, LINEARIZE(rp), SS_DOSMEM);
        FP_SET(dummyfp, LINEARIZE(rp), SS_DOSMEM);
        return(dummyfp);
        return(dummyfp);
}
}
 
 
/*****************
/*****************
 * Routine used to create and initialize a stack for C context stack switching
 * Routine used to create and initialize a stack for C context stack switching
 * (used only when conventional memory can't be mapped
 * (used only when conventional memory can't be mapped
 ****************/
 ****************/
static void create_stack(int stack_index, int size_in_bytes)
static void create_stack(int stack_index, int size_in_bytes)
{
{
int *p;
int *p;
int  index_to_last_int;
int  index_to_last_int;
 
 
        /* malloc appropriate size and point stack_table entry to second last word */
        /* malloc appropriate size and point stack_table entry to second last word */
    p = (int *)malloc(size_in_bytes);
    p = (int *)malloc(size_in_bytes);
    if (p == 0) {
    if (p == 0) {
        printf("\nTIP: unable to malloc stacks\n");
        printf("\nTIP: unable to malloc stacks\n");
        do_exit(1);
        do_exit(1);
    }
    }
    index_to_last_int =  (size_in_bytes/sizeof(int)) - 1;
    index_to_last_int =  (size_in_bytes/sizeof(int)) - 1;
    stack_table[stack_index] = &p[index_to_last_int-1];
    stack_table[stack_index] = &p[index_to_last_int-1];
 
 
        /* and set last word to 0 (marked as free) */
        /* and set last word to 0 (marked as free) */
        /* set second last word to stack size (used for alloca checking) */
        /* set second last word to stack size (used for alloca checking) */
    p[index_to_last_int-1]   = size_in_bytes-8;
    p[index_to_last_int-1]   = size_in_bytes-8;
    p[index_to_last_int] = 0;
    p[index_to_last_int] = 0;
}
}
#endif
#endif
 
 
 
 
 
 
static void TerminateTIP UDIParams((
static void TerminateTIP UDIParams((
  DOSTerm               IPCFar *TermStruct      /* In - not seen in UDIP */
  DOSTerm               IPCFar *TermStruct      /* In - not seen in UDIP */
  ))
  ))
{
{
    /* Delink ourselves from the linked list of TIPs */
    /* Delink ourselves from the linked list of TIPs */
    if (pTIPVecRec->Next != REALNULL)
    if (pTIPVecRec->Next != REALNULL)
        ((struct UDIVecRec IPCFar *)REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = pTIPVecRec->Prev;
        ((struct UDIVecRec IPCFar *)REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = pTIPVecRec->Prev;
    if (pTIPVecRec->Prev != REALNULL)
    if (pTIPVecRec->Prev != REALNULL)
        ((struct UDIVecRec IPCFar *)REALPTR_TO_FARCPTR(pTIPVecRec->Prev))->Next = pTIPVecRec->Next;
        ((struct UDIVecRec IPCFar *)REALPTR_TO_FARCPTR(pTIPVecRec->Prev))->Next = pTIPVecRec->Next;
    else
    else
        *UDIVecP = pTIPVecRec->Next;    /* no previous TIP, set the interrupt vector
        *UDIVecP = pTIPVecRec->Next;    /* no previous TIP, set the interrupt vector
                                           to point to our Next TIP */
                                           to point to our Next TIP */
 
 
#ifdef DOS386
#ifdef DOS386
{
{
    if (loaded_from_exp_file)   /* if we were loaded from an exp file, skip all this PSP stuff */
    if (loaded_from_exp_file)   /* if we were loaded from an exp file, skip all this PSP stuff */
        return;
        return;
 
 
    /* Under DOSEXT, our PSP is parented by the DOSEXTENDER's PSP */
    /* Under DOSEXT, our PSP is parented by the DOSEXTENDER's PSP */
    /* We want to modify the DOSEXT's PSP to point to the DFE info */
    /* We want to modify the DOSEXT's PSP to point to the DFE info */
REALPTR ptr_dos_ext_psp_parent;
REALPTR ptr_dos_ext_psp_parent;
REALPTR ptr_dos_ext_psp_termaddr;
REALPTR ptr_dos_ext_psp_termaddr;
 
 
    /* Set the dos_ext_psp's Parent PSP to the current PSP (ie, the DFE PSP)*/
    /* Set the dos_ext_psp's Parent PSP to the current PSP (ie, the DFE PSP)*/
    RP_SET(ptr_dos_ext_psp_parent,0x16, dos_ext_psp);
    RP_SET(ptr_dos_ext_psp_parent,0x16, dos_ext_psp);
    *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp_parent))) = GetPSP();
    *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp_parent))) = GetPSP();
 
 
    /* Set the dos_ext_psp's Terminate address to reasonable address in
    /* Set the dos_ext_psp's Terminate address to reasonable address in
       current PSP (DFE)'s program space */
       current PSP (DFE)'s program space */
    RP_SET(ptr_dos_ext_psp_termaddr,0xa, dos_ext_psp);
    RP_SET(ptr_dos_ext_psp_termaddr,0xa, dos_ext_psp);
    *((ULONG _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp_termaddr))) = (ULONG) TermStruct->TermFunc;
    *((ULONG _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp_termaddr))) = (ULONG) TermStruct->TermFunc;
}
}
#else
#else
    /* Set our TSR's PSP's Parent PSP to the current PSP */
    /* Set our TSR's PSP's Parent PSP to the current PSP */
    fflush(fpstdout);
    fflush(fpstdout);
 
 
    *(unsigned _far *)(((long)_psp << 16) + 0x16) = GetPSP();
    *(unsigned _far *)(((long)_psp << 16) + 0x16) = GetPSP();
 
 
    /* Set our TSR's PSP's Terminate address to reasonable address in
    /* Set our TSR's PSP's Terminate address to reasonable address in
       current PSP's program space */
       current PSP's program space */
    /*(void _far (_far *) (void))(((long)_psp << 16) + 0xa) = ExitAddr;*/
    /*(void _far (_far *) (void))(((long)_psp << 16) + 0xa) = ExitAddr;*/
    *(void (_far *(_far *))(void))(((long)_psp << 16) + 0xa) =
    *(void (_far *(_far *))(void))(((long)_psp << 16) + 0xa) =
        TermStruct->TermFunc;
        TermStruct->TermFunc;
#endif
#endif
 
 
    /* Change DOS's notion of what the current PSP is to be our TSR's PSP */
    /* Change DOS's notion of what the current PSP is to be our TSR's PSP */
#ifdef DOS386
#ifdef DOS386
    SetPSP(our_tsr_psp);
    SetPSP(our_tsr_psp);
        /* Under Dosext, termination will chain back from our_psp to DOSEXT PSP */
        /* Under Dosext, termination will chain back from our_psp to DOSEXT PSP */
        /* and then back to the DFE (since we modified the DOSEXT PSP above)    */
        /* and then back to the DFE (since we modified the DOSEXT PSP above)    */
#else
#else
    SetPSP(_psp );
    SetPSP(_psp );
#endif
#endif
 
 
    /* Terminate the program by using DOSTerminate 0x21/0x4c. Execution
    /* Terminate the program by using DOSTerminate 0x21/0x4c. Execution
       will resume at the Terminate address set above with ALL REGISTERS
       will resume at the Terminate address set above with ALL REGISTERS
       UNKNOWN especially SS:SP, DS, ES, etc */
       UNKNOWN especially SS:SP, DS, ES, etc */
    bdos( 0x4c, 0, 0 );
    bdos( 0x4c, 0, 0 );
    }
    }
 
 
UDIError UDICConnect UDIParams((
UDIError UDICConnect UDIParams((
  char                  *Configuration,         /* In */
  char                  *Configuration,         /* In */
  UDISessionId          *Session,               /* Out */
  UDISessionId          *Session,               /* Out */
  DOSTerm               IPCFar *TermStruct      /* In - not seen in UDIP */
  DOSTerm               IPCFar *TermStruct      /* In - not seen in UDIP */
  ))
  ))
{
{
    UDIError err;
    UDIError err;
 
 
    if ((err = UDIConnect( Configuration, Session )) <= UDINoError)
    if ((err = UDIConnect( Configuration, Session )) <= UDINoError)
        ConnectCount++;
        ConnectCount++;
 
 
    if (ConnectCount == 0) {     /* Terminate the unused TIP */
    if (ConnectCount == 0) {     /* Terminate the unused TIP */
        /* Save the error status in the TermStruct */
        /* Save the error status in the TermStruct */
        TermStruct->retval = err;
        TermStruct->retval = err;
 
 
        TerminateTIP( TermStruct );     /* Never returns */
        TerminateTIP( TermStruct );     /* Never returns */
        }
        }
 
 
    return err;
    return err;
    }
    }
 
 
UDIError UDICDisconnect UDIParams((
UDIError UDICDisconnect UDIParams((
  UDISessionId          Session,                /* In */
  UDISessionId          Session,                /* In */
  UDIBool               Terminate,              /* In */
  UDIBool               Terminate,              /* In */
  DOSTerm               IPCFar *TermStruct      /* In - not seen in UDIP */
  DOSTerm               IPCFar *TermStruct      /* In - not seen in UDIP */
  ))
  ))
{
{
    UDIError err;
    UDIError err;
 
 
    /* Disconnect via the real TIP */
    /* Disconnect via the real TIP */
    if ((err = UDIDisconnect( Session, Terminate )) == UDINoError)
    if ((err = UDIDisconnect( Session, Terminate )) == UDINoError)
        ConnectCount--;
        ConnectCount--;
 
 
    if (Terminate != UDIContinueSession && ConnectCount == 0) {
    if (Terminate != UDIContinueSession && ConnectCount == 0) {
        /* Terminate the unused TIP */
        /* Terminate the unused TIP */
        /* Save the error status in the TermStruct */
        /* Save the error status in the TermStruct */
        TermStruct->retval = err;
        TermStruct->retval = err;
 
 
        TerminateTIP( TermStruct );     /* Never returns */
        TerminateTIP( TermStruct );     /* Never returns */
        }
        }
 
 
    return err;
    return err;
    }
    }
 
 
UDIError UDICCapabilities UDIParams((
UDIError UDICCapabilities UDIParams((
  UDIUInt32     *TIPId,                 /* Out */
  UDIUInt32     *TIPId,                 /* Out */
  UDIUInt32     *TargetId,              /* Out */
  UDIUInt32     *TargetId,              /* Out */
  UDIUInt32     DFEId,                  /* In */
  UDIUInt32     DFEId,                  /* In */
  UDIUInt32     DFE,                    /* In */
  UDIUInt32     DFE,                    /* In */
  UDIUInt32     *TIP,                   /* Out */
  UDIUInt32     *TIP,                   /* Out */
  UDIUInt32     *DFEIPCId,              /* Out */
  UDIUInt32     *DFEIPCId,              /* Out */
  UDIUInt32     *TIPIPCId,              /* Out */
  UDIUInt32     *TIPIPCId,              /* Out */
  char          *TIPString              /* Out */
  char          *TIPString              /* Out */
  ))
  ))
{
{
    UDIError err;
    UDIError err;
 
 
    err = UDICapabilities( TIPId, TargetId, DFEId, DFE, TIP,
    err = UDICapabilities( TIPId, TargetId, DFEId, DFE, TIP,
                                DFEIPCId, TIPIPCId, TIPString );
                                DFEIPCId, TIPIPCId, TIPString );
 
 
    *TIPIPCId = (((UDIUInt32)TIPIPCIdCompany) << 16) |
    *TIPIPCId = (((UDIUInt32)TIPIPCIdCompany) << 16) |
                        (TIPIPCIdProduct << 12) | TIPIPCIdVersion;
                        (TIPIPCIdProduct << 12) | TIPIPCIdVersion;
 
 
    return err;
    return err;
    }
    }
 
 
 
 
static RealUDIVecRecPtr IPCFar * AllocateIntVect()
static RealUDIVecRecPtr IPCFar * AllocateIntVect()
{
{
    RealUDIVecRecPtr IPCFar * VecP;
    RealUDIVecRecPtr IPCFar * VecP;
 
 
    /* Try and find a vector that is unused */
    /* Try and find a vector that is unused */
    for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));
    for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));
         VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));
         VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));
         VecP++) {
         VecP++) {
        if (*VecP == REALNULL)
        if (*VecP == REALNULL)
            return VecP;
            return VecP;
        }
        }
 
 
    return NULL;
    return NULL;
    }
    }
 
 
static RealUDIVecRecPtr IPCFar * FindIntVect()
static RealUDIVecRecPtr IPCFar * FindIntVect()
{
{
    RealUDIVecRecPtr IPCFar * VecP;
    RealUDIVecRecPtr IPCFar * VecP;
    union rec recognizer;
    union rec recognizer;
 
 
    InitRecognizer( &recognizer );
    InitRecognizer( &recognizer );
 
 
    /* Try and find a vector that matches the passed in recognizer */
    /* Try and find a vector that matches the passed in recognizer */
    for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));
    for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));
         VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));
         VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));
         VecP++) {
         VecP++) {
        if ((*VecP != REALNULL) && ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(*VecP))->recognizer.l == recognizer.l)
        if ((*VecP != REALNULL) && ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(*VecP))->recognizer.l == recognizer.l)
                return VecP;
                return VecP;
    }
    }
 
 
    return NULL;
    return NULL;
}
}
 
 
static void SetupEnvironment(void)
static void SetupEnvironment(void)
{
{
#ifndef DOS386
#ifndef DOS386
                /* if not DOS386, nothing to do except set up the
                /* if not DOS386, nothing to do except set up the
                   pointer to TIPVecRec
                   pointer to TIPVecRec
                   */
                   */
        pTIPVecRec = &TIPVecRec;
        pTIPVecRec = &TIPVecRec;
 
 
#else           /* setup code for DOS386 */
#else           /* setup code for DOS386 */
FARPTR  dummyfp;
FARPTR  dummyfp;
REALPTR dummyrp;
REALPTR dummyrp;
ULONG   dummyint;
ULONG   dummyint;
REALPTR IPCFar *p;
REALPTR IPCFar *p;
REALPTR ptr_dos_ext_psp;
REALPTR ptr_dos_ext_psp;
int     err;
int     err;
int     i;
int     i;
 
 
        /**************************************************************
        /**************************************************************
         * There are some initialization things that we might as well do before
         * There are some initialization things that we might as well do before
         * we do the realcopy down below.  Here we do some initialization
         * we do the realcopy down below.  Here we do some initialization
         * of TIPVecRec and the code_selector and data_selector and call_prot
         * of TIPVecRec and the code_selector and data_selector and call_prot
         * routine address that are then used by the real mode code.
         * routine address that are then used by the real mode code.
         ****************************************************************/
         ****************************************************************/
 
 
        _dx_rmlink_get(&call_prot, &dummyrp, &dummyint, &dummyfp);
        _dx_rmlink_get(&call_prot, &dummyrp, &dummyint, &dummyfp);
        code_selector = GetCS();
        code_selector = GetCS();
        data_selector = GetDS();
        data_selector = GetDS();
        for (i=0; i<4; i++)
        for (i=0; i<4; i++)
            segregblock[i] = data_selector;
            segregblock[i] = data_selector;
 
 
        /******************************************************
        /******************************************************
         * Map first 1 meg of physical memory into our ds: address space
         * Map first 1 meg of physical memory into our ds: address space
         * This is 256 4K pages starting at physical address 0.
         * This is 256 4K pages starting at physical address 0.
         * The pointer conventional_memory is its mapped offset in our data space
         * The pointer conventional_memory is its mapped offset in our data space
         * If this mapping cannot be done (because we are running under DPMI 0.90)
         * If this mapping cannot be done (because we are running under DPMI 0.90)
         * then we will have to access dos memory using far pointers and do some
         * then we will have to access dos memory using far pointers and do some
         * copies of data down in the d386 routines.
         * copies of data down in the d386 routines.
         ********************************************************/
         ********************************************************/
        err = _dx_map_phys(data_selector, (ULONG) 0, (ULONG) 256, (ULONG *)&conventional_memory);
        err = _dx_map_phys(data_selector, (ULONG) 0, (ULONG) 256, (ULONG *)&conventional_memory);
        if (err)
        if (err)
            conventional_memory = NULL;
            conventional_memory = NULL;
 
 
#ifdef DEBUG
#ifdef DEBUG
        if (err)
        if (err)
            printf("TIP: Unable to map conventional memory %d\n", err);
            printf("TIP: Unable to map conventional memory %d\n", err);
        else
        else
            printf("TIP: Successfully mapped conventional memory\n");
            printf("TIP: Successfully mapped conventional memory\n");
#endif
#endif
 
 
        if (!conventional_memory) {
        if (!conventional_memory) {
           /* mapping conventional memory did not work */
           /* mapping conventional memory did not work */
           /* need to set up stacks to switch to at UDI call time */
           /* need to set up stacks to switch to at UDI call time */
            create_stack(0, 64000);
            create_stack(0, 64000);
            create_stack(1, 10000);
            create_stack(1, 10000);
            stack_table[2] =  0; /* end of list */
            stack_table[2] =  0; /* end of list */
          }
          }
 
 
        /* do a realcopy to copy all the things that must be reachable
        /* do a realcopy to copy all the things that must be reachable
           * from real mode into a real mode segment.  For simplicity,
           * from real mode into a real mode segment.  For simplicity,
           * we just always assume that REALBREAK might not work.
           * we just always assume that REALBREAK might not work.
           * This is only used at TIP INIT time and the performance impact is negligent.
           * This is only used at TIP INIT time and the performance impact is negligent.
           */
           */
         err = realcopy(0,                 /* real mode stuff was linked first */
         err = realcopy(0,                 /* real mode stuff was linked first */
                        end_real,         /* where the real mode stuff ends */
                        end_real,         /* where the real mode stuff ends */
                        &real_basep,
                        &real_basep,
                        &prot_basep,
                        &prot_basep,
                        &rmem_adrp);
                        &rmem_adrp);
 
 
        if (err) {
        if (err) {
                printf("\nTIP: realcopy call failed;\n");
                printf("\nTIP: realcopy call failed;\n");
                printf(  "     Probable cause: insufficient free conventional memory.\n");
                printf(  "     Probable cause: insufficient free conventional memory.\n");
                do_exit(1);
                do_exit(1);
        }
        }
 
 
 
 
        /* The prot_basep that was returned above must now be used
        /* The prot_basep that was returned above must now be used
           to access from protected mode the data elements that were
           to access from protected mode the data elements that were
           copied above.  In particular, we create a pointer to the
           copied above.  In particular, we create a pointer to the
           copied TIPVecRec and use that.
           copied TIPVecRec and use that.
         */
         */
        pTIPVecRec = (struct UDIVecRec IPCFar *) (prot_basep + (ULONG) &TIPVecRec);
        pTIPVecRec = (struct UDIVecRec IPCFar *) (prot_basep + (ULONG) &TIPVecRec);
 
 
 
 
 
 
        /**************************************************************
        /**************************************************************
         * The real_basep that was returned from realcopy must be used as
         * The real_basep that was returned from realcopy must be used as
         * the code segment pointer of all the real mode routines.
         * the code segment pointer of all the real mode routines.
         * and so must be patched into TIPVecRec.
         * and so must be patched into TIPVecRec.
         * real_basep is returned by realcopy such that the offset parts
         * real_basep is returned by realcopy such that the offset parts
         * (as assembled in in the module dostip.asm) can remain unchanged.
         * (as assembled in in the module dostip.asm) can remain unchanged.
         * So we just need to patch the real_basep seg into each of those pointers
         * So we just need to patch the real_basep seg into each of those pointers
         ***************************************************************/
         ***************************************************************/
        for (p = (REALPTR IPCFar *)&pTIPVecRec->exeName;
        for (p = (REALPTR IPCFar *)&pTIPVecRec->exeName;
             p<= (REALPTR IPCFar *)&pTIPVecRec->UDITransMode; p++) {
             p<= (REALPTR IPCFar *)&pTIPVecRec->UDITransMode; p++) {
                RP_SET(*p, RP_OFF(*p), RP_SEG(real_basep));
                RP_SET(*p, RP_OFF(*p), RP_SEG(real_basep));
        }
        }
 
 
        /*****************************************************
        /*****************************************************
           Store our PSP (real segment) away for later termination
           Store our PSP (real segment) away for later termination
           and also the dos extender's PSP (our parent).  We get this by
           and also the dos extender's PSP (our parent).  We get this by
           building a real pointer with seg = our_tsr_psp, ofst = 0x16,
           building a real pointer with seg = our_tsr_psp, ofst = 0x16,
           and then derefencing that
           and then derefencing that
        *****************************************************/
        *****************************************************/
        our_tsr_psp = GetPSP();
        our_tsr_psp = GetPSP();
        RP_SET(ptr_dos_ext_psp, 0x16, our_tsr_psp);
        RP_SET(ptr_dos_ext_psp, 0x16, our_tsr_psp);
        dos_ext_psp = *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp)));
        dos_ext_psp = *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp)));
 
 
#endif  /* end of DOS386 setup code */
#endif  /* end of DOS386 setup code */
}
}
 
 
 
 
static unsigned int ComputeTSRSize(void *topofstack)
static unsigned int ComputeTSRSize(void *topofstack)
{
{
#ifndef DOS386
#ifndef DOS386
        /* Real mode program, compute program size */
        /* Real mode program, compute program size */
        /* Huge pointers force compiler to do segment arithmetic for us. */
        /* Huge pointers force compiler to do segment arithmetic for us. */
static char _huge *tsrstack;
static char _huge *tsrstack;
static char _huge *tsrbottom;
static char _huge *tsrbottom;
    /* Initialize stack and bottom of program. */
    /* Initialize stack and bottom of program. */
    tsrstack = (char huge *)topofstack;
    tsrstack = (char huge *)topofstack;
    FP_SEG( tsrbottom ) = _psp;
    FP_SEG( tsrbottom ) = _psp;
    FP_OFF( tsrbottom ) = 0;
    FP_OFF( tsrbottom ) = 0;
 
 
    /* Program size is:
    /* Program size is:
     *     top of stack
     *     top of stack
     *   - bottom of program (converted to paragraphs) (using huge math)
     *   - bottom of program (converted to paragraphs) (using huge math)
     *   + one extra paragraph
     *   + one extra paragraph
     */
     */
    return((unsigned int) (((tsrstack - tsrbottom) >> 4) + 1));
    return((unsigned int) (((tsrstack - tsrbottom) >> 4) + 1));
#else
#else
        /*********************
        /*********************
         In DOS386 mode, the TSR size consists of the real memory that
         In DOS386 mode, the TSR size consists of the real memory that
         is used by the Pharlap DOS extender and the small amount of real memory
         is used by the Pharlap DOS extender and the small amount of real memory
         used by UDI.  The number 6400 seems to be a good guess for now.
         used by UDI.  The number 6400 seems to be a good guess for now.
         This might have to be adjusted with newer versions of Dos extender, etc.
         This might have to be adjusted with newer versions of Dos extender, etc.
         I wonder if there is some way to compute this number accurately.
         I wonder if there is some way to compute this number accurately.
         **********************/
         **********************/
        return(6400);   /* our best guess for now */
        return(6400);   /* our best guess for now */
#endif
#endif
}
}
 
 
main(int argc, char *argv[])
main(int argc, char *argv[])
{
{
    unsigned tsrsize;
    unsigned tsrsize;
 
 
    get_tip_name(argc, argv);   /* get name from argv or whereever */
    get_tip_name(argc, argv);   /* get name from argv or whereever */
 
 
#ifdef TSRDEBUG
#ifdef TSRDEBUG
    {
    {
    int i;
    int i;
    printf( "Invoked with %d arguments\n", argc );
    printf( "Invoked with %d arguments\n", argc );
    for (i = 0; i < argc; i++)
    for (i = 0; i < argc; i++)
        printf( "%s ", argv[i] );
        printf( "%s ", argv[i] );
    printf( "\n" );
    printf( "\n" );
    }
    }
#endif
#endif
 
 
    InitRecognizer(&TIPVecRec.recognizer );
    InitRecognizer(&TIPVecRec.recognizer );
 
 
    SetupEnvironment();         /* do some setup specific to DOS or DOS386 */
    SetupEnvironment();         /* do some setup specific to DOS or DOS386 */
 
 
 
 
    /* See if the interrupt vector has already been selected for us */
    /* See if the interrupt vector has already been selected for us */
    if ((UDIVecP = FindIntVect()) == NULL) {
    if ((UDIVecP = FindIntVect()) == NULL) {
        if ((UDIVecP = AllocateIntVect()) == NULL)
        if ((UDIVecP = AllocateIntVect()) == NULL)
            return -1;  /* No interrupt vectors available */
            return -1;  /* No interrupt vectors available */
        }
        }
    else {      /* Interrupt vector already allocated */
    else {      /* Interrupt vector already allocated */
        pTIPVecRec->Next = *UDIVecP;            /* always store a real ptr there */
        pTIPVecRec->Next = *UDIVecP;            /* always store a real ptr there */
        ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = FARCPTR_TO_REALPTR(pTIPVecRec);
        ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = FARCPTR_TO_REALPTR(pTIPVecRec);
        }
        }
 
 
    *UDIVecP = FARCPTR_TO_REALPTR(pTIPVecRec);
    *UDIVecP = FARCPTR_TO_REALPTR(pTIPVecRec);
 
 
    tsrsize = ComputeTSRSize(&argv);    /* pass it pointer to argv (top of stack) */
    tsrsize = ComputeTSRSize(&argv);    /* pass it pointer to argv (top of stack) */
 
 
    /* We are now ready to support DFEs. If we wish to debug back-ends,
    /* We are now ready to support DFEs. If we wish to debug back-ends,
       though, we are probably running CodeView with the TIP right now
       though, we are probably running CodeView with the TIP right now
       and don't want to really TSR because CV will shut down at that
       and don't want to really TSR because CV will shut down at that
       point. Instead, let's spawn a new DOS shell from which we can
       point. Instead, let's spawn a new DOS shell from which we can
       start a DFE (after setting a breakpoint in the TIP somewhere).
       start a DFE (after setting a breakpoint in the TIP somewhere).
    */
    */
#ifdef TSRDEBUG
#ifdef TSRDEBUG
    system( getenv( "COMSPEC" ) );
    system( getenv( "COMSPEC" ) );
#else
#else
    do_dos_keep(0, tsrsize);
    do_dos_keep(0, tsrsize);
#endif
#endif
 
 
    return 0;
    return 0;
}
}
 
 
 
 
#define GET_PSP_DOS2    0x51
#define GET_PSP_DOS2    0x51
#define GET_PSP_DOS3    0x62
#define GET_PSP_DOS3    0x62
#define SET_PSP         0x50
#define SET_PSP         0x50
 
 
static unsigned short GetPSP( void )
static unsigned short GetPSP( void )
{
{
    union REGS regs;
    union REGS regs;
 
 
    if (_osmajor == 2)
    if (_osmajor == 2)
        return 0;
        return 0;
#ifdef DOS386
#ifdef DOS386
    regs.h.ah = GET_PSP_DOS2;   /* Phar Lap requires we use this to get real segment */
    regs.h.ah = GET_PSP_DOS2;   /* Phar Lap requires we use this to get real segment */
#else
#else
    regs.h.ah = GET_PSP_DOS3;
    regs.h.ah = GET_PSP_DOS3;
#endif
#endif
    intdos( &regs, &regs );
    intdos( &regs, &regs );
    return regs.x.bx;
    return regs.x.bx;
}
}
 
 
static void SetPSP( unsigned short PSPSegment )
static void SetPSP( unsigned short PSPSegment )
{
{
    union REGS regs;
    union REGS regs;
 
 
    regs.h.ah = SET_PSP;
    regs.h.ah = SET_PSP;
    regs.x.bx = PSPSegment;
    regs.x.bx = PSPSegment;
    intdos( &regs, &regs );
    intdos( &regs, &regs );
}
}
 
 
 
 
#ifdef DOS386
#ifdef DOS386
/*============================ DOS386 glue routines ====================================*/
/*============================ DOS386 glue routines ====================================*/
 
 
/****************************************************************
/****************************************************************
 * In DPMI Compatibility mode, when we get to this point, the only
 * In DPMI Compatibility mode, when we get to this point, the only
 * thing that is on the stack is the saved far stack pointer (which actually
 * thing that is on the stack is the saved far stack pointer (which actually
 * points back to the real mode stack).   Remember in pmstub in dostip.asm,
 * points back to the real mode stack).   Remember in pmstub in dostip.asm,
 * we switched stack pointers so that SS = DS for C level requirements.
 * we switched stack pointers so that SS = DS for C level requirements.
 *
 *
 * The INCOMING_PARAMS macro defines a packed structure which expresses what the
 * The INCOMING_PARAMS macro defines a packed structure which expresses what the
 * real mode stack really looks like when we get to each dos386 glue routine.
 * real mode stack really looks like when we get to each dos386 glue routine.
 * The STACK_PAD is all the extra stuff that was on the stack because of the switching
 * The STACK_PAD is all the extra stuff that was on the stack because of the switching
 * from real to protected mode, etc.
 * from real to protected mode, etc.
 * The packed structure can be used to express where things really are on the stack
 * The packed structure can be used to express where things really are on the stack
 * because the DFE's MSC compiler will push things differently from the hc386 compiler.
 * because the DFE's MSC compiler will push things differently from the hc386 compiler.
 ********************************************************************/
 ********************************************************************/
typedef _packed struct {
typedef _packed struct {
        FARPTR  ret_to_dosext;
        FARPTR  ret_to_dosext;
        USHORT  zero_word;
        USHORT  zero_word;
        USHORT  saved_di;
        USHORT  saved_di;
        USHORT  saved_si;
        USHORT  saved_si;
        USHORT  saved_bp;
        USHORT  saved_bp;
        USHORT  saved_ds;
        USHORT  saved_ds;
        ULONG   ret_to_dfe;
        ULONG   ret_to_dfe;
} STACK_PAD;
} STACK_PAD;
 
 
/* The following macro defines the packed structure for the incoming parameters
/* The following macro defines the packed structure for the incoming parameters
 * including the STACK_PAD stuff noted above.  It is used by those few d386_
 * including the STACK_PAD stuff noted above.  It is used by those few d386_
 * routines that do not need converted pointers to avoid non-use warnings
 * routines that do not need converted pointers to avoid non-use warnings
 */
 */
#define INCOMING_PARAMS_NO_PTR(params)  \
#define INCOMING_PARAMS_NO_PTR(params)  \
        _packed struct {                \
        _packed struct {                \
            STACK_PAD padding;          \
            STACK_PAD padding;          \
            params                      \
            params                      \
        } _far *in  = rm_stk_ptr;       \
        } _far *in  = rm_stk_ptr;       \
 
 
 
 
/* The following macro defines the packed structure for the incoming parameters
/* The following macro defines the packed structure for the incoming parameters
 * (see above) and also defines a local structure for storing the converted local
 * (see above) and also defines a local structure for storing the converted local
 * pointers.  Most d386_ routines use this macro.
 * pointers.  Most d386_ routines use this macro.
 */
 */
#define INCOMING_PARAMS(params)         \
#define INCOMING_PARAMS(params)         \
        INCOMING_PARAMS_NO_PTR(params)  \
        INCOMING_PARAMS_NO_PTR(params)  \
        struct {                        \
        struct {                        \
            params                      \
            params                      \
            int dummy;     /* to avoid warnings and for local count */          \
            int dummy;     /* to avoid warnings and for local count */          \
        } local ;    /* local structure for holding converted pointers */  \
        } local ;    /* local structure for holding converted pointers */  \
        int  stackspace = stacksize;    \
        int  stackspace = stacksize;    \
 
 
 
 
 
 
/**************************************************************
/**************************************************************
 * The following macros handle the creation of near C pointers from real pointers
 * The following macros handle the creation of near C pointers from real pointers
 * so that the real UDI routines can be called with near C pointers.
 * so that the real UDI routines can be called with near C pointers.
 * Different macros are called for IN pointers vs. OUT pointers and
 * Different macros are called for IN pointers vs. OUT pointers and
 * for PREPROCESSING (before the real UDI call) and POSTPROCESSING (cleanup
 * for PREPROCESSING (before the real UDI call) and POSTPROCESSING (cleanup
 * after returning from the real UDI call).
 * after returning from the real UDI call).
 *
 *
 * If conventional_memory has been mapped, the following happens
 * If conventional_memory has been mapped, the following happens
 *      PREPROCESS (IN or OUT ptr) sets local.var pointer to the mapped pointer
 *      PREPROCESS (IN or OUT ptr) sets local.var pointer to the mapped pointer
 *                                 nothing to copy so count is ignored
 *                                 nothing to copy so count is ignored
 *      POSTPROCESS                nothing to do
 *      POSTPROCESS                nothing to do
 *
 *
 * If conventional_memory has not been mapped, then
 * If conventional_memory has not been mapped, then
 *      PREPROCESS (IN ptr)        does alloca of count to get local pointer
 *      PREPROCESS (IN ptr)        does alloca of count to get local pointer
 *                                 copies data into local allocated area
 *                                 copies data into local allocated area
 *      PREPROCESS (OUT ptr)       does alloca of count to get local pointer
 *      PREPROCESS (OUT ptr)       does alloca of count to get local pointer
 *                                 no copy of data yet.
 *                                 no copy of data yet.
 *      POSTPROCESS (OUT ptr)      copies data from local allocated area back to real mem
 *      POSTPROCESS (OUT ptr)      copies data from local allocated area back to real mem
 *
 *
 * Note that a few UDI routines have pointers that are both IN and OUT
 * Note that a few UDI routines have pointers that are both IN and OUT
 */
 */
 
 
        /* the following is used in a couple of places in the macros */
        /* the following is used in a couple of places in the macros */
#define ALLOC_LOCAL(var, count) \
#define ALLOC_LOCAL(var, count) \
        if ((stackspace -= count) <= 500) return(UDIErrorIPCLimitation); \
        if ((stackspace -= count) <= 500) return(UDIErrorIPCLimitation); \
        local.var = alloca(count);
        local.var = alloca(count);
 
 
#define INPTR_PREPROCESS_COUNT(var,count)  \
#define INPTR_PREPROCESS_COUNT(var,count)  \
    if (conventional_memory) { \
    if (conventional_memory) { \
        local.var = REALPTR_TO_NEARCPTR(in->var); \
        local.var = REALPTR_TO_NEARCPTR(in->var); \
    } \
    } \
    else { \
    else { \
        local.dummy = count;    /* avoid double evaluation if count is expression */   \
        local.dummy = count;    /* avoid double evaluation if count is expression */   \
        ALLOC_LOCAL(var, local.dummy); \
        ALLOC_LOCAL(var, local.dummy); \
        movedata(SS_DOSMEM, LINEARIZE(in->var), data_selector, (unsigned int) local.var, local.dummy); \
        movedata(SS_DOSMEM, LINEARIZE(in->var), data_selector, (unsigned int) local.var, local.dummy); \
    }
    }
 
 
 
 
#define INPTR_PREPROCESS(var) INPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))
#define INPTR_PREPROCESS(var) INPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))
 
 
#define OUTPTR_PREPROCESS_COUNT(var,count)  \
#define OUTPTR_PREPROCESS_COUNT(var,count)  \
    if (conventional_memory)  \
    if (conventional_memory)  \
        local.var = REALPTR_TO_NEARCPTR(in->var); \
        local.var = REALPTR_TO_NEARCPTR(in->var); \
    else { \
    else { \
        ALLOC_LOCAL(var,count); \
        ALLOC_LOCAL(var,count); \
    }
    }
 
 
#define OUTPTR_PREPROCESS(var) OUTPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))
#define OUTPTR_PREPROCESS(var) OUTPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))
 
 
#define OUTPTR_POSTPROCESS_COUNT(var,count)  \
#define OUTPTR_POSTPROCESS_COUNT(var,count)  \
    if (!conventional_memory) {\
    if (!conventional_memory) {\
        movedata(data_selector, (unsigned int)local.var, SS_DOSMEM, LINEARIZE(in->var), count); \
        movedata(data_selector, (unsigned int)local.var, SS_DOSMEM, LINEARIZE(in->var), count); \
    }
    }
 
 
#define OUTPTR_POSTPROCESS(var) OUTPTR_POSTPROCESS_COUNT(var, sizeof(*(in->var)))
#define OUTPTR_POSTPROCESS(var) OUTPTR_POSTPROCESS_COUNT(var, sizeof(*(in->var)))
 
 
 
 
 
 
/* The following routine computes the length of a string that
/* The following routine computes the length of a string that
 * is pointed to by a real pointer.  This is only needed when
 * is pointed to by a real pointer.  This is only needed when
 * we cannot map real mode memory at the end of the DS.
 * we cannot map real mode memory at the end of the DS.
 */
 */
int realptr_strlen(REALPTR rp)
int realptr_strlen(REALPTR rp)
{
{
char _far *farp;
char _far *farp;
char _far *start;
char _far *start;
 
 
    farp = (char _far *) REALPTR_TO_FARCPTR(rp);   /* need to use a far c ptr */
    farp = (char _far *) REALPTR_TO_FARCPTR(rp);   /* need to use a far c ptr */
    start = farp;
    start = farp;
    while (*farp++);       /* advance until a 0 located */
    while (*farp++);       /* advance until a 0 located */
    return(FP_OFF(farp) - FP_OFF(start));
    return(FP_OFF(farp) - FP_OFF(start));
}
}
 
 
/*========================  Glue Routines ============================================*/
/*========================  Glue Routines ============================================*/
 
 
 
 
UDIError d386_UDIConnect (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIConnect (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  char          *Configuration;         /* In  */
  char          *Configuration;         /* In  */
  UDISessionId  *Session;               /* Out */
  UDISessionId  *Session;               /* Out */
  DOSTerm           *TermStruct;        /* In - not seen in UDIP */
  DOSTerm           *TermStruct;        /* In - not seen in UDIP */
)
)
UDIError err;
UDIError err;
 
 
    INPTR_PREPROCESS_COUNT(Configuration, realptr_strlen((REALPTR)(in->Configuration))+1);
    INPTR_PREPROCESS_COUNT(Configuration, realptr_strlen((REALPTR)(in->Configuration))+1);
    OUTPTR_PREPROCESS(Session);
    OUTPTR_PREPROCESS(Session);
 
 
    err = UDICConnect(     /* for UDIConnect, special case, call UDICConnect in dos2udip.c */
    err = UDICConnect(     /* for UDIConnect, special case, call UDICConnect in dos2udip.c */
        local.Configuration,
        local.Configuration,
        local.Session,
        local.Session,
        REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)
        REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)
    );
    );
 
 
    OUTPTR_POSTPROCESS(Session);
    OUTPTR_POSTPROCESS(Session);
    return(err);
    return(err);
}
}
 
 
UDIError d386_UDIDisconnect (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIDisconnect (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDISessionId  Session;                /* In */
  UDISessionId  Session;                /* In */
  UDIBool       Terminate;
  UDIBool       Terminate;
  DOSTerm           *TermStruct;                /* In - not seen in UDIP */
  DOSTerm           *TermStruct;                /* In - not seen in UDIP */
)
)
UDIError err;
UDIError err;
 
 
    local.dummy = 0;                    /* avoids warning */
    local.dummy = 0;                    /* avoids warning */
    err = UDICDisconnect(               /* need to call UDICDisconnect */
    err = UDICDisconnect(               /* need to call UDICDisconnect */
        in->Session,
        in->Session,
        in->Terminate,
        in->Terminate,
        REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)
        REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)
    );
    );
    return(err);
    return(err);
 
 
}
}
 
 
 
 
UDIError d386_UDISetCurrentConnection  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDISetCurrentConnection  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS_NO_PTR(
INCOMING_PARAMS_NO_PTR(
  UDISessionId  Session;                /* In */
  UDISessionId  Session;                /* In */
)
)
        return(UDISetCurrentConnection(in->Session));
        return(UDISetCurrentConnection(in->Session));
}
}
 
 
 
 
UDIError d386_UDICapabilities  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDICapabilities  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIUInt32     *TIPId;                 /* Out */
  UDIUInt32     *TIPId;                 /* Out */
  UDIUInt32     *TargetId;              /* Out */
  UDIUInt32     *TargetId;              /* Out */
  UDIUInt32     DFEId;                  /* In */
  UDIUInt32     DFEId;                  /* In */
  UDIUInt32     DFE;                    /* In */
  UDIUInt32     DFE;                    /* In */
  UDIUInt32     *TIP;                   /* Out */
  UDIUInt32     *TIP;                   /* Out */
  UDIUInt32     *DFEIPCId;              /* Out */
  UDIUInt32     *DFEIPCId;              /* Out */
  UDIUInt32     *TIPIPCId;              /* Out */
  UDIUInt32     *TIPIPCId;              /* Out */
  char          *TIPString;             /* Out */
  char          *TIPString;             /* Out */
)
)
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(TIPId);
    OUTPTR_PREPROCESS(TIPId);
    OUTPTR_PREPROCESS(TargetId);
    OUTPTR_PREPROCESS(TargetId);
    OUTPTR_PREPROCESS(TIP);
    OUTPTR_PREPROCESS(TIP);
    OUTPTR_PREPROCESS(DFEIPCId);
    OUTPTR_PREPROCESS(DFEIPCId);
    OUTPTR_PREPROCESS(TIPIPCId);
    OUTPTR_PREPROCESS(TIPIPCId);
    OUTPTR_PREPROCESS_COUNT(TIPString, 100);   /* max TIP string? */
    OUTPTR_PREPROCESS_COUNT(TIPString, 100);   /* max TIP string? */
 
 
    err = UDICCapabilities(             /* another special case call UDICapabilities */
    err = UDICCapabilities(             /* another special case call UDICapabilities */
        local.TIPId,
        local.TIPId,
        local.TargetId,
        local.TargetId,
        in->DFEId,
        in->DFEId,
        in->DFE,
        in->DFE,
        local.TIP,
        local.TIP,
        local.DFEIPCId,
        local.DFEIPCId,
        local.TIPIPCId,
        local.TIPIPCId,
        local.TIPString
        local.TIPString
    );
    );
 
 
    OUTPTR_POSTPROCESS(TIPId);
    OUTPTR_POSTPROCESS(TIPId);
    OUTPTR_POSTPROCESS(TargetId);
    OUTPTR_POSTPROCESS(TargetId);
    OUTPTR_POSTPROCESS(TIP);
    OUTPTR_POSTPROCESS(TIP);
    OUTPTR_POSTPROCESS(DFEIPCId);
    OUTPTR_POSTPROCESS(DFEIPCId);
    OUTPTR_POSTPROCESS(TIPIPCId);
    OUTPTR_POSTPROCESS(TIPIPCId);
    OUTPTR_POSTPROCESS_COUNT(TIPString, strlen(local.TIPString)+1);
    OUTPTR_POSTPROCESS_COUNT(TIPString, strlen(local.TIPString)+1);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDIGetErrorMsg  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIGetErrorMsg  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIError      ErrorCode;              /* In */
  UDIError      ErrorCode;              /* In */
  UDISizeT      MsgSize;                /* In */
  UDISizeT      MsgSize;                /* In */
  char          *Msg;                   /* Out */
  char          *Msg;                   /* Out */
  UDISizeT      *CountDone;             /* Out */
  UDISizeT      *CountDone;             /* Out */
)
)
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS_COUNT(Msg, in->MsgSize);
    OUTPTR_PREPROCESS_COUNT(Msg, in->MsgSize);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIGetErrorMsg(
    err = UDIGetErrorMsg(
        in->ErrorCode,
        in->ErrorCode,
        in->MsgSize,
        in->MsgSize,
        local.Msg,              /* pointers made local */
        local.Msg,              /* pointers made local */
        local.CountDone
        local.CountDone
    );
    );
 
 
    OUTPTR_POSTPROCESS_COUNT(Msg, *(local.CountDone)+1);
    OUTPTR_POSTPROCESS_COUNT(Msg, *(local.CountDone)+1);
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIError d386_UDIGetTargetConfig (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIGetTargetConfig (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIMemoryRange *KnownMemory;          /* Out */
  UDIMemoryRange *KnownMemory;          /* Out */
  UDIInt        *NumberOfRanges;        /* In/Out */
  UDIInt        *NumberOfRanges;        /* In/Out */
  UDIUInt32     *ChipVersions;          /* Out */
  UDIUInt32     *ChipVersions;          /* Out */
  UDIInt        *NumberOfChips;         /* In/Out */
  UDIInt        *NumberOfChips;         /* In/Out */
)
)
UDIError err;
UDIError err;
 
 
    INPTR_PREPROCESS(NumberOfRanges);
    INPTR_PREPROCESS(NumberOfRanges);
    INPTR_PREPROCESS(NumberOfChips);
    INPTR_PREPROCESS(NumberOfChips);
    OUTPTR_PREPROCESS_COUNT(KnownMemory, *(local.NumberOfRanges) * sizeof(UDIMemoryRange));
    OUTPTR_PREPROCESS_COUNT(KnownMemory, *(local.NumberOfRanges) * sizeof(UDIMemoryRange));
    OUTPTR_PREPROCESS_COUNT(ChipVersions, *(local.NumberOfChips) * sizeof(UDIUInt32));
    OUTPTR_PREPROCESS_COUNT(ChipVersions, *(local.NumberOfChips) * sizeof(UDIUInt32));
 
 
    err = UDIGetTargetConfig(
    err = UDIGetTargetConfig(
        local.KnownMemory,
        local.KnownMemory,
        local.NumberOfRanges,
        local.NumberOfRanges,
        local.ChipVersions,
        local.ChipVersions,
        local.NumberOfChips
        local.NumberOfChips
    );
    );
 
 
    OUTPTR_POSTPROCESS(NumberOfRanges);
    OUTPTR_POSTPROCESS(NumberOfRanges);
    OUTPTR_POSTPROCESS(NumberOfChips);
    OUTPTR_POSTPROCESS(NumberOfChips);
    OUTPTR_POSTPROCESS_COUNT(KnownMemory, *(local.NumberOfRanges) * sizeof(UDIMemoryRange));
    OUTPTR_POSTPROCESS_COUNT(KnownMemory, *(local.NumberOfRanges) * sizeof(UDIMemoryRange));
    OUTPTR_POSTPROCESS_COUNT(ChipVersions, *(local.NumberOfChips) * sizeof(UDIUInt32));
    OUTPTR_POSTPROCESS_COUNT(ChipVersions, *(local.NumberOfChips) * sizeof(UDIUInt32));
 
 
    return(err);
    return(err);
}
}
 
 
UDIError d386_UDICreateProcess (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDICreateProcess (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIPId        *PId;                   /* Out */
  UDIPId        *PId;                   /* Out */
)
)
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(PId);
    OUTPTR_PREPROCESS(PId);
 
 
    err = UDICreateProcess(
    err = UDICreateProcess(
        local.PId
        local.PId
    );
    );
 
 
    OUTPTR_POSTPROCESS(PId);
    OUTPTR_POSTPROCESS(PId);
    return(err);
    return(err);
}
}
 
 
UDIError d386_UDISetCurrentProcess (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDISetCurrentProcess (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS_NO_PTR(
INCOMING_PARAMS_NO_PTR(
  UDIPId        PId;                    /* In */
  UDIPId        PId;                    /* In */
  )
  )
 
 
    return(UDISetCurrentProcess(
    return(UDISetCurrentProcess(
        in->PId
        in->PId
    ));
    ));
}
}
 
 
UDIError d386_UDIDestroyProcess (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIDestroyProcess (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS_NO_PTR(
INCOMING_PARAMS_NO_PTR(
  UDIPId        PId;                    /* In */
  UDIPId        PId;                    /* In */
  )
  )
 
 
    return(UDIDestroyProcess(
    return(UDIDestroyProcess(
        in->PId
        in->PId
    ));
    ));
}
}
 
 
 
 
 
 
UDIError d386_UDIInitializeProcess (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIInitializeProcess (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIMemoryRange *ProcessMemory;        /* In */
  UDIMemoryRange *ProcessMemory;        /* In */
  UDIInt        NumberOfRanges;         /* In */
  UDIInt        NumberOfRanges;         /* In */
  UDIResource   EntryPoint;             /* In */
  UDIResource   EntryPoint;             /* In */
  CPUSizeT      *StackSizes;            /* In */
  CPUSizeT      *StackSizes;            /* In */
  UDIInt        NumberOfStacks;         /* In */
  UDIInt        NumberOfStacks;         /* In */
  char          *ArgString;             /* In */
  char          *ArgString;             /* In */
  )
  )
UDIError err;
UDIError err;
 
 
    INPTR_PREPROCESS_COUNT(ProcessMemory, in->NumberOfRanges * sizeof(UDIMemoryRange));
    INPTR_PREPROCESS_COUNT(ProcessMemory, in->NumberOfRanges * sizeof(UDIMemoryRange));
    INPTR_PREPROCESS_COUNT(StackSizes, in->NumberOfStacks * sizeof(CPUSizeT));
    INPTR_PREPROCESS_COUNT(StackSizes, in->NumberOfStacks * sizeof(CPUSizeT));
    INPTR_PREPROCESS_COUNT(ArgString, realptr_strlen((REALPTR)(in->ArgString))+1);
    INPTR_PREPROCESS_COUNT(ArgString, realptr_strlen((REALPTR)(in->ArgString))+1);
 
 
    err = UDIInitializeProcess(
    err = UDIInitializeProcess(
        local.ProcessMemory,
        local.ProcessMemory,
        in->NumberOfRanges,
        in->NumberOfRanges,
        in->EntryPoint,
        in->EntryPoint,
        local.StackSizes,
        local.StackSizes,
        in->NumberOfStacks,
        in->NumberOfStacks,
        local.ArgString
        local.ArgString
    );
    );
 
 
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIError d386_UDIRead (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIRead (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIResource   From;                   /* In */
  UDIResource   From;                   /* In */
  UDIHostMemPtr To;                     /* Out */
  UDIHostMemPtr To;                     /* Out */
  UDICount      Count;                  /* In */
  UDICount      Count;                  /* In */
  UDISizeT      Size;                   /* In */
  UDISizeT      Size;                   /* In */
  UDICount      *CountDone;             /* Out */
  UDICount      *CountDone;             /* Out */
  UDIBool       HostEndian;             /* In */
  UDIBool       HostEndian;             /* In */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS_COUNT(To, in->Count * in->Size);
    OUTPTR_PREPROCESS_COUNT(To, in->Count * in->Size);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIRead(
    err = UDIRead(
        in->From,
        in->From,
        local.To,
        local.To,
        in->Count,
        in->Count,
        in->Size,
        in->Size,
        local.CountDone,
        local.CountDone,
        in->HostEndian
        in->HostEndian
    );
    );
 
 
    OUTPTR_POSTPROCESS_COUNT(To, *(local.CountDone) * in->Size);
    OUTPTR_POSTPROCESS_COUNT(To, *(local.CountDone) * in->Size);
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIError d386_UDIWrite  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIWrite  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIHostMemPtr From;                   /* In */
  UDIHostMemPtr From;                   /* In */
  UDIResource   To;                     /* In */
  UDIResource   To;                     /* In */
  UDICount      Count;                  /* In */
  UDICount      Count;                  /* In */
  UDISizeT      Size;                   /* In */
  UDISizeT      Size;                   /* In */
  UDICount      *CountDone;             /* Out */
  UDICount      *CountDone;             /* Out */
  UDIBool       HostEndian;             /* In */
  UDIBool       HostEndian;             /* In */
  )
  )
UDIError err;
UDIError err;
 
 
    INPTR_PREPROCESS_COUNT (From, in->Count * in->Size);
    INPTR_PREPROCESS_COUNT (From, in->Count * in->Size);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIWrite(
    err = UDIWrite(
        local.From,
        local.From,
        in->To,
        in->To,
        in->Count,
        in->Count,
        in->Size,
        in->Size,
        local.CountDone,
        local.CountDone,
        in->HostEndian
        in->HostEndian
    );
    );
 
 
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
 
 
}
}
 
 
 
 
UDIError d386_UDICopy (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDICopy (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIResource   From;                   /* In */
  UDIResource   From;                   /* In */
  UDIResource   To;                     /* In */
  UDIResource   To;                     /* In */
  UDICount      Count;                  /* In */
  UDICount      Count;                  /* In */
  UDISizeT      Size;                   /* In */
  UDISizeT      Size;                   /* In */
  UDICount      *CountDone;             /* Out */
  UDICount      *CountDone;             /* Out */
  UDIBool       Direction;              /* In */
  UDIBool       Direction;              /* In */
 )
 )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDICopy(
    err = UDICopy(
        in->From,
        in->From,
        in->To,
        in->To,
        in->Count,
        in->Count,
        in->Size,
        in->Size,
        local.CountDone,
        local.CountDone,
        in->Direction
        in->Direction
    );
    );
 
 
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDIExecute (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIExecute (void _far * rm_stk_ptr, int stacksize)
{
{
/* no incoming parameters */
/* no incoming parameters */
 
 
    return(UDIExecute());
    return(UDIExecute());
}
}
 
 
 
 
UDIError d386_UDIStep  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIStep  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS_NO_PTR(
INCOMING_PARAMS_NO_PTR(
  UDIUInt32     Steps;                  /* In */
  UDIUInt32     Steps;                  /* In */
  UDIStepType   StepType;               /* In */
  UDIStepType   StepType;               /* In */
  UDIRange      Range;                  /* In */
  UDIRange      Range;                  /* In */
  )
  )
UDIError err;
UDIError err;
 
 
    err = UDIStep(
    err = UDIStep(
        in->Steps,
        in->Steps,
        in->StepType,
        in->StepType,
        in->Range
        in->Range
    );
    );
 
 
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIVoid d386_UDIStop   (void _far * rm_stk_ptr, int stacksize)
UDIVoid d386_UDIStop   (void _far * rm_stk_ptr, int stacksize)
{
{
/* no incoming parameters, no return value */
/* no incoming parameters, no return value */
    UDIStop();
    UDIStop();
}
}
 
 
 
 
 
 
 
 
UDIError d386_UDIWait  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIWait  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIInt32      MaxTime;                /* In */
  UDIInt32      MaxTime;                /* In */
  UDIPId        *PId;                   /* Out */
  UDIPId        *PId;                   /* Out */
  UDIUInt32     *StopReason;            /* Out */
  UDIUInt32     *StopReason;            /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(PId);
    OUTPTR_PREPROCESS(PId);
    OUTPTR_PREPROCESS(StopReason);
    OUTPTR_PREPROCESS(StopReason);
 
 
    err = UDIWait(
    err = UDIWait(
        in->MaxTime,
        in->MaxTime,
        local.PId,
        local.PId,
        local.StopReason
        local.StopReason
    );
    );
 
 
    OUTPTR_POSTPROCESS(PId);
    OUTPTR_POSTPROCESS(PId);
    OUTPTR_POSTPROCESS(StopReason);
    OUTPTR_POSTPROCESS(StopReason);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIError d386_UDISetBreakpoint  (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDISetBreakpoint  (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIResource   Addr;                   /* In */
  UDIResource   Addr;                   /* In */
  UDIInt32      PassCount;              /* In */
  UDIInt32      PassCount;              /* In */
  UDIBreakType  Type;                   /* In */
  UDIBreakType  Type;                   /* In */
  UDIBreakId    *BreakId;               /* Out */
  UDIBreakId    *BreakId;               /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(BreakId);
    OUTPTR_PREPROCESS(BreakId);
 
 
    err = UDISetBreakpoint(
    err = UDISetBreakpoint(
        in->Addr,
        in->Addr,
        in->PassCount,
        in->PassCount,
        in->Type,
        in->Type,
        local.BreakId
        local.BreakId
    );
    );
 
 
    OUTPTR_POSTPROCESS(BreakId);
    OUTPTR_POSTPROCESS(BreakId);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDIQueryBreakpoint   (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIQueryBreakpoint   (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIBreakId    BreakId;                /* In */
  UDIBreakId    BreakId;                /* In */
  UDIResource   *Addr;                  /* Out */
  UDIResource   *Addr;                  /* Out */
  UDIInt32      *PassCount;             /* Out */
  UDIInt32      *PassCount;             /* Out */
  UDIBreakType  *Type;          /* Out */
  UDIBreakType  *Type;          /* Out */
  UDIInt32      *CurrentCount;          /* Out */
  UDIInt32      *CurrentCount;          /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(Addr);
    OUTPTR_PREPROCESS(Addr);
    OUTPTR_PREPROCESS(PassCount);
    OUTPTR_PREPROCESS(PassCount);
    OUTPTR_PREPROCESS(Type);
    OUTPTR_PREPROCESS(Type);
    OUTPTR_PREPROCESS(CurrentCount);
    OUTPTR_PREPROCESS(CurrentCount);
 
 
    err = UDIQueryBreakpoint(
    err = UDIQueryBreakpoint(
        in->BreakId,
        in->BreakId,
        local.Addr,
        local.Addr,
        local.PassCount,
        local.PassCount,
        local.Type,
        local.Type,
        local.CurrentCount
        local.CurrentCount
    );
    );
 
 
    OUTPTR_POSTPROCESS(Addr);
    OUTPTR_POSTPROCESS(Addr);
    OUTPTR_POSTPROCESS(PassCount);
    OUTPTR_POSTPROCESS(PassCount);
    OUTPTR_POSTPROCESS(Type);
    OUTPTR_POSTPROCESS(Type);
    OUTPTR_POSTPROCESS(CurrentCount);
    OUTPTR_POSTPROCESS(CurrentCount);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIError d386_UDIClearBreakpoint (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIClearBreakpoint (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS_NO_PTR(
INCOMING_PARAMS_NO_PTR(
  UDIBreakId    BreakId;                /* In */
  UDIBreakId    BreakId;                /* In */
  )
  )
    return(UDIClearBreakpoint(
    return(UDIClearBreakpoint(
        in->BreakId
        in->BreakId
    ));
    ));
 
 
}
}
 
 
UDIError d386_UDIGetStdout (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIGetStdout (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIHostMemPtr Buf;                    /* Out */
  UDIHostMemPtr Buf;                    /* Out */
  UDISizeT      BufSize;                /* In */
  UDISizeT      BufSize;                /* In */
  UDISizeT      *CountDone;             /* Out */
  UDISizeT      *CountDone;             /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
    OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIGetStdout(
    err = UDIGetStdout(
        local.Buf,
        local.Buf,
        in->BufSize,
        in->BufSize,
        local.CountDone
        local.CountDone
    );
    );
 
 
    OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
    OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDIGetStderr (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIGetStderr (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIHostMemPtr Buf;                    /* Out */
  UDIHostMemPtr Buf;                    /* Out */
  UDISizeT      BufSize;                /* In */
  UDISizeT      BufSize;                /* In */
  UDISizeT      *CountDone;             /* Out */
  UDISizeT      *CountDone;             /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
    OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIGetStderr(
    err = UDIGetStderr(
        local.Buf,
        local.Buf,
        in->BufSize,
        in->BufSize,
        local.CountDone
        local.CountDone
    );
    );
 
 
    OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
    OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
 
 
UDIError d386_UDIPutStdin (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIPutStdin (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIHostMemPtr Buf;                    /* In */
  UDIHostMemPtr Buf;                    /* In */
  UDISizeT      Count;                  /* In */
  UDISizeT      Count;                  /* In */
  UDISizeT      *CountDone;             /* Out */
  UDISizeT      *CountDone;             /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    INPTR_PREPROCESS_COUNT(Buf, in->Count);
    INPTR_PREPROCESS_COUNT(Buf, in->Count);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIPutStdin(
    err = UDIPutStdin(
        local.Buf,
        local.Buf,
        in->Count,
        in->Count,
        local.CountDone
        local.CountDone
    );
    );
 
 
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDIStdinMode (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIStdinMode (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIMode       *Mode;                  /* Out */
  UDIMode       *Mode;                  /* Out */
 )
 )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(Mode);
    OUTPTR_PREPROCESS(Mode);
 
 
    err = UDIStdinMode(
    err = UDIStdinMode(
        local.Mode
        local.Mode
    );
    );
 
 
    OUTPTR_POSTPROCESS(Mode);
    OUTPTR_POSTPROCESS(Mode);
 
 
    return(err);
    return(err);
}
}
 
 
UDIError d386_UDIPutTrans (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIPutTrans (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIHostMemPtr Buf;                    /* In */
  UDIHostMemPtr Buf;                    /* In */
  UDISizeT      Count;                  /* In */
  UDISizeT      Count;                  /* In */
  UDISizeT      *CountDone;             /* Out */
  UDISizeT      *CountDone;             /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    INPTR_PREPROCESS_COUNT(Buf, in->Count);
    INPTR_PREPROCESS_COUNT(Buf, in->Count);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIPutTrans(
    err = UDIPutTrans(
        local.Buf,
        local.Buf,
        in->Count,
        in->Count,
        local.CountDone
        local.CountDone
    );
    );
 
 
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDIGetTrans (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDIGetTrans (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIHostMemPtr Buf;                    /* Out */
  UDIHostMemPtr Buf;                    /* Out */
  UDISizeT      BufSize;                /* In */
  UDISizeT      BufSize;                /* In */
  UDISizeT      *CountDone;             /* Out */
  UDISizeT      *CountDone;             /* Out */
  )
  )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
    OUTPTR_PREPROCESS_COUNT(Buf, in->BufSize);
    OUTPTR_PREPROCESS(CountDone);
    OUTPTR_PREPROCESS(CountDone);
 
 
    err = UDIGetTrans(
    err = UDIGetTrans(
        local.Buf,
        local.Buf,
        in->BufSize,
        in->BufSize,
        local.CountDone
        local.CountDone
    );
    );
 
 
    OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
    OUTPTR_POSTPROCESS_COUNT(Buf, *(local.CountDone));
    OUTPTR_POSTPROCESS(CountDone);
    OUTPTR_POSTPROCESS(CountDone);
 
 
    return(err);
    return(err);
}
}
 
 
 
 
UDIError d386_UDITransMode (void _far * rm_stk_ptr, int stacksize)
UDIError d386_UDITransMode (void _far * rm_stk_ptr, int stacksize)
{
{
INCOMING_PARAMS(
INCOMING_PARAMS(
  UDIMode       *Mode;                  /* Out */
  UDIMode       *Mode;                  /* Out */
 )
 )
UDIError err;
UDIError err;
 
 
    OUTPTR_PREPROCESS(Mode);
    OUTPTR_PREPROCESS(Mode);
 
 
    err = UDITransMode(
    err = UDITransMode(
        local.Mode
        local.Mode
    );
    );
 
 
    OUTPTR_POSTPROCESS(Mode);
    OUTPTR_POSTPROCESS(Mode);
 
 
    return(err);
    return(err);
}
}
 
 
#endif
#endif
/*==================== End of DOS386 glue routines ====================================*/
/*==================== End of DOS386 glue routines ====================================*/
 
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.