dosxlink.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 555 行 · 第 1/2 页

C
555
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  DOS protected mode "remote link" to real mode.
*
****************************************************************************/


#include <setjmp.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "packet.h"
#include "trperr.h"

#if defined( ACAD )
    #undef PHARLAP /* just in case */
#endif

#ifdef SERVER

    #define _DBG( s )
    #define _DBG_ExitFunc( s )

    #ifdef PHARLAP
        #include "pharlap.h"
        #include "dxproto.h"
    #endif

    extern long         GetDosLong( long linear_addr );
    extern char         GetDosByte( long linear_addr );
    extern void         PutDosByte( long linear_addr, char );
    extern void         PutDosLong( long linear_addr, long );
    extern void         CallRealMode( long dos_addr );
    long                RMProcAddr;
    long                RMBuffPtr;
    long                RMBuffLen;
    char                XVersion;
    short               Meg1;

#else

    #include "tinyio.h"
    #include "trapdbg.h"
    #include <i86.h>

    extern unsigned short MyCS( void );

    #pragma aux MyCS   = 0x8c 0xc8 value [ ax ];

    #define MK_LINEAR( p )    ( ( (long)FP_SEG( (void far *)(p) ) << 4 ) + FP_OFF( (void far *)(p) ) )

    char                Server;
    jmp_buf             RealModeState;
    jmp_buf             ProtModeState;
    struct {
        long            ptr;
        long            len;
    }                   Buff;
    char                BackFromFork;
    short               OldPSP;
    char                BeenToProtMode;

    extern short        DbgPSP( void );
    extern short        GetPSP( void );
    extern void         SetPSP( short );
    extern int          _fork(char *,char *);

#endif



unsigned RemoteGet( char *rec, unsigned len )
{
    unsigned received;
#ifdef SERVER
    long buff;

    _DBG(("Remote Get Calling real mode - %8.8lx %8.8lx\n", RMProcAddr, RMBuffPtr));
    CallRealMode( RMProcAddr );
    _DBG(("Remote Get Back from real mode\n"));
    buff = GetDosLong( RMBuffPtr );
    received = GetDosLong( RMBuffLen );
    len = received;
    _DBG(("Remote Geting %d bytes\n",len));
    while( len != 0 ) {
        *rec = GetDosByte( buff );
        ++buff;
        ++rec;
        --len;
    }
    _DBG(("Remote Get Done\n"));
#else
    _DBG_EnterFunc( "RemoteGet()" );
    len = len;
    Buff.ptr = MK_LINEAR( rec );
    BackToProtMode();
    received = Buff.len;
    _DBG_DumpBytes( rec, received );
    _DBG_ExitFunc( "RemoteGet()" );
#endif
    return( received );
}

unsigned RemotePut( char *snd, unsigned len )
{
#ifdef SERVER
    long buff;

    _DBG(("Remote Put - %8.8lx %8.8lx\n", RMProcAddr, RMBuffPtr));
    PutDosLong( RMBuffLen, len );
    _DBG(("Remote Put %d bytes\n",len));
    buff = GetDosLong( RMBuffPtr );
    while( len != 0 ) {
        PutDosByte( buff, *snd );
        ++buff;
        ++snd;
        --len;
    }
    _DBG(("Remote Put Calling real mode\n"));
    CallRealMode( RMProcAddr );
    _DBG(("Remote Put Back from real mode\n"));
#else
    _DBG_EnterFunc( "RemotePut()" );
    _DBG_DumpBytes( snd, len );
    Buff.len = len;
    Buff.ptr = MK_LINEAR( snd );
    BackToProtMode();
    _DBG_ExitFunc( "RemotePut()" );
#endif
    return( len );
}

#ifndef SERVER
void BackToProtMode( void )
{
    if( setjmp( RealModeState ) == 0 ) {
        _DBG_Writeln( "ENTERING PROTECTED MODE" );
        longjmp( ProtModeState, 0 );
    }
    _DBG_Writeln( "RETURNED FROM PROTECTED MODE" );
}


void far BackFromProtMode( void )
{
    BeenToProtMode = 1;
    if( setjmp( ProtModeState ) == 0 ) {
        OldPSP = GetPSP();
        SetPSP( DbgPSP() );
        longjmp( RealModeState, 0 );
    }
    SetPSP( OldPSP );
}
#endif

char RemoteConnect( void )
{
    return( 1 );
}

void RemoteDisco( void )
{
}


#ifndef SERVER
char *CopyStr( char *src, char *dst )
{
    while( *dst = *src ) {
        dst++;
        src++;
    }
    return( dst );
}

static char *FindEnv( char *name )
{
    char        far *env;
    unsigned    len;

    len = strlen( name );
    env = MK_FP( *((unsigned far *)MK_FP( DbgPSP(), 0x2c )), 0 );
    while( *env ) {
        if( memcmp( env, name, len ) == 0 ) {
            return( env + len );
        }
        while( *env ) ++env;
        ++env;
    }
    return( NULL );
}

static char *SearchPath( char far *env, char *file, char *buff, char **pendname )
{
    char        *endname;
    char        *name;
    tiny_ret_t  rc;
    char        save[20];
    unsigned    len;
    char        *ptr;

    if( env == NULL ) {
        CopyStr( ";", buff );
    } else {
        CopyStr( ";", CopyStr( env, CopyStr( ".;", buff ) ) );
    }
    name = buff;
    len = strlen( file );
    while( *name ) {
        endname = name;
        while( *endname != ';' ) ++endname;
        memcpy( save, endname, len + 2 );
        ptr = endname;
        if( name != ptr && ptr[-1]!=':' && ptr[-1]!='/' && ptr[-1]!='\\' ) {
            *ptr++ = '\\';
        }
        memcpy( ptr, file, len + 1 );
        rc = TinyOpen( name, 0 );
        if( rc > 0 ) {
            TinyClose( (tiny_handle_t)rc );
            break;
        }
        memcpy( endname, save, len + 2 );
        name = endname + 1;
    }
    *pendname = endname;
    return( name );
}

#if defined(ACAD)
    #define NAME        "ACAD.EXE"
    #define HELPNAME    ""
#elif defined(PHARLAP)
    #define NAME        "TNT.EXE"
    #define OTHER_NAMES "RUN386.EXE\0"
    #define HELPNAME    "PLSHELP.EXP"
    #define HELPNAME_DS "PEDHELP.EXP"
    #define HELPNAME_NS "PENHELP.EXP"   /* not supported yet */
#elif defined(DOS4G)
    #define NAME        "DOS4GW.EXE"
    #define OTHER_NAMES "4GWPRO.EXE\0DOS4G.EXE\0DOS4GX.EXE\0"
    #define HELPNAME    "RSIHELP.EXP"
#elif defined(CAUSEWAY)
    #define NAME        "CWSTUB.EXE"
    #define OTHER_NAMES "\0"
    #define HELPNAME    "CWHELP.EXE"
#else
    #error Extender and helper names not defined
#endif

#ifndef OTHER_NAMES
    #define OTHER_NAMES
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?