📄 cwacc.c
字号:
/****************************************************************************
*
* 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: CauseWay trap file protected mode request handling.
*
****************************************************************************/
//#define DEBUG_TRAP
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "trpimp.h"
#include "trperr.h"
#include "madx86.h"
#include "dpmi.h"
#include "x86cpu.h"
#include "misc7386.h"
#ifdef DEBUG_TRAP
extern void dos_printf( const char *format, ... );
#define _DBG( ... ) dos_printf( __VA_ARGS__ )
#define _DBG1( ... ) dos_printf( __VA_ARGS__ )
#define _DBG2( ... ) dos_printf( __VA_ARGS__ )
#else
#define _DBG( ... )
#define _DBG1( ... )
#define _DBG2( ... )
#endif
/*static */unsigned (* const CoreRequests[])( void ) = {
NULL,// ReqConnect,
NULL,// ReqDisconnect,
NULL,// ReqSuspend,
NULL,// ReqResume,
NULL,// ReqGet_supplementary_service,
NULL,// ReqPerform_supplementary_service,
ReqGet_sys_config,
NULL,// ReqMap_addr,
ReqAddr_info, //obsolete
NULL,// ReqChecksum_mem,
NULL,// ReqRead_mem,
NULL,// ReqWrite_mem,
NULL,// ReqRead_io,
NULL,// ReqWrite_io,
NULL,// ReqRead_cpu, //obsolete
NULL,// ReqRead_fpu, //obsolete
NULL,// ReqWrite_cpu, //obsolete
NULL,// ReqWrite_fpu, //obsolete
NULL,// ReqProg_go,
NULL,// ReqProg_step,
NULL,// ReqProg_load,
NULL,// ReqProg_kill,
NULL,// ReqSet_watch,
NULL,// ReqClear_watch,
NULL,// ReqSet_break,
NULL,// ReqClear_break,
NULL,// ReqGet_next_alias,
NULL,// ReqSet_user_screen,
NULL,// ReqSet_debug_screen,
NULL,// ReqRead_user_keyboard,
NULL,// ReqGet_lib_name,
NULL,// ReqGet_err_text,
NULL,// ReqGet_message_text,
NULL,// ReqRedirect_stdin,
NULL,// ReqRedirect_stdout,
NULL,// ReqSplit_cmd,
NULL,// ReqRead_regs,
NULL,// ReqWrite_regs,
ReqMachine_data,
};
// Linear executable (LE/LX) object information
static unsigned NumObjects;
static struct {
unsigned_32 size;
unsigned_32 start;
} *ObjInfo;
unsigned_16 dos_getver( void );
#pragma aux dos_getver = \
"mov ah,30h" \
"int 21h" \
value [ax];
unsigned ReqGet_sys_config( void )
/********************************/
{
get_sys_config_ret *ret;
unsigned_16 dosver;
_DBG( "AccGetConfig\r\n" );
ret = GetOutPtr( 0 );
ret->sys.os = OS_RATIONAL; // Pretend we're DOS/4G
dosver = dos_getver();
ret->sys.osmajor = dosver >> 8;
ret->sys.osminor = dosver & 0xff;
ret->sys.cpu = X86CPUType();
ret->sys.huge_shift = 12;
ret->sys.fpu = NPXType(); //RealNPXType;
ret->sys.mad = MAD_X86;
_DBG( "os = %d, cpu=%d, fpu=%d, osmajor=%d, osminor=%d\r\n",
ret->sys.os, ret->sys.cpu, ret->sys.fpu,
ret->sys.osmajor, ret->sys.osminor );
return( sizeof( *ret ) );
}
unsigned ReqMap_addr( void )
/**************************/
{
unsigned_16 sel;
unsigned_32 off;
map_addr_req *acc;
map_addr_ret *ret;
unsigned i;
_DBG1( "AccMapAddr\r\n" );
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->lo_bound = 0;
ret->hi_bound = ~(addr48_off)0;
off = acc->in_addr.offset;
sel = acc->in_addr.segment;
switch( sel ) {
case MAP_FLAT_CODE_SELECTOR:
case MAP_FLAT_DATA_SELECTOR:
sel = 1;
off += ObjInfo[0].start;
for( i = 0; i < NumObjects; ++i ) {
if( ObjInfo[i].start <= off
&& (ObjInfo[i].start + ObjInfo[i].size) > off ) {
sel = i + 1;
off -= ObjInfo[i].start;
ret->lo_bound = ObjInfo[i].start - ObjInfo[0].start;
ret->hi_bound = ret->lo_bound + ObjInfo[i].size - 1;
break;
}
}
break;
}
// D32Relocate( &fp );
ret->out_addr.segment = sel;
ret->out_addr.offset = off;
return( sizeof( *ret ) );
}
extern unsigned long GetLAR( unsigned );
#pragma aux GetLAR = \
"movzx eax,ax" \
"lar eax,eax" \
parm [ax] value [eax];
//OBSOLETE - use ReqMachine_data
unsigned ReqAddr_info( void )
{
addr_info_req *acc;
addr_info_ret *ret;
_DBG( "AccAddrInfo\r\n" );
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->is_32 = 0;
// if( D32AddressCheck( acc->in_addr.segment, 0, 1, NULL ) ) {
if( GetLAR( acc->in_addr.segment ) & 0x400000 ) {
ret->is_32 = 1;
}
// }
return( sizeof( *ret ) );
}
unsigned ReqMachine_data( void )
{
machine_data_req *acc;
machine_data_ret *ret;
unsigned_8 *data;
_DBG( "AccMachineData\r\n" );
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
data = GetOutPtr( sizeof( *ret ) );
ret->cache_start = 0;
ret->cache_end = ~(addr_off)0;
*data = 0;
// if( D32AddressCheck( acc->addr.segment, 0, 1, NULL ) ) {
if( GetLAR( acc->addr.segment ) & 0x400000 ) {
*data = X86AC_BIG;
}
// }
_DBG( "address is %s\r\n", *data ? "32-bit" : "16-bit" );
return( sizeof( *ret ) + sizeof( *data ) );
}
#if 0
//#define DEBUG_TRAP
#include "misc7386.h"
TSF32 Proc;
char Break;
extern unsigned ExceptionText( unsigned, char * );
extern void InitRedirect(void);
bool FakeBreak;
unsigned NumObjects;
struct {
unsigned_32 size;
unsigned_32 start;
} *ObjInfo;
static unsigned_8 RealNPXType;
#define BUFF_SIZE 256
char UtilBuff[BUFF_SIZE];
#define NIL_DOS_HANDLE ((short)0xFFFF)
#define IsDPMI (_d16info.swmode == 0)
typedef struct watch {
addr48_ptr addr;
dword value;
dword linear;
short dregs;
unsigned short len;
dpmi_watch_handle handle;
dpmi_watch_handle handle2;
} watch;
#define MAX_WP 32
watch WatchPoints[ MAX_WP ];
int WatchCount;
static unsigned short ReadWrite( int (*r)(OFFSET32,SELECTOR,int,char far*,unsigned short), addr48_ptr *addr, byte far *data, unsigned short req ) {
unsigned short len;
_DBG("checking %4.4x:%8.8lx for 0x%x bytes -- ",
addr->segment, addr->offset, req );
if( D32AddressCheck( addr->segment, addr->offset, req, NULL ) &&
r( addr->offset, addr->segment, 0, data, req ) == 0 ) {
_DBG( "OK\n" );
addr->offset += req;
return( req );
}
_DBG( "Bad\n" );
len = 0;
while( req > 0 ) {
if( !D32AddressCheck( addr->segment, addr->offset, 1, NULL ) ) break;
if( r( addr->offset, addr->segment, 0, data, 1 ) != 0 ) break;
++addr->offset;
++data;
++len;
--req;
}
return( len );
}
static unsigned short ReadMemory( addr48_ptr *addr, byte far *data, unsigned short len )
{
return( ReadWrite( D32DebugRead, addr, data, len ) );
}
static unsigned short WriteMemory( addr48_ptr *addr, byte far *data, unsigned short len )
{
return( ReadWrite( D32DebugWrite, addr, data, len ) );
}
unsigned ReqChecksum_mem( void )
{
unsigned short len;
int i;
unsigned short read;
checksum_mem_req *acc;
checksum_mem_ret *ret;
_DBG1( "AccChkSum\n" );
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
len = acc->len;
ret->result = 0;
while( len >= BUFF_SIZE ) {
read = ReadMemory( (addr48_ptr *)&acc->in_addr, &UtilBuff, 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( (addr48_ptr *)&acc->in_addr, &UtilBuff, len );
if( read == len ) {
for( i = 0; i < len; ++i ) {
ret->result += UtilBuff[ i ];
}
}
}
return( sizeof( ret ) );
}
unsigned ReqRead_mem( void )
{
read_mem_req *acc;
void far *buff;
unsigned short len;
_DBG1( "ReadMem\n" );
acc = GetInPtr( 0 );
buff = GetOutPtr( 0 );
len = ReadMemory( (addr48_ptr *)&acc->mem_addr, buff, acc->len );
return( len );
}
unsigned ReqWrite_mem( void )
{
write_mem_req *acc;
write_mem_ret *ret;
_DBG1( "WriteMem\n" );
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->len = WriteMemory( (addr48_ptr *)&acc->mem_addr,
GetInPtr( sizeof(*acc) ),
GetTotalSize() - sizeof(*acc) );
return( sizeof( *ret ) );
}
unsigned ReqRead_io( void )
{
read_io_req *acc;
void *data;
acc = GetInPtr(0);
data = GetOutPtr(0);
if( acc->len == 1 ) {
*(byte *)data = In_b( acc->IO_offset );
} else if( acc->len == 2 ) {
*(word *)data = In_w( acc->IO_offset );
} else {
*(dword *)data = In_d( acc->IO_offset );
}
return( acc->len );
}
unsigned ReqWrite_io( void )
{
unsigned 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 ) );
}
static void ReadCPU( struct x86_cpu *r )
{
r->efl = Proc.eflags;
r->eax = Proc.eax;
r->ebx = Proc.ebx;
r->ecx = Proc.ecx;
r->edx = Proc.edx;
r->esi = Proc.esi;
r->edi = Proc.edi;
r->esp = Proc.esp;
r->ebp = Proc.ebp;
r->eip = Proc.eip;
r->ds = Proc.ds;
r->cs = Proc.cs;
r->es = Proc.es;
r->ss = Proc.ss;
r->fs = Proc.fs;
r->gs = Proc.gs;
}
static void WriteCPU( struct x86_cpu *r )
{
Proc.eflags = r->efl;
Proc.eax = r->eax;
Proc.ebx = r->ebx;
Proc.ecx = r->ecx;
Proc.edx = r->edx;
Proc.esi = r->esi;
Proc.edi = r->edi;
Proc.esp = r->esp;
Proc.ebp = r->ebp;
Proc.eip = r->eip;
Proc.ds = r->ds;
Proc.cs = r->cs;
Proc.es = r->es;
Proc.ss = r->ss;
Proc.fs = r->fs;
Proc.gs = r->gs;
}
static void ReadFPU( struct x86_fpu *r )
{
if( HAVE_EMU ) {
if( CheckWin386Debug() == WGOD_VERSION ) {
EMUSaveRestore( Proc.cs, r, 1 );
} else {
Read387( r );
}
} else if( RealNPXType != X86_NO ) {
if( _d16info.cpumod >= 3 ) {
Read387( r );
} else {
Read8087( r );
}
}
}
static void WriteFPU( struct x86_fpu *r )
{
if( HAVE_EMU ) {
if( CheckWin386Debug() == WGOD_VERSION ) {
EMUSaveRestore( Proc.cs, r, 0 );
} else {
Write387( r );
}
} else if( RealNPXType != X86_NO ) {
if( _d16info.cpumod >= 3 ) {
Write387( r );
} else {
Write8087( r );
}
}
}
//OBSOLETE - use ReqRead_regs
unsigned ReqRead_cpu( void )
{
trap_cpu_regs *regs;
regs = GetOutPtr( 0 );
ReadCPU( (struct x86_cpu *)regs );
return( sizeof( *regs ) );
}
//OBSOLETE - use ReqRead_regs
unsigned ReqRead_fpu( void )
{
trap_fpu_regs *regs;
regs = GetOutPtr( 0 );
ReadFPU( (struct x86_fpu *)regs );
return( sizeof( *regs ) );
}
//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_cpu( void )
{
trap_cpu_regs *regs;
regs = GetInPtr( sizeof( write_cpu_req ) );
WriteCPU( (struct x86_cpu *)regs );
return( 0 );
}
//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_fpu( void )
{
trap_fpu_regs *regs;
regs = GetInPtr( sizeof( write_fpu_req ) );
WriteFPU( (struct x86_fpu *)regs );
return( 0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -