adsacc.c

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

C
989
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <io.h>
#include <dos.h>
#include <fcntl.h>
#include <stdarg.h>

#include "tinyio.h"
#include "trpimp.h"
#include "packet.h"
#include "dbg386.h"
#include "ioports.h"
#include "adslib.h"
#include "doshdl.h"
#include "madregs.h"
#include "x86cpu.h"
#include "misc7386.h"

trap_cpu_regs   Regs;
int             IntNum;
char            Break;

extern void DumpDbgRegs(void);


extern  void            GrabVects(void);
extern  void            ReleVects(void);
extern  dword           GetDS(void);
extern  dword           GetCS(void);
extern  dword           GetSS(void);
extern  dword           GetFL(void);
extern  void            DoRunProg(void);
extern  word            DoMapSeg(word);
extern  int             DoReadMem(word,dword,char*);
extern  int             DoWriteMem(word,dword,char*);
extern  dword           GetLinear(word,dword);
extern  dword           SegLimit(word);
extern  bool            WriteOk(word);
extern  unsigned        ExceptionText( unsigned, char * );

bool                    FakeBreak;
bool                    AtEnd;
bool                    DoneAutoCAD;

static unsigned_8       RealNPXType;
static int              SaveStdIn;
static int              SaveStdOut;
#define BUFF_SIZE       256
char                    UtilBuff[BUFF_SIZE];
#define ADSSTACK_SIZE      4096
char                    ADSStack[ADSSTACK_SIZE];

typedef struct watch {
    addr48_ptr  addr;
    dword       value;
    dword       linear;
    short       dregs;
    short       len;
} watch;

#define MAX_WP  8
watch   WatchPoints[ MAX_WP ];
int     WatchCount;

#define _DBG3( x ) // MyOut x
#define _DBG2( x ) // MyOut x
#define _DBG1( x ) // MyOut x
#define _DBG0( x ) // MyOut x
#define _DBG( x )  // MyOut x

struct {
        dword   cr0;
        dword   dr0;
        dword   dr1;
        dword   dr2;
        dword   dr3;
        dword   res1;
        dword   res2;
        dword   dr6;
        dword   dr7;
        dword   res3;
        dword   res4;
        dword   res5;
} SysRegs;

extern void GetSysRegs( void * );
extern void SetSysRegs( void * );

#if 0
/*
 * Debugging output code for ADS
 */

int _cnt;
static int _line=0;

extern void InitMeg1();
char far *GetScreenPointer( void )
{
    extern      short           Meg1;
    InitMeg1();
    return( MK_FP( Meg1, 0xB0000 ) );
}

void MyClearScreen()
{
    int i;

    char far *scrn=GetScreenPointer();

    for( i=0;i<80*25;i++ ) {
        scrn[i*2] = ' ';
        scrn[i*2+1] = 7;
    }
}

void RawOut( char *str )
{
    int         len,i;
    char        far*scr;
    char        far*scrn=GetScreenPointer();

    len = strlen( str );
    scr = &scrn[_line*80*2];
    for( i=0;i<len;i++ ) {
        scr[i*2] = str[i];
        scr[i*2+1] = 7;
    }
    for( i=len;i<80;i++ ) {
        scr[i*2] = ' ';
        scr[i*2+1] = 7;
    }
    _line++;
    if( _line > 24 ) _line = 0;

    scr = &scrn[_line*80*2];
    for( i=0;i<80;i++ ) {
        scr[i*2] = ' ';
        scr[i*2+1] = 7;
    }
}

void MyOut( char *str, ... )
{
    va_list     al;
    char        tmpbuff[128];

    sprintf( tmpbuff,"%03d) ",++_cnt );
    va_start( al, str );
    vsprintf( &tmpbuff[5],str, al );

    RawOut( tmpbuff );
}

#endif

