📄 plsacc.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: Trap file for debugging PharLap DOS extended apps.
*
****************************************************************************/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <io.h>
#include <fcntl.h>
#include "pltypes.h"
#include "dilintf.h"
#include "hw386.h"
#include "pharlap.h"
#include "dilproto.h"
#include "trpimp.h"
#include "exedos.h"
#include "exeos2.h"
#include "exepe.h"
#include "madregs.h"
#include "x86cpu.h"
#include "misc7386.h"
extern bool GrabVects( void );
extern void ReleVects( void );
extern void GrabPrtScrn( void );
extern void RelePrtScrn( void );
extern bool SetPSP( USHORT );
extern short GetDS( void );
extern short GetCS( void );
extern void SetMSW(unsigned);
extern unsigned ExceptionText( unsigned, char * );
#ifdef DEBUG_TRAP
#define _DBG( x ) cputs x
#else
#define _DBG( x )
#endif
#define DBG_ERROR "System error: "
static char *DBErrors[] = {
"???",
"???",
"File error",
"Invalid protected mode address",
"???",
"???",
"???",
"???",
"???",
"???",
"???",
"???",
"Memory error",
"Unable to move segments at init time",
"Internal system error",
"No child program is present",
"???",
"Child program is already present",
"Invalid DOS-Extender Version number",
"???",
"???",
"Attempt to set segreg to an invalid value",
"Invalid SS:ESP value",
"Child's -NISTACK and/or -ISTKSIZE switches",
"Child's -MINIBUF switch not satisfied",
"Child's -CALLBUFS switch not satisfied",
"Bad parameter passed to function",
"Function not supported under DPMI",
"No active protected mode state",
"Child privilege level cannot be satisfied",
"Current DOS-X is bound, no good",
"DILIB loadable portion not yet loaded",
"Incorrect DILIB loadable portion version"
};
extern long _STACKTOP;
extern char _8087;
#pragma aux (metaware) _dil_global;
#pragma aux (metaware) _dx_config_inf;
bool FakeBreak;
bool AtEnd;
bool ReportedAlias;
char SavedByte;
short InitialSS;
short InitialCS;
static int SaveStdIn;
static int SaveStdOut;
static unsigned SaveMSW;
static unsigned_8 RealNPXType;
#define BUFF_SIZE 256
char UtilBuff[BUFF_SIZE];
static MSB Mach;
static SEL_REMAP SelBlk;
static bool HavePSP;
#define MAX_OBJECTS 128
static unsigned long ObjOffReloc[MAX_OBJECTS];
#define NIL_DOS_HANDLE ((short)0xFFFF)
#define DBE_BASE 1000
typedef struct watch {
addr48_ptr addr;
dword value;
dword linear;
short dregs;
short len;
} watch;
#define MAX_WP 32
watch WatchPoints[ MAX_WP ];
int WatchCount;
typedef struct {
long have_vmm;
long nconvpg;
long nbimpg;
long nextpg;
long extlim;
long aphyseg;
long alockpg;
long sysphyspg;
long nfreepg;
long beglinaddr;
long endlinaddr;
long secsincelastvmstat;
long pgfaults;
long pgswritten;
long pgsreclaimed;
long vmpages;
long pgfilesize;
long emspages;
long mincomvmem;
long maxpagefile;
long vmflags;
long reserved[4];
} memory_stats;
unsigned ReqGet_sys_config()
{
get_sys_config_ret *ret;
_DBG(("AccGetConfig\r\n"));
ret = GetOutPtr(0);
ret->sys.os = OS_PHARLAP;
ret->sys.osmajor = _osmajor;
ret->sys.osminor = _osminor;
ret->sys.cpu = X86CPUType();
ret->sys.huge_shift = 12;
if( HavePSP && !AtEnd ) {
if( Mach.msb_cr0 & MSW_EM ) {
ret->sys.fpu = X86_EMU;
} else {
ret->sys.fpu = RealNPXType;
}
} else {
ret->sys.fpu = RealNPXType;
}
ret->sys.mad = MAD_X86;
return( sizeof( *ret ) );
}
unsigned ReqMap_addr()
{
map_addr_req *acc;
map_addr_ret *ret;
unsigned object;
_DBG(("AccMapAddr\r\n"));
acc = GetInPtr(0);
ret = GetOutPtr(0);
object = acc->in_addr.segment;
switch( object ) {
case MAP_FLAT_DATA_SELECTOR:
object = 1;
ret->out_addr.segment = Mach.msb_ds;
break;
case MAP_FLAT_CODE_SELECTOR:
object = 1;
/* fall through */
default:
ret->out_addr.segment = Mach.msb_cs;
break;
}
ret->out_addr.offset = acc->in_addr.offset + ObjOffReloc[object-1];
ret->lo_bound = 0;
ret->hi_bound = ~(addr48_off)0;
return( sizeof( *ret ) );
}
static bool IsProtSeg( USHORT seg )
{
CD_DES desc;
if( dbg_rdsdes( seg, 1, &desc ) != 0 ) return( FALSE );
if( ( desc.arights & AR_CODE ) == AR_CODE ) return( TRUE );
if( ( desc.arights & AR_DATA ) == AR_DATA ) return( TRUE );
return( FALSE );
}
//OBSOLETE - use ReqMachine_data
unsigned ReqAddr_info()
{
addr_info_req *acc;
addr_info_ret *ret;
_DBG(("AccAddrInfo\r\n"));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->is_32 = IsProtSeg( acc->in_addr.segment );
return( sizeof( *ret ) );
}
unsigned ReqMachine_data()
{
machine_data_req *acc;
machine_data_ret *ret;
unsigned_8 *data;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
data = GetOutPtr( sizeof( *ret ) );
ret->cache_start = 0;
ret->cache_end = ~(addr_off)0;
*data = IsProtSeg( acc->addr.segment ) ? X86AC_BIG : 0;
return( sizeof( *ret ) + sizeof( *data ) );
}
static ULONG RealAddr( PTR386 *addr )
{
return( ( (long)addr->selector << 16 ) + ( addr->offset & 0xFFFF ) );
}
static int RunProgram()
{
MSB temp;
int rc;
int i;
dbg_rdmsb( &temp );
temp.msb_cs = Mach.msb_cs;
temp.msb_ds = Mach.msb_ds;
temp.msb_es = Mach.msb_es;
temp.msb_fs = Mach.msb_fs;
temp.msb_gs = Mach.msb_gs;
temp.msb_ss = Mach.msb_ss;
temp.msb_eax = Mach.msb_eax;
temp.msb_ebx = Mach.msb_ebx;
temp.msb_ecx = Mach.msb_ecx;
temp.msb_edx = Mach.msb_edx;
temp.msb_esi = Mach.msb_esi;
temp.msb_edi = Mach.msb_edi;
temp.msb_ebp = Mach.msb_ebp;
temp.msb_esp = Mach.msb_esp;
temp.msb_eip = Mach.msb_eip;
for( i = 0; i <= 7; ++i ) temp.msb_dreg[ i ] = Mach.msb_dreg[ i ];
temp.msb_eflags = Mach.msb_eflags;
dbg_wrmsb( &temp );
rc = dbg_go();
dbg_rdmsb( &Mach );
return( rc );
}
static int ReadMemory( PTR386 *addr, unsigned long req, void *buf )
{
if( IsProtSeg( addr->selector ) ) {
return( dbg_pread( addr, req, buf ) );
} else {
return( dbg_rread( RealAddr( addr ), req, buf ) );
}
}
static int WriteMemory( PTR386 *addr, unsigned long req, void *buf )
{
if( IsProtSeg( addr->selector ) ) {
return( dbg_pwrite( addr, req, buf ) );
} else {
return( dbg_rwrite( RealAddr( addr ), req, buf ) );
}
}
static unsigned short ReadWrite( rtn, addr, buff, requested )
int (*rtn)();
PTR386 *addr;
char *buff;
unsigned short requested;
{
int err;
unsigned short len;
err = rtn( addr, (unsigned long)requested, buff );
if( err == 0 ) {
addr->offset += requested;
return( requested );
}
len = requested;
while( len != 0 ) {
if( rtn( addr, 1UL, buff++ ) != 0 ) break;
--len;
addr->offset++;
}
return( requested - len );
}
unsigned ReqChecksum_mem()
{
unsigned short len;
unsigned short read;
PTR386 addr;
int i;
checksum_mem_req *acc;
checksum_mem_ret *ret;
_DBG(("AccChkSum\r\n"));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
len = acc->len;
addr.offset = acc->in_addr.offset;
addr.selector = acc->in_addr.segment;
ret->result = 0;
while( len >= BUFF_SIZE ) {
read = ReadWrite( ReadMemory, &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 = ReadWrite( ReadMemory, &addr, UtilBuff, len );
if( read == len ) {
for( i = 0; i < len; ++i ) {
ret->result += UtilBuff[ i ];
}
}
}
return( sizeof( *ret ) );
}
unsigned ReqRead_mem()
{
PTR386 addr;
read_mem_req *acc;
void *ret;
unsigned len;
_DBG(("ReadMem\r\n"));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
addr.offset = acc->mem_addr.offset;
addr.selector = acc->mem_addr.segment;
len = ReadWrite( ReadMemory, &addr, ret, acc->len );
return( len );
}
unsigned ReqWrite_mem()
{
PTR386 addr;
write_mem_req *acc;
write_mem_ret *ret;
_DBG(("WriteMem\r\n"));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
addr.offset = acc->mem_addr.offset;
addr.selector = acc->mem_addr.segment;
ret->len = ReadWrite( WriteMemory, &addr,
GetInPtr( sizeof(*acc) ),
GetTotalSize() - sizeof(*acc) );
return( sizeof( *ret ) );
}
unsigned ReqRead_io()
{
int err;
read_io_req *acc;
void *ret;
unsigned len;
_DBG(("ReadPort\r\n"));
acc = GetInPtr(0);
ret = GetOutPtr(0);
switch( acc->len ) {
case 1:
err = dbg_iport( acc->IO_offset, ret, 1 );
break;
case 2:
err = dbg_iport( acc->IO_offset, ret, 2 );
break;
case 4:
err = dbg_iport( acc->IO_offset, ret, 3 );
break;
default:
err = DBE_INVWID;
}
if( err != 0 ) {
len = 0;
} else {
len = acc->len;
}
return( len );
}
unsigned ReqWrite_io()
{
int err;
int len;
write_io_req *acc;
write_io_ret *ret;
void *data;
_DBG(("WritePort\r\n"));
acc = GetInPtr(0);
data = GetInPtr( sizeof( *acc ) );
len = GetTotalSize() - sizeof( *acc );
ret = GetOutPtr(0);
switch( len ) {
case 1:
err = dbg_oport( acc->IO_offset, data, 1 );
break;
case 2:
err = dbg_oport( acc->IO_offset, data, 2 );
break;
case 4:
err = dbg_oport( acc->IO_offset, data, 3 );
break;
default:
err = DBE_INVWID;
}
if( err != 0 ) {
ret->len = 0;
} else {
ret->len = len;
}
return( sizeof( *ret ) );
}
static void TaskFPExec( ULONG rtn, struct x86_fpu *regs )
{
long eax,eip,efl;
short cs,ds;
if( RealNPXType == X86_387 || RealNPXType == X86_287 || (Mach.msb_cr0 & MSW_EM) ) {
ds = Mach.msb_ds;
eax = Mach.msb_eax;
cs = Mach.msb_cs;
eip = Mach.msb_eip;
efl = Mach.msb_eflags;
Mach.msb_ds = GetDS();
Mach.msb_eax = (ULONG)regs;
Mach.msb_cs = GetCS();
Mach.msb_eip = rtn;
RunProgram();
Mach.msb_cs = cs;
Mach.msb_eip = eip;
Mach.msb_ds = ds;
Mach.msb_eax = eax;
Mach.msb_eflags = efl;
}
}
static void ReadCPU( struct x86_cpu *r )
{
r->eax = Mach.msb_eax;
r->ebx = Mach.msb_ebx;
r->ecx = Mach.msb_ecx;
r->edx = Mach.msb_edx;
r->esi = Mach.msb_esi;
r->edi = Mach.msb_edi;
r->esp = Mach.msb_esp;
r->ebp = Mach.msb_ebp;
r->eip = Mach.msb_eip;
r->ds = Mach.msb_ds;
r->cs = Mach.msb_cs;
r->es = Mach.msb_es;
r->ss = Mach.msb_ss;
r->fs = Mach.msb_fs;
r->gs = Mach.msb_gs;
r->efl = Mach.msb_eflags;
}
static void WriteCPU( struct x86_cpu *r )
{
Mach.msb_eax = r->eax;
Mach.msb_ebx = r->ebx;
Mach.msb_ecx = r->ecx;
Mach.msb_edx = r->edx;
Mach.msb_esi = r->esi;
Mach.msb_edi = r->edi;
Mach.msb_esp = r->esp;
Mach.msb_ebp = r->ebp;
Mach.msb_eip = r->eip;
Mach.msb_ds = r->ds;
Mach.msb_cs = r->cs;
Mach.msb_es = r->es;
Mach.msb_ss = r->ss;
Mach.msb_fs = r->fs;
Mach.msb_gs = r->gs;
Mach.msb_eflags = r->efl;
}
//OBSOLETE - use ReqRead_regs
unsigned ReqRead_cpu()
{
trap_cpu_regs *regs;
_DBG(("AccReadCPU\r\n"));
regs = GetOutPtr( 0 );
ReadCPU( (struct x86_cpu *)regs );
_DBG(("exit AccReadCPU\r\n"));
return( sizeof( *regs ) );
}
//OBSOLETE - use ReqRead_regs
unsigned ReqRead_fpu()
{
_DBG(("AccReadFPU\r\n"));
TaskFPExec( (ULONG)&Read387, GetOutPtr( 0 ) );
_DBG(("exit AccReadFPU\r\n"));
return( sizeof( trap_fpu_regs ) );
}
//OBSOLETE - use ReqWrite_regs
unsigned ReqWrite_cpu()
{
trap_cpu_regs *regs;
_DBG(("AccWriteCPU\r\n"));
regs = GetInPtr( sizeof( write_cpu_req ) );
WriteCPU( (struct x86_cpu *)regs );
return( 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -