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 + -
显示快捷键?