📄 freerun.cpp
字号:
} /* set go */
CloseRegisterTransaction(_T("Register Go Hack Out"));
return 0;
}
/****************************************************************************
* CSimulatorDlg::OnPulse
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Indicates that a pulse has occurred in the polling operation
****************************************************************************/
LRESULT CSimulatorDlg::OnPulse(WPARAM, LPARAM)
{
c_GoHackIn.pulse();
c_GoHackOut.pulse();
return 0;
}
/****************************************************************************
* CSimulatorDlg::OnIACKOutSet
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Handles the IACK OUT bit being set
* - Clears the INT bit
* Notes:
* This is called for the freerun mode
****************************************************************************/
LRESULT CSimulatorDlg::OnIACKOutSet(WPARAM, LPARAM)
{
ASSERT(!manual);
BYTE status = registers.get(REGISTER_OUT_STATUS);
status &= ~REGISTER_OUT_STATUS_INT; // clear INT bit
registers.set(REGISTER_OUT_STATUS, status);
OutStatusToControls(status);
TraceItem * item = new TraceItem(TRACE_TYPE_IACK_OUT, TRUE);
c_Trace.AddString(item);
item = new TraceItem(TRACE_TYPE_INT_OUT, FALSE);
c_Trace.AddString(item);
// Now clear the IACK bit
BYTE command = registers.get(REGISTER_OUT_COMMAND);
command &= ~REGISTER_OUT_COMMAND_IACK; // clear the IACK bit
registers.set(REGISTER_OUT_COMMAND, command);
item = new TraceItem(TRACE_TYPE_IACK_OUT, FALSE, _T("Auto-reset"));
c_Trace.AddString(item);
OutCommandToControls(command);
return 0;
}
/****************************************************************************
* CSimulatorDlg::OnIACKInSet
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Handles the IACK bit being set
****************************************************************************/
LRESULT CSimulatorDlg::OnIACKInSet(WPARAM, LPARAM)
{
ASSERT(!manual);
BYTE status = registers.get(REGISTER_IN_STATUS);
status &= ~REGISTER_IN_STATUS_INT; // clear INT bit
registers.set(REGISTER_IN_STATUS, status);
InStatusToControls(status);
TraceItem * item = new TraceItem(TRACE_TYPE_IACK_IN, TRUE, _T(""));
c_Trace.AddString(item);
item = new TraceItem(TRACE_TYPE_INT_IN, FALSE);
c_Trace.AddString(item);
// Now clear the IACK bit
BYTE command = registers.get(REGISTER_IN_COMMAND);
command &= ~REGISTER_IN_COMMAND_IACK; // clear the IACK bit
registers.set(REGISTER_IN_COMMAND, command);
item = new TraceItem(TRACE_TYPE_IACK_IN, FALSE, _T("Auto-reset"));
c_Trace.AddString(item);
InCommandToControls(command);
return 0;
}
/****************************************************************************
* CSimulatorDlg::OnTimer
* Inputs:
* UINT nIDEvent: Event id
* Result: void
*
* Effect:
* Handles the timer
****************************************************************************/
void CSimulatorDlg::OnTimer(UINT nIDEvent)
{
KillTimer(nIDEvent); // take only one such event
switch(nIDEvent)
{ /* event type */
case TIMER_SET_DONE_IN:
{ /* done in */
if(debug)
{ /* note it */
TraceItem * e = new TraceItem(TRACE_TYPE_ANNOTATION, _T("=> Timer: In Done"));
c_Trace.AddString(e);
} /* note it */
OpenRegisterTransaction(_T("Timer Done In"));
sendNext();
CloseRegisterTransaction(_T("Timer Done In"));
c_GoHackIn.setMode(TRUE); // indicate we are done waiting
if(debug)
{ /* note it */
TraceItem * e = new TraceItem(TRACE_TYPE_ANNOTATION, _T("<= Timer: In Done"));
c_Trace.AddString(e);
} /* note it */
} /* done in */
break;
case TIMER_SET_DONE_OUT:
{ /* done out */
if(debug)
{ /* note it */
TraceItem * e = new TraceItem(TRACE_TYPE_ANNOTATION, _T("=> Timer: Out Done"));
c_Trace.AddString(e);
} /* note it */
OpenRegisterTransaction(_T("Timer Done Out"));
receiveNext();
CloseRegisterTransaction(_T("Timer Done Out"));
c_GoHackOut.setMode(TRUE);
if(debug)
{ /* note it */
TraceItem * e = new TraceItem(TRACE_TYPE_ANNOTATION, _T("<= Timer: Out Done"));
c_Trace.AddString(e);
} /* note it */
} /* done out */
break;
} /* event type */
CDialog::OnTimer(nIDEvent);
}
/****************************************************************************
* CSimulatorDlg::GoDoneDelay
* Result: DWORD
* Random interval
* At least GoDoneMinimum, and with as much as GoDoneVariance added
****************************************************************************/
DWORD CSimulatorDlg::GoDoneDelay()
{
DWORD interval = GoDoneMinimum;
if(GoDoneVariance > 0)
interval += rand() % GoDoneVariance;
return interval;
}
/****************************************************************************
* CSimulatorDlg::OnPoll
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Polls for input and output state changes
* Notes:
* Since this is done as an atomic operation in the context of the
* main thread, it can be properly serialized with WM_TIMER messages
****************************************************************************/
LRESULT CSimulatorDlg::OnPoll(WPARAM, LPARAM)
{
static int count = 0;
count++;
if(debug)
{ /* trace it */
TraceItem * e = new TraceItem(TRACE_TYPE_COMMENT, _T("=> OnPoll"));
c_Trace.AddString(e);
if(count > 1)
{ /* add error */
e = new TraceItem(TRACE_TYPE_ERROR, _T("!!! count wrong"));
c_Trace.AddString(e);
} /* add error */
} /* trace it */
else
{ /* watch it */
ASSERT(count < 2);
} /* watch it */
startPollingCycle();
pollInput();
pollOutput();
endPollingCycle();
count--;
if(debug)
{ /* trace it */
TraceItem * e = new TraceItem(TRACE_TYPE_COMMENT, _T("<= OnPoll"));
c_Trace.AddString(e);
} /* trace it */
::SetEvent(pause); // release polling thread
return 0;
}
/****************************************************************************
* CSimulatorDlg::pollInput
* Result: void
*
* Effect:
* If the GO bit is set, initiate the actions that will implement
* the transfer of a byte to the simulated device's input
****************************************************************************/
void CSimulatorDlg::pollInput()
{
BYTE command = registers.get(REGISTER_IN_COMMAND);
// Compare to the previous state
if( (command ^ CommandIn) & REGISTER_IN_COMMAND_GO)
{ /* Go bit set */
CommandIn = command; // store current state
OnGoInSet(0, 0);
} /* Go bit set */
if((command ^ CommandIn) & REGISTER_IN_COMMAND_IE)
{ /* IE bit set */
CommandIn = command; // Store current state
OnIEInSet(0, 0);
} /* IE bit set */
if((command ^ CommandIn) & REGISTER_IN_COMMAND_IACK)
{ /* IACK bit set */
CommandIn = command; // store current state
OnIACKInSet(0, 0);
} /* IACK bit set */
if((command ^ CommandIn) & REGISTER_IN_COMMAND_RST)
{ /* RST bit set */
CommandIn = command; // store current state
OnRstInSet(0, 0);
} /* RST bit set */
}
/****************************************************************************
* CSimulatorDlg::pollOutput
* Result: void
*
* Effect:
* If the GO bit is set for the output side, accept the byte from the
* device
****************************************************************************/
void CSimulatorDlg::pollOutput()
{
BYTE command = registers.get(REGISTER_OUT_COMMAND);
if(command & REGISTER_OUT_COMMAND_GO)
{ /* Go bit set */
OnGoOutSet(0, 0);
} /* Go bit set */
if((command ^ CommandOut) & REGISTER_OUT_COMMAND_IE)
{ /* IE bit set */
CommandOut = command; // Store current state
OnIEOutSet(0, 0);
} /* IE bit set */
if((command ^ CommandOut) & REGISTER_OUT_COMMAND_IACK)
{ /* IACK bit set */
CommandOut = command; // store current state
OnIACKOutSet(0, 0);
} /* IACK bit set */
if((command ^ CommandOut) & REGISTER_OUT_COMMAND_RST)
{ /* RST bit set */
CommandOut = command;
OnRstOutSet(0, 0);
} /* RST bit set */
}
/****************************************************************************
* CSimulatorDlg::OnSetTimerOut
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Sets the timer
* Notes:
* This is done via a PostMessage so it will not take place until
* the current transaction has completed
****************************************************************************/
LRESULT CSimulatorDlg::OnSetTimerOut(WPARAM, LPARAM)
{
DWORD interval = GoDoneDelay();
if(debug)
{ /* debug */
CString s;
s.Format(_T("Setting output timer %dms"), interval);
TraceItem * e = new TraceItem(TRACE_TYPE_COMMENT, s);
c_Trace.AddString(e);
} /* debug */
SetTimer(TIMER_SET_DONE_OUT, interval, NULL);
return 0;
}
/****************************************************************************
* CSimulatorDlg::OnSetTimerIn
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Sets the timer
* Notes:
* This is done via a PostMessage so it will not take place until
* the current transaction has completed
****************************************************************************/
LRESULT CSimulatorDlg::OnSetTimerIn(WPARAM, LPARAM)
{
DWORD interval = GoDoneDelay();
if(debug)
{ /* debug */
CString s;
s.Format(_T("Setting input timer %dms"), interval);
TraceItem * e = new TraceItem(TRACE_TYPE_COMMENT, s);
c_Trace.AddString(e);
} /* debug */
SetTimer(TIMER_SET_DONE_IN, interval, NULL);
return 0;
}
/****************************************************************************
* CSimulatorDlg::OnSingleStep
* Result: void
*
* Effect:
* Allows one (1) automatic cycle to occur
****************************************************************************/
void CSimulatorDlg::OnSinglestep()
{
if(!manual)
return; // should not be here!
TraceItem * item = new TraceItem(TRACE_TYPE_ANNOTATION, TRUE,
_T("Single Step Mode"));
c_Trace.AddString(item);
manual = FALSE;
singleStep = TRUE;
OpenRegisterTransaction("OnFreeRun");
updateControls();
CloseRegisterTransaction("OnFreeRun");
::PulseEvent(freerun);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -