⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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 real mode debugger access functions.
*
****************************************************************************/


//#define DEBUG_ME

#include <string.h>
#include <i86.h>
#include "tinyio.h"
#include "dbg386.h"
#include "drset.h"
#include "doshdl.h"
#include "exedos.h"
#include "exeos2.h"
#include "exephar.h"
#include "trperr.h"
#define ERR_CODES
#include "dosmsgs.h"
#undef ERR_CODES
#include "trpimp.h"
#include "ioports.h"
#include "winchk.h"
#include "madregs.h"
#include "x86cpu.h"
#include "misc7086.h"

typedef enum {
    EXE_UNKNOWN,
    EXE_DOS,                    /* DOS */
    EXE_OS2,                    /* OS/2 */
    EXE_PHARLAP_SIMPLE,         /* PharLap Simple */
    EXE_PHARLAP_EXTENDED_286,   /* PharLap Extended 286 */
    EXE_PHARLAP_EXTENDED_386,   /* PharLap Extended 386 (may be bound) */
    EXE_RATIONAL_386,           /* Rational DOS/4G app */
    EXE_LAST_TYPE
} EXE_TYPE;

#pragma aux MoveBytes =                                  \
/*  MoveBytes( fromseg, fromoff, toseg, tooff, len ); */ \
       " rep    movsb "                                  \
    parm    caller  [ ds ] [ si ] [ es ] [ di ] [ cx ]   \
    modify  [ si di ];

#pragma aux MyFlags = \
       " pushf  "     \
       " pop ax "     \
    value [ax];

extern void MoveBytes( short, short, short, short, short );
extern unsigned short MyCS( void );
extern unsigned short MyFlags( void );


typedef _Packed struct pblock {
    addr_seg    envstring;
    addr32_ptr  commandln;
    addr32_ptr  fcb01;
    addr32_ptr  fcb02;
    addr32_ptr  startsssp;
    addr32_ptr  startcsip;
} pblock;

#define CMD_OFFSET      0x80

//
// NOTE: if you change this structure, you must update DBGTRAP.ASM
//
typedef _Packed struct watch {
    addr32_ptr  addr;
    dword       value;
    dword       linear;
    short       dregs;
    short       len;
} watch;

#define MAX_WP  32
watch   WatchPoints[ MAX_WP ];
short   WatchCount;

typedef enum {
        TRAP_SKIP = -1,
        TRAP_NONE,
        TRAP_TRACE_POINT,
        TRAP_BREAK_POINT,
        TRAP_WATCH_POINT,
        TRAP_USER,
        TRAP_TERMINATE,
        TRAP_MACH_EXCEPTION,
        TRAP_OVL_CHANGE_LOAD,
        TRAP_OVL_CHANGE_RET
} trap_types;

/* user modifiable flags */
#define USR_FLAGS (FLG_C | FLG_P | FLG_A | FLG_Z | FLG_S | \
            FLG_I | FLG_D | FLG_O)

extern void             InitRedirect(void);
extern addr_seg         DbgPSP(void);
extern long             DOSLoadProg(char far *, pblock far *);
extern addr_seg         DOSTaskPSP(void);
extern void             EndUser(void);
extern unsigned_8       RunProg(trap_cpu_regs *, trap_cpu_regs *);
extern void             SetWatch386( unsigned, watch far * );
extern void             SetWatchPnt(unsigned, watch far *);
extern void             SetSingleStep(void);
extern void             SetSingle386(void);
extern void             SetDbgTask(void);
extern void             SetUsrTask(void);
extern void             InitVectors(void);
extern void             FiniVectors(void);
extern void             TrapTypeInit(void);
extern void             ClrIntVecs(void);
extern void             SetIntVecs(void);
extern void             DoRemInt(trap_cpu_regs *, unsigned);
extern char             Have87Emu(void);
extern void             Null87Emu( void );
extern void             Read87EmuState( void far * );
extern void             Write87EmuState( void far * );
extern tiny_ret_t       FindFilePath( char *, char *, char * );
extern unsigned         Redirect( bool );
extern unsigned         ExceptionText( unsigned, char * );
extern unsigned         StringToFullPath( char * );
extern int              far NoOvlsHdlr( int, void * );
extern bool             CheckOvl( addr32_ptr );
extern int              NullOvlHdlr(void);