static  word    LookUp( word sdtseg, word seg, word global )
{
    dword       sdtoff;
    dword       sdtlim;
    dword       linear;
    word        otherseg;

    sdtlim = SegLimit( sdtseg );
    linear = GetLinear( seg, 0 );
    for( sdtoff = 0; sdtoff < sdtlim; sdtoff += 8 ) {
        if( sdtoff == ( seg & 0xfff8 ) ) continue;
        otherseg = sdtoff + ( global ? 0 : 4 );
        if( !WriteOk( otherseg ) ) continue;
        if( GetLinear( otherseg, 0 ) != linear ) continue;
                                                                          _DBG3(("lookup %4.4x", otherseg));
        return( otherseg );
    }
    return( 0 );
}


word    AltSegment( word seg )
{
    word        otherseg;

    otherseg = LookUp( 0x30, seg, 0 );  /* try LDT */
    if( otherseg != 0 ) return( otherseg );
    otherseg = LookUp( 0x38, seg, 1 );  /* try GDT */
    if( otherseg != 0 ) return( otherseg );
    return( seg );
}

static int ReadWrite( int (*r)(word,dword,char*), addr48_ptr *addr, byte *data, int req ) {

    int         len;
    word        segment;
    dword       offset;

    offset = addr->offset;
    segment = addr->segment;
                                                                          _DBG2(("Read Write %4.4x:%8.8lx",segment,offset));
    if( SegLimit( segment ) >= offset + req - 1 ) {
                                                                          _DBG2(("Read Write Ok for %d", req));
        if( !r( segment, offset, data ) ) {
            segment = AltSegment( segment );
        }
        if( SegLimit( segment ) < offset + req - 1 ) {
                                                                          _DBG3(("Gosh, we're in trouble dudes"));
            if( SegLimit( segment ) == 0 ) {
                                                                          _DBG3(("Gosh, we're in SERIOUS trouble dudes"));
            }
        } else {
            len = req;
            while( --len >= 0 ) {
                if( !r( segment, offset++, data++ ) ) {
                                                                          _DBG3(("failed for %4.4x:%8.8lx", segment, offset-1));
                }
            }
                                                                          _DBG2(("Read Write Done"));
            return( req );
        }
    }
    len = 0;
                                                                          _DBG2(("Read Write One byte at a time for %d", req));
    while( --req >= 0 ) {
        if( SegLimit( segment ) < offset ) break;
        if( !r( segment, offset, data ) ) {
            segment = AltSegment( segment );
        }
        if( !r( segment, offset++, data++ ) ) {
                                                                          _DBG3(("failed for %4.4x:%8.8lx", segment, offset-1));
        }
        ++len;
    }
                                                                          _DBG2(("Read Write Done"));
    return( len );
}


static int ReadMemory( addr48_ptr *addr, byte *data, int len )
{
    return( ReadWrite( DoReadMem, addr, data, len ) );
}

static int WriteMemory( addr48_ptr *addr, byte *data, int len )
{
    if( addr->segment == Regs.CS ) addr->segment = Regs.DS; // hack, ack
    return( ReadWrite( DoWriteMem, addr, data, len ) );
}

unsigned ReqGet_sys_config()
{
    get_sys_config_ret  *ret;

                                                                          _DBG1(( "AccGetConfig" ));
    ret = GetOutPtr(0);
    ret->sys.os = OS_AUTOCAD;
    ret->sys.osmajor = _osmajor;
    ret->sys.osminor = _osminor;
    ret->sys.cpu = X86CPUType();
    ret->sys.huge_shift = 12;
    ret->sys.fpu = RealNPXType;
    ret->sys.mad = MAD_X86;
    return( sizeof( *ret ) );
}


unsigned ReqMap_addr()
{
    map_addr_req        *acc;
    map_addr_ret        *ret;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    if( acc->in_addr.segment == MAP_FLAT_DATA_SELECTOR ) {
        ret->out_addr.segment = Regs.DS;
    } else {
        ret->out_addr.segment = Regs.CS;
    }
    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()
{
    addr_info_ret       *ret;

                                                                          _DBG1(( "AccAddrInfo" ));
    ret = GetOutPtr( 0 );
    ret->is_32 = 1;
    return( sizeof( *ret ) );
}

unsigned ReqMachine_data()
{
    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 = X86AC_BIG;
    return( sizeof( *ret ) + sizeof( *data ) );
}


unsigned ReqChecksum_mem()
{
    unsigned       len;
    int            i;
    int            read;
    checksum_mem_req    *acc;
    checksum_mem_ret    *ret;

                                                                          _DBG1(( "AccChkSum" ));
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    len = acc->len;
    ret->result = 0;
    while( len >= BUFF_SIZE ) {
        read = ReadMemory( &acc->in_addr, (byte *)&UtilBuff, BUFF_SIZE );
        acc->in_addr.offset += BUFF_SIZE;
        for( i = 0; i < read; ++i ) {
            ret->result += UtilBuff[ i ];
        }
        if( read != BUFF_SIZE ) return( sizeof( *ret ) );
        len -= BUFF_SIZE;
    }
    if( len != 0 ) {
        read = ReadMemory( &acc->in_addr, (byte *)&UtilBuff, len );
        if( read == len ) {
            for( i = 0; i < len; ++i ) {
                ret->result += UtilBuff[ i ];
            }
        }
    }
    return( sizeof( *ret ) );
}


unsigned ReqRead_mem()
{
    read_mem_req        *acc;
    void                *ret;
    unsigned            len;
                                                                          _DBG1(( "ReadMem" ));
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    len = ReadMemory( &acc->mem_addr, ret, acc->len );
    return( len );
}

unsigned ReqWrite_mem()
{
    write_mem_req       *acc;
    write_mem_ret       *ret;
                                                                          _DBG1(( "WriteMem" ));
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->len = WriteMemory( &acc->mem_addr, GetInPtr( sizeof(*acc) ),
                            GetTotalSize() - sizeof(*acc) );
    return( sizeof( *ret ) );
}

unsigned ReqRead_io()
{
    read_io_req *acc;
    void        *ret;

    acc = GetInPtr(0);
    ret = GetOutPtr(0);
    if( acc->len == 1 ) {
        *( (byte *)ret ) = In_b( acc->IO_offset );
    } else if( acc->len == 2 ) {
        *( (word *)ret ) = In_w( acc->IO_offset );
    } else {
        *( (dword *)ret ) = In_d( acc->IO_offset );
    }
    return( acc->len );
}


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

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

//OBSOLETE - use ReqRead_regs
unsigned ReqRead_cpu()
{
    trap_cpu_regs       *regs;

    regs = GetOutPtr( 0 );
    *regs = Regs;
    return( sizeof( *regs ) );
}

//OBSOLETE - use ReqRead_regs
unsigned ReqRead_fpu()
{
    Read387( (trap_fpu_regs *)GetOutPtr( 0 ) );
    return( sizeof( trap_fpu_regs ) );
}

unsigned ReqRead_regs( void )
{
    mad_registers       *mr;

    mr = GetOutPtr(0);
    mr->x86.cpu = *(struct x86_cpu *)&Regs;
    Read387( &mr->x86.fpu );
    return( sizeof( mr->x86 ) );
}

//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_cpu()
{
    Regs = *( trap_cpu_regs *)GetInPtr( sizeof( write_cpu_req ) );
    return( 0 );
}

//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_fpu()
{
    Write387( (trap_fpu_regs *)GetInPtr( sizeof( write_fpu_req ) ) );
    return( 0 );
}

unsigned ReqWrite_regs( void )
{
    mad_registers       *mr;

    mr = GetInPtr(sizeof(write_regs_req));
    *(struct x86_cpu *)&Regs = mr->x86.cpu;
    Write387( &mr->x86.fpu );
    return( 0 );
}

#pragma aux StackCheck "__STK";

void StackCheck()
{
}

⌨️ 快捷键说明

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