static unsigned DoRun( bool step ) { unsigned conditions; if( HaveRemoteAsync() ) { conditions = MakeAsyncRun( step ); if( conditions & COND_RUNNING ) { conditions = DUIDlgAsyncRun(); } } else { conditions = MakeProgRun( step ); } return( conditions ); }
unsigned ExecProg( bool tracing, bool do_flip, bool want_wps ) { bool have_brk_at_ip; bool act_wps; bool first_time; mad_trace_how how; execute_state es; unsigned conditions; unsigned run_conditions; bool already_stopping; bool force_stop; if( !want_wps ) ++InCall; tracing = TraceStart( tracing ); WriteDbgRegs(); first_time = true; es = ES_NORMAL; run_conditions = 0; if( !HaveRemoteAsync() ) { DUIPlayDead( true ); } how = MTRH_STOP; for( ;; ) { switch( es ) { case ES_FORCE_BREAK: case ES_NORMAL: if( tracing ) { how = TraceHow( false ); } else { _SwitchOn( SW_EXECUTE_LONG ); how = MTRH_BREAK; } break; case ES_STEP_ONE: how = TraceHow( true ); break; } if( how == MTRH_STOP ) break; switch( how ) { case MTRH_BREAK: DbgUpdate( UP_CSIP_JUMPED ); _SwitchOn( SW_TOUCH_SCREEN_BUFF ); /* fall through */ case MTRH_SIMULATE: case MTRH_STEP: case MTRH_STEPBREAK: if( _IsOff( SW_TOUCH_SCREEN_BUFF ) ) break; /* fall through */ default: if( !(ScrnState & USR_SCRN_ACTIVE) && do_flip ) { DUIStop(); } _SwitchOff( SW_TOUCH_SCREEN_BUFF ); break; } if( first_time ) { /* got to be down here so that SW_EXECUTE_LONG is properly set */ SetThreadStates(); first_time = false; } have_brk_at_ip = InsertBPs( (es == ES_FORCE_BREAK) ); act_wps = UpdateWPs(); if( how == MTRH_BREAK ) { if( have_brk_at_ip ) { es = ES_STEP_ONE; RemoveBPs(); continue; /* back to top */ } if( act_wps && want_wps ) { InsertWPs(); } } SetMemBefore( tracing ); switch( how ) { case MTRH_SIMULATE: if( TraceSimulate() ) { conditions = COND_TRACE; break; } /* fall through */ case MTRH_STEP: /* only updates stack/execution */ conditions = DoRun( true ); break; default: /* only updates stack/execution */ conditions = DoRun( false ); break; } if( _IsOn( SW_EXECUTE_LONG ) ) { if( ScrnState & DBG_SCRN_ACTIVE ) { _SwitchOn( SW_MIGHT_HAVE_LOST_DISPLAY ); } _SwitchOff( SW_EXECUTE_LONG ); } SetMemAfter( tracing ); run_conditions &= ~COND_WATCH; run_conditions |= conditions; RemoveBPs(); if( conditions & COND_MESSAGE ) { if( !RecordMsgText( &conditions ) ) { conditions &= ~COND_MESSAGE; } } conditions = CheckBPs( conditions, run_conditions ); if( _IsOn( SW_BREAK_ON_DEBUG_MESSAGE ) && ( conditions & COND_MESSAGE ) ) { conditions |= COND_STOP; } if( HaveRemoteAsync() && (conditions & COND_THREAD ) ) { conditions |= COND_STOP; } if( how == MTRH_STEPBREAK && (conditions & COND_BREAK) && DbgTmpBrk.status.b.hit ) { conditions &= ~COND_BREAK; conditions |= COND_TRACE; } if( conditions & COND_LIBRARIES ) { already_stopping = ( conditions & COND_STOPPERS ) != 0; conditions &= ~COND_LIBRARIES; force_stop = false; if( AddLibInfo( already_stopping, &force_stop ) ) { if( force_stop || DLLMatch() ) { conditions |= COND_STOP | COND_LIBRARIES; } } ReMapPoints( NULL ); } if( conditions & COND_SECTIONS ) { SectTblRead( DbgRegs ); InvalidateTblCache(); } if( (es == ES_STEP_ONE) && (conditions & COND_TRACE) ) { conditions &= ~COND_TRACE; } if( tracing ) { conditions = TraceCheck( conditions ); } if( !(conditions & COND_STOPPERS) && TBreak() ) { conditions |= COND_USER; break; } if( conditions & COND_STOPPERS ) break; switch( es ) { case ES_STEP_ONE: es = ES_FORCE_BREAK; break; case ES_FORCE_BREAK: es = ES_NORMAL; break; } if( (run_conditions & COND_WATCH) && es == ES_NORMAL ) { /* We got a spurious watch point indication. Make the next instruction single step since we might be dealing with a control flow opcode on a machine without a T-bit (e.g. Alpha). */ es = ES_STEP_ONE; } } TraceStop( tracing ); DUIPlayDead( false ); SetProgState( run_conditions ); _SwitchOff( SW_KNOW_EMULATOR ); if( !want_wps ) --InCall; return( conditions ); }