static bool SetDebugRegs() { int needed; int i; watch *wp; bool success; long rc; needed = 0; for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) { needed += wp->dregs; } if( needed > 4 ) return( FALSE ); if( IsDPMI ) { success = TRUE; for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) { wp->handle = -1; wp->handle2 = -1; } for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) { _DBG2(( "Setting Watch On %8.8lx\r\n", wp->linear )); success = FALSE; rc = DPMISetWatch( wp->linear, wp->len, DPMI_WATCH_WRITE ); _DBG2(( "OK 1 = %d\r\n", rc >= 0 )); if( rc < 0 ) break; wp->handle = rc; if( wp->dregs == 2 ) { rc = DPMISetWatch( wp->linear+4, wp->len, DPMI_WATCH_WRITE ); _DBG2(( "OK 2 = %d\r\n", rc >= 0 )); if( rc <= 0 ) break; wp->handle2 = rc; } success = TRUE; } if( !success ) { ClearDebugRegs(); } return( success ); } else { int dr; unsigned long dr7; dr = 0; dr7 = 0; for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) { dr7 |= SetDRn( dr, wp->linear, DRLen( wp->len ) | DR7_BWR ); ++dr; if( wp->dregs == 2 ) { dr7 |= SetDRn( dr, wp->linear+4, DRLen( wp->len ) | DR7_BWR ); ++dr; } } SetDR7( dr7 ); return( TRUE ); } }
static int ReadWrite( int (*r)(word,dword,char*), addr48_ptr *addr, char *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 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 ? TRACE_BIT : 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 |= TRACE_BIT; 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 ) ); }