adsacc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 989 行 · 第 1/2 页
C
989 行
#pragma aux BreakPoint = 0xCC;
extern void BreakPoint( void );
void ADSLoop()
{
short scode = RSRSLT; /* Normal result code (default) */
int stat;
for ( ;; ) { /* Request/Result loop */
// _DBG0(("ADS Loop"));
if ((stat = ads_link(scode)) < 0) {
cputs( "ADSHELP: bad status from ads_link()\r\n");
exit(1);
}
scode = RSRSLT; /* Reset result code */
switch (stat) {
case RQSUBR: /* Handle external function requests */
scode = RSERR;
break;
case RQXUNLD: /* Handle external function requests */
DoneAutoCAD = TRUE;
AtEnd = TRUE;
BreakPoint(); /* you figure it out */
break;
}
}
}
unsigned ReqProg_load()
{
prog_load_ret *ret;
_DBG(("We're in AccLoadProg"));
GetSysRegs( &SysRegs );
ret = GetOutPtr( 0 );
ret->err = 0;
ret->flags = LD_FLAG_IS_32 | LD_FLAG_IS_PROT | LD_FLAG_IS_STARTED | LD_FLAG_DISPLAY_DAMAGED;
ret->task_id = 4;
ret->mod_handle = 0;
Regs.DS = Regs.ES = Regs.FS = Regs.GS = GetDS();
Regs.SS = GetSS();
Regs.ESP = (dword)ADSStack + ADSSTACK_SIZE - sizeof( dword );
Regs.CS = GetCS();
Regs.EIP = (dword)&ADSLoop;
Regs.EFL = GetFL();
Regs.EAX = Regs.EBX = Regs.ECX = Regs.EDX = Regs.ESI = 0;
Regs.EDI = Regs.EBP = 0;
IntNum = -1;
_DBG(("We're back from AccLoadProg"));
return( sizeof( *ret ) );
}
static void MyRunProg()
{
_DBG0(( "RunProg - Regs" ));
DumpRegs( &Regs );
_DBG0(( "RunProg - dbgregs" ));
SetSysRegs( &SysRegs );
DoRunProg();
GetSysRegs( &SysRegs );
_DBG0(( "AfterRunProg (%d) - Regs", IntNum ));
DumpRegs( &Regs );
_DBG0(( "AfterRunProg - dbgregs" ));
DumpDbgRegs();
}
unsigned ReqProg_kill()
{
prog_kill_ret *ret;
_DBG1(( "AccKillProg" ));
ret = GetOutPtr( 0 );
SaveStdIn = NIL_DOS_HANDLE;
SaveStdOut = NIL_DOS_HANDLE;
AtEnd = TRUE;
if( !DoneAutoCAD ) {
AtEnd = TRUE;
cputs( "*** Please quit AUTOCAD in order to restart debugger ***\r\n" );
MyRunProg();
}
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqSet_watch()
{
watch *curr;
set_watch_req *acc;
set_watch_ret *ret;
int i,needed;
_DBG0(( "AccSetWatch" ));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->multiplier = 20000;
ret->err = 1;
if( WatchCount < MAX_WP ) {
ret->err = 0;
curr = WatchPoints + WatchCount;
curr->addr = acc->watch_addr;
ReadMemory( &acc->watch_addr, (byte *)&curr->value, 4 );
++WatchCount;
curr->linear = GetLinear( curr->addr.segment, curr->addr.offset );
curr->len = acc->size;
curr->dregs = ( curr->linear & (curr->len-1) ) ? 2 : 1;
curr->linear &= ~(curr->len-1);
needed = 0;
for( i = 0; i < WatchCount; ++i ) {
needed += WatchPoints[ i ].dregs;
}
if( needed <= 4 ) ret->multiplier |= USING_DEBUG_REG;
_DBG0((
"addr %4.4x:%8.8lx "
"linear %8.8x "
"len %d "
"needed %d "
,curr->addr.segment,curr->addr.offset
,curr->linear
,curr->len
,needed
));
}
return( sizeof( *ret ) );
}
unsigned ReqClear_watch()
{
_DBG0(( "AccRestoreWatch" ));
/* assume all watches removed at same time */
WatchCount = 0;
return( 0 );
}
unsigned ReqSet_break()
{
set_break_req *acc;
set_break_ret *ret;
static char brake = 0xCC; /* cause maybe SS != DS */
_DBG1(( "AccSetBreak" ));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( ReadMemory( &acc->break_addr, (byte *)&ret->old, 1 ) == 0 ) {
ret->old = 0;
} else {
WriteMemory( &acc->break_addr, &brake, 1 );
}
return( sizeof( *ret ) );
}
unsigned ReqClear_break()
{
clear_break_req *acc;
acc = GetInPtr( 0 );
WriteMemory( &acc->break_addr, (byte *)&acc->old, 1 );
_DBG1(( "AccRestoreBreak" ));
return( 0 );
}
static dword *DR[] = { &SysRegs.dr0, &SysRegs.dr1, &SysRegs.dr2, &SysRegs.dr3 };
static void SetDRnBW( int dr, dword linear, int len ) /* Set DRn for break on write */
{
*DR[ dr ] = linear;
SysRegs.dr7 |= ( ( DRLen( len )+DR7_BWR) << DR7_RWLSHIFT( dr ) )
| ( DR7_GEMASK << DR7_GLSHIFT( dr ) );
}
static bool SetDebugRegs()
{
int needed;
int i;
int dr;
watch *wp;
needed = 0;
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
needed += wp->dregs;
}
if( needed > 4 ) return( FALSE );
dr = 0;
SysRegs.dr7 = DR7_GE;
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
SetDRnBW( dr, wp->linear, wp->len );
++dr;
if( wp->dregs == 2 ) {
SetDRnBW( dr, wp->linear+4, wp->len );
++dr;
}
}
return( TRUE );
}
void DumpRegs( trap_cpu_regs *regs )
{
regs=regs;
_DBG0(("EAX=%8.8x EBX=%8.8x ECX=%8.8x EDX=%8.8x",
regs->EAX, regs->EBX, regs->ECX, regs->EDX ));
_DBG0(("ESI=%8.8x EDI=%8.8x ESP=%8.8x EBP=%8.8x",
regs->ESI, regs->EDI, regs->ESP, regs->EBP ));
_DBG0(("DS=%4.4x ES=%4.4x FS=%4.4x GS=%4.4x",
regs->DS, regs->ES, regs->FS, regs->GS ));
_DBG0(("CS=%4.4x EIP=%8.8x EFL=%8.8x SS=%4.4x",
regs->CS, regs->EIP, regs->EFL, regs->SS ));
}
static unsigned ProgRun( bool step )
{
watch *wp;
long trace;
int i;
dword value;
prog_go_ret *ret;
_DBG1(( "ProgRun" ));
ret = GetOutPtr( 0 );
ret->conditions = COND_CONFIG;
trace = step ? 0x100 : 0;
Regs.EFL |= trace;
if( AtEnd ) {
_DBG2(("No RunProg"));
;
} else if( !trace && WatchCount != 0 ) {
_DBG2(("All that trace goop"));
if( SetDebugRegs() ) {
MyRunProg();
SysRegs.dr6 = 0;
SysRegs.dr7 = 0;
} else {
for( ;; ) {
Regs.EFL |= 0x100;
MyRunProg();
if( DoneAutoCAD ) break;
if( IntNum != 1 ) break;
if( !( SysRegs.dr6 & DR6_BS ) ) break;
for( wp = WatchPoints, i = WatchCount; i > 0; ++wp, --i ) {
ReadMemory( &wp->addr, (void *)&value, 4 );
if( value != wp->value ) {
ret->conditions |= COND_WATCH;
goto leave;
}
}
}
}
} else {
MyRunProg();
}
if( AtEnd ) {
ret->conditions |= COND_TERMINATE;
} else if( DoneAutoCAD ) {
ret->conditions = COND_TERMINATE;
AtEnd = TRUE;
} else if( IntNum == 1 ) {
if( trace ) {
ret->conditions |= COND_TRACE;
} else {
ret->conditions |= COND_WATCH;
}
} else if( IntNum == 3 ) {
ret->conditions |= COND_BREAK;
Regs.EIP--;
} else {
ret->conditions |= COND_EXCEPTION;
}
leave:
Regs.EFL &= ~trace;
ret->program_counter.offset = Regs.EIP;
ret->program_counter.segment = Regs.CS;
ret->stack_pointer.offset = Regs.ESP;
ret->stack_pointer.segment = Regs.SS;
WatchCount = 0;
return( sizeof( *ret ) );
}
unsigned ReqProg_go()
{
return( ProgRun( FALSE ) );
}
unsigned ReqProg_step()
{
return( ProgRun( TRUE ) );
}
static unsigned Redirect( bool input )
{
int std_hndl;
int *var;
int handle;
char *name;
redirect_stdin_ret *ret;
ret = GetOutPtr( 0 );
name = GetInPtr( sizeof( redirect_stdin_req ) );
ret->err = 0;
if( input ) {
std_hndl = 0;
var = &SaveStdIn;
} else {
std_hndl = 1;
var = &SaveStdOut;
}
if( *name == '\0' ) {
if( *var != NIL_DOS_HANDLE ) {
if( dup2( *var, std_hndl ) == -1 ) {
ret->err = 1; // error!
} else {
close( *var );
*var = NIL_DOS_HANDLE;
}
}
} else {
if( *var == NIL_DOS_HANDLE ) {
*var = dup( std_hndl );
}
if( input ) {
handle = open( name, O_BINARY | O_RDWR, 0 );
} else {
handle = open( name, O_BINARY | O_RDWR | O_TRUNC | O_CREAT, 0 );
}
if( handle == -1 ) {
ret->err = 1; // error!
} else {
dup2( handle, std_hndl );
close( handle );
}
}
return( sizeof( *ret ) );
}
unsigned ReqRedirect_stdin()
{
return( Redirect( TRUE ) );
}
unsigned ReqRedirect_stdout()
{
return( Redirect( FALSE ) );
}
#if 0
static void DOSEnvLkup( char *src, char *dst )
{
char *p;
p = getenv( src );
if( p == NULL ) {
*dst = '\0';
} else {
strcpy( dst, p );
}
}
#endif
unsigned ReqGet_next_alias()
{
get_next_alias_req *acc;
get_next_alias_ret *ret;
_DBG(("AccGetNextAlias"));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( acc->seg == 0 ) {
_DBG(("acc->seg == 0"));
ret->seg = Regs.CS;
ret->alias = Regs.DS;
} else {
_DBG(("acc->seg == other"));
ret->seg = 0;
ret->alias = 0;
}
return( sizeof( *ret ) );
}
#if 0
extern int GtKey();
#pragma aux GtKey = \
0XB4 0X00 /* mov ah,0 */ \
0XCD 0X16 /* int 16 */ \
modify [ ax ];
static unsigned_16 AccReadUserKey()
{
rd_key_return FAR *retblk;
retblk = GetOutPtr( 0 );
retblk->key = GtKey();
return( sizeof( rd_key_return ) );
}
#endif
unsigned ReqGet_err_text()
{
static char *DosErrMsgs[] = {
#include "dosmsgs.h"
};
get_err_text_req *acc;
char *err_txt;
#define MAX_CODE (sizeof( DosErrMsgs ) / sizeof( char * ) - 1)
_DBG1(( "AccErrText" ));
acc = GetInPtr( 0 );
err_txt = GetOutPtr( 0 );
if( acc->err > MAX_CODE ) {
utoa( acc->err, err_txt, 16 );
} else {
strcpy( err_txt, DosErrMsgs[ acc->err ] );
}
return( strlen( err_txt ) + 1 );
}
unsigned ReqGet_lib_name()
{
char *ch;
get_lib_name_ret *ret;
ret = GetOutPtr( 0 );
ret->handle = 0;
ch = GetOutPtr( sizeof( *ret ) );
*ch = '\0';
return( sizeof( *ret ) + 1 );
}
unsigned ReqGet_message_text()
{
get_message_text_ret *ret;
char *err_txt;
ret = GetOutPtr( 0 );
err_txt = GetOutPtr( sizeof(*ret) );
if( IntNum == -1 ) {
err_txt[0] = '\0';
} else {
ExceptionText( IntNum, err_txt );
IntNum = -1;
}
ret->flags = MSG_NEWLINE | MSG_ERROR;
return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}
trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
trap_version ver;
_DBG0(( "TrapInit" ));
remote = remote; parm = parm;
err[0] = '\0'; /* all ok */
ver.major = TRAP_MAJOR_VERSION;
ver.minor = TRAP_MINOR_VERSION;
ver.remote = FALSE;
SaveStdIn = NIL_DOS_HANDLE;
SaveStdOut = NIL_DOS_HANDLE;
RealNPXType = NPXType();
WatchCount = 0;
FakeBreak = FALSE;
GrabVects();
_DBG0(( "Done TrapInit" ));
return( ver );
}
void LetACADDie()
{
if( DoneAutoCAD ) {
DoneAutoCAD = FALSE;
MyRunProg(); /* we're history! */
}
}
void TRAPENTRY TrapFini()
{
_DBG0(( "TrapFini" ));
ReleVects();
_DBG0(( "Done TrapFini" ));
}
void GotInt3()
{
_DBG0(( "Got Int 3!!!" ));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?