extern word             far SegmentChain;

static tiny_handle_t    EXEhandle;
static tiny_ftime_t     EXETime;
static tiny_fdate_t     EXEDate;
#define ReadEXE( x )    TinyRead( EXEhandle, &x, sizeof(x) )
#define WriteEXE( x )   TinyWrite( EXEhandle, &x, sizeof(x) )
#define SeekEXEset( x ) TinySeek( EXEhandle, x, TIO_SEEK_START )
static dword            NEOffset;
static word             NumSegments;
static dword            SegTable;
static dword            StartByte;
static byte             SavedByte;
static addr48_ptr       BadBreak;
static bool             GotABadBreak;
static int              ExceptNum;

static unsigned_8       RealNPXType;
static unsigned_8       CPUType;

trap_cpu_regs   TaskRegs;
char            DOS_major;
char            DOS_minor;
bool            BoundAppLoading;
bool            IsBreak[4];

struct {
    unsigned    Is386       : 1;
    unsigned    IsMMX       : 1;
    unsigned    IsXMM       : 1;
    unsigned    DRsOn       : 1;
    unsigned    com_file    : 1;
    unsigned    NoOvlMgr    : 1;
    unsigned    BoundApp    : 1;
} Flags;

#ifdef DEBUG_ME
int out( char * str )
{
    char *p;

    p = str;
    while( *p ) ++p;
    TinyWrite( 1, str, p - str );
    return 0;
}

#define out0 out

static char hexbuff[80];

char * hex( unsigned long num )
{
    char *p;

    p = &hexbuff[79];
    *p = 0;
    if( num == 0 ) {
      *--p = '0';
      return( p );
    }
    while( num != 0 ) {
        *--p = "0123456789abcdef"[ num & 15 ];
        num >>= 4;
    }
    return( p );

}
#else
    #define out( s )
    #define out0( s ) 0
    #define hex( n )
#endif

unsigned ReqGet_sys_config( void )
{
    get_sys_config_ret  *ret;

    ret = GetOutPtr(0);
    ret->sys.os = OS_DOS;
    ret->sys.osmajor = DOS_major;
    ret->sys.osminor = DOS_minor;
    ret->sys.cpu = CPUType;
    if( Have87Emu() ) {
        ret->sys.fpu = X86_EMU;
    } else if( RealNPXType != X86_NO ) {
        if( CPUType < X86_486 ) {
            ret->sys.fpu = RealNPXType;
        } else {
            ret->sys.fpu = CPUType & X86_CPU_MASK;
        }
    } else {
        ret->sys.fpu = X86_NO;
    }
    ret->sys.huge_shift = 12;
    ret->sys.mad = MAD_X86;
    return( sizeof( *ret ) );
}


unsigned ReqMap_addr( void )
{
    word            seg;
    int             count;
    word            far *segment;
    map_addr_req    *acc;
    map_addr_ret    *ret;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    seg = acc->in_addr.segment;
    switch( seg ) {
    case MAP_FLAT_CODE_SELECTOR:
    case MAP_FLAT_DATA_SELECTOR:
        seg = 0;
        break;
    }
    if( Flags.BoundApp ) {
        count = NumSegments - seg;
        segment = MK_FP( SegmentChain, 14 );
        while( count != 0 ) {
            segment = MK_FP( *segment, 14 );
            --count;
        }
        ret->out_addr.segment = FP_SEG( segment ) + 1;
    } else {
        ret->out_addr.segment = DOSTaskPSP() + seg;
        if( !Flags.com_file ) ret->out_addr.segment += 0x10;
    }
    ret->out_addr.offset = acc->in_addr.offset;
    ret->lo_bound = 0;
    ret->hi_bound = ~(addr48_off)0;
    return( sizeof( *ret ) );
}

//OBSOLETE - use ReqMachine_data
unsigned ReqAddr_info( void )
{
    addr_info_ret       *ret;

    ret = GetOutPtr( 0 );
    ret->is_32 = FALSE;
    return( sizeof( *ret ) );
}

unsigned ReqMachine_data( void )
{
    machine_data_ret    *ret;
    unsigned_8          *data;

    ret = GetOutPtr( 0 );
    data = GetOutPtr( sizeof( *ret ) );
    ret->cache_start = 0;
    ret->cache_end = ~(addr_off)0;
    *data = 0;
    return( sizeof( *ret ) + sizeof( *data ) );
}

unsigned ReqChecksum_mem( void )
{
    unsigned_8          far *ptr;
    unsigned long       sum = 0;
    unsigned            len;
    checksum_mem_req    *acc;
    checksum_mem_ret    *ret;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    ptr = MK_FP( acc->in_addr.segment, acc->in_addr.offset );
    for( len = acc->len; len != 0; --len ) {
        sum += *ptr++;
    }
    ret->result = sum;
    return( sizeof( *ret ) );
}


static bool IsInterrupt( addr48_ptr addr, unsigned length )
{
    unsigned long start, end;

    start = ((unsigned long)addr.segment << 4) + addr.offset;
    end = start + length;
    return( start < 0x400 || end < 0x400 );
}


unsigned ReqRead_mem( void )
{
    bool          int_tbl;
    read_mem_req  *acc;
    void          *data;
    unsigned      len;

    acc = GetInPtr(0);
    data = GetOutPtr( 0 );
    acc->mem_addr.offset &= 0xffff;
    int_tbl = IsInterrupt( acc->mem_addr, acc->len );
    if( int_tbl )
        SetIntVecs();
    len = acc->len;
    if( ( acc->mem_addr.offset + len ) > 0xffff ) {
        len = 0x10000 - acc->mem_addr.offset;
    }
    MoveBytes( acc->mem_addr.segment, acc->mem_addr.offset,
               FP_SEG( data ), FP_OFF( data ), len );
    if( int_tbl )
        ClrIntVecs();
    return( len );
}


unsigned ReqWrite_mem( void )
{
    bool          int_tbl;
    write_mem_req *acc;
    write_mem_ret *ret;
    unsigned      len;
    void          *data;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    data = GetInPtr(sizeof(*acc));
    len = GetTotalSize() - sizeof(*acc);

    acc->mem_addr.offset &= 0xffff;
    int_tbl = IsInterrupt( acc->mem_addr, len );
    if( int_tbl )
        SetIntVecs();
    if( ( acc->mem_addr.offset + len ) > 0xffff ) {
        len = 0x10000 - acc->mem_addr.offset;
    }
    MoveBytes( FP_SEG( data ), FP_OFF( data ),
               acc->mem_addr.segment, acc->mem_addr.offset, len );
    if( int_tbl )
        ClrIntVecs();
    ret->len = len;
    return( sizeof( *ret ) );
}


unsigned ReqRead_io( void )
{
    read_io_req *acc;
    void        *data;
    unsigned    len;

    acc = GetInPtr(0);
    data = GetOutPtr(0);
    if( acc->len == 1 ) {
       *( (byte far *)data ) = In_b( acc->IO_offset );
       len = 1;
    } else if( acc->len == 2 ) {
       *( (word far *)data ) = In_w( acc->IO_offset );
       len = 2;
    } else if( Flags.Is386 ) {
       *( (dword far *)data ) = In_d( acc->IO_offset );
       len = 4;
    } else {
       len = 0;
    }
    return( len );
}


unsigned ReqWrite_io( void )
{
    write_io_req        *acc;
    write_io_ret        *ret;
    void                *data;
    unsigned            len;

    acc = GetInPtr(0);
    data = GetInPtr( sizeof( *acc ) );
    len = GetTotalSize() - sizeof( *acc );
    ret = GetOutPtr(0);
    if( len == 1 ) {
        Out_b( acc->IO_offset, *( (byte far *)data ) );
        ret->len = 1;
    } else if( len == 2 ) {
        Out_w( acc->IO_offset, *( (word far *)data ) );
        ret->len = 2;
    } else if ( Flags.Is386 ) {
        Out_d( acc->IO_offset, *( (dword far *)data ) );
        ret->len = 4;
    } else {
        ret->len = 0;
    }
    return( sizeof( *ret ) );
}

//OBSOLETE - use ReqRead_regs
unsigned ReqRead_cpu( void )
{
    void          *regs;
    read_cpu_ret  *ret;

    ret = GetOutPtr( 0 );
    regs = GetOutPtr( sizeof( *ret ) );
    ret->cpu = TaskRegs;
    return( sizeof( *ret ) );
}

//OBSOLETE - use ReqRead_regs
unsigned ReqRead_fpu( void )
{
    void    far *regs;

    regs = GetOutPtr(0);
    if( Have87Emu() ) {
        Read87EmuState( regs );
    } else if( RealNPXType != X86_NO ) {
        Read8087( regs );
    } else {
        return( 0 );
    }
    return( sizeof( trap_fpu_regs ) );
}

//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_cpu( void )
{
    trap_cpu_regs *regs;

    regs = GetInPtr(sizeof(write_cpu_req));
    TaskRegs = *regs;
    return( 0 );
}

//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_fpu( void )
{
    void    far *regs;

    regs = GetInPtr(sizeof(write_fpu_req));
    if( Have87Emu() ) {
        Write87EmuState( regs );
    } else if( RealNPXType != X86_NO ) {
        Write8087( regs );
    }
    return( 0 );
}

unsigned ReqRead_regs( void )
{
    mad_registers       *mr;

    mr = GetOutPtr(0);
    mr->x86.cpu = *(struct x86_cpu *)&TaskRegs;
    if( Have87Emu() ) {
        Read87EmuState( &mr->x86.fpu );
    } else if( RealNPXType != X86_NO ) {
        Read8087( &mr->x86.fpu );
    } else {
        memset( &mr->x86.fpu, 0, sizeof( mr->x86.fpu ) );
    }
    return( sizeof( mr->x86 ) );
}

unsigned ReqWrite_regs( void )
{
    mad_registers       *mr;

    mr = GetInPtr(sizeof(write_regs_req));
    *(struct x86_cpu *)&TaskRegs = mr->x86.cpu;
    if( Have87Emu() ) {
        Write87EmuState( &mr->x86.fpu );
    } else if( RealNPXType != X86_NO ) {
        Write8087( &mr->x86.fpu );
    }
    return( 0 );
}

static EXE_TYPE CheckEXEType( char *name )
{
    tiny_ret_t            rc;
    union {
        tiny_ret_t        rc;
        tiny_file_stamp_t stamp;
    } exe_time;
    word                  value;
    byte                  breakpt;
    static dos_exe_header head;
    static os2_exe_header os2_head;

    Flags.com_file = FALSE;
    EXEhandle = 0;
    rc = TinyOpen( name, TIO_READ_WRITE );
    if( TINY_ERROR( rc ) )
        return( EXE_UNKNOWN );
    EXEhandle = rc;
    exe_time.rc = TinyGetFileStamp( EXEhandle );
    EXETime = exe_time.stamp.time;
    EXEDate = exe_time.stamp.date;
    if( TINY_ERROR( ReadEXE( head ) ) )
        return( EXE_UNKNOWN );    /* MZ Signature */
    switch( head.signature ) {
    case SIMPLE_SIGNATURE: // mp
    case REX_SIGNATURE: // mq

⌨️ 快捷键说明

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