📄 manual.cpp
字号:
/*****************************************************************************
* Change Log
* Date | Change
*-----------+-----------------------------------------------------------------
* 20-Mar-99 | Created
* 20-Mar-99 | Added OnRstIn, OnRstOut handlers for reset bit
*****************************************************************************/
// manual.cpp: The functions associated with manual simulation
#include "stdafx.h"
#include "Simulator.h"
#include <sys\timeb.h>
#include "TraceWnd.h"
#include "Regvars.h"
#include "NumericEdit.h"
#include "InterruptMgt.h"
#include "SpinnerButton.h"
#include "register.h"
#include "RegData.h"
#include "RegDisplay.h"
#include "SimulatorDlg.h"
#include "uwm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/****************************************************************************
* CSimulatorDlg::OnManual
* Result: void
*
* Effect:
* Queues up a request to terminate freerun mode
* Notes:
* This posts a message so it falls behind the next UWM_POLL and thus
* prevents a deadlock situation
****************************************************************************/
void CSimulatorDlg::OnManual()
{
if(manual)
return; // already in manual mode
PostMessage(UWM_SET_MANUAL_MODE);
}
/****************************************************************************
* CSimulatorDlg::SetOnManualMode
* Inputs:
* WPARAM: ignored
* LPARAM: ignored
* Result: LRESULT
* 0, always
* Effect:
* Forces the free-running polling thread to stop after it completes its
* current cycle
****************************************************************************/
LRESULT CSimulatorDlg::OnSetManualMode(WPARAM single, LPARAM)
{
// We do a WaitForSingleObject here so we don't try to stop in the
// middle of a cycle
// The polling loop looks like this
//
// WaitForSingleObject(freerun);
// ResetEvent(stop) // block out stoppability
// * ResetEvent(pause); // wait for reply
// * PostMessage // will SetEvent(pause) when done
// * WaitForSingleObject(pause); //
// SetEventStop
//
::SetEvent(pause); // release pause that is queued up
::ResetEvent(freerun); // shut down freerun loop
DWORD interval;
if(pollInterval < 1000)
interval = 10 * pollInterval;
else
interval = 2 * pollInterval;
switch(::WaitForSingleObject(stop, interval))
{ /* wait */
case WAIT_TIMEOUT:
if(debug)
{
CString s;
s.LoadString(IDS_STOP_TIMEOUT);
TraceItem * e = new TraceItem(TRACE_TYPE_ERROR, s);
c_Trace.AddString(e);
}
PostMessage(UWM_SET_MANUAL_MODE); // resync state
return 0; // don't go any further
case WAIT_OBJECT_0:
break; // proceed with kill
default:
{
CString s;
s.LoadString(IDS_STOP_ERROR);
TraceItem * e = new TraceItem(TRACE_TYPE_ERROR, s);
c_Trace.AddString(e);
}
return 0;
} /* wait */
TraceItem * item = new TraceItem(TRACE_TYPE_ANNOTATION, TRUE,
single ? _T("End Single Step")
: _T("Manual Mode"));
c_Trace.AddString(item);
OpenRegisterTransaction(_T("OnManual"));
updateControls();
CloseRegisterTransaction(_T("OnManual"));
manual = TRUE;
singleStep = FALSE; // clear single step flag in case from single step
return 0;
}
void CSimulatorDlg::OnBusyOut()
{
ASSERT(manual);
OpenRegisterTransaction(_T("OnBusyOut"));
// Nothing to be done here
CloseRegisterTransaction(_T("OnBusyOut"));
}
/****************************************************************************
* CSimulatorDlg::OnDoneIn
* Result: void
*
* Effect:
* Forces the DONE bit to be set on the input side. This has the
* side effect that if IE is set, an interrupt will be generated
* Notes:
* The system must be in Manual mode and the Done bit must be
* clear for this to be enabled
****************************************************************************/
void CSimulatorDlg::OnDoneIn()
{
ASSERT(manual);
OpenRegisterTransaction(_T("OnDoneIn"));
BYTE status = registers.get(REGISTER_IN_STATUS);
BYTE newstatus = status;
BOOL done = c_DoneIn.GetCheck() == BST_CHECKED;
if(done)
{ /* set */
newstatus |= REGISTER_IN_STATUS_DONE;
} /* set */
else
{ /* cleared */
newstatus &= ~REGISTER_IN_STATUS_DONE;
} /* cleared */
registers.set(REGISTER_IN_STATUS, newstatus);
logStatusChangeIn(status, newstatus, _T("Manual"));
updateControls();
CloseRegisterTransaction(_T("OnDoneIn"));
}
/****************************************************************************
* CSimulatorDlg::OnDoneOout
* Result: void
*
* Effect:
* Simulates the DONE bit being checked manually
* Notes:
* This works only in manual mode
****************************************************************************/
void CSimulatorDlg::OnDoneOut()
{
ASSERT(manual);
ASSERT(manual);
OpenRegisterTransaction(_T("OnDoneOut"));
BYTE status = registers.get(REGISTER_OUT_STATUS);
BYTE newstatus = status;
BOOL done = c_DoneOut.GetCheck() == BST_CHECKED;
if(done)
{ /* set */
newstatus |= REGISTER_OUT_STATUS_DONE;
newstatus &= ~REGISTER_OUT_STATUS_BUSY; // clear busy
} /* set */
else
{ /* cleared */
newstatus &= ~REGISTER_OUT_STATUS_DONE;
} /* cleared */
registers.set(REGISTER_OUT_STATUS, newstatus);
logStatusChangeOut(status, newstatus, _T("Manual"));
updateControls();
CloseRegisterTransaction(_T("OnDoneOut"));
}
/****************************************************************************
* CSimulatorDlg::OnEopIn
* Result: void
*
* Effect:
* Logs the EOP bit being set
****************************************************************************/
void CSimulatorDlg::OnEopIn()
{
ASSERT(manual);
OpenRegisterTransaction(_T("OnEopIn"));
BYTE status = registers.get(REGISTER_IN_STATUS);
BYTE command = registers.get(REGISTER_IN_COMMAND);
BYTE newstatus = 0;
if(c_EopIn.GetCheck() == BST_CHECKED)
newstatus = status | REGISTER_IN_STATUS_EOP;
else
newstatus = status & ~REGISTER_IN_STATUS_EOP;
logStatusChangeIn(status, newstatus, _T("Manual Set"));
registers.set(REGISTER_IN_STATUS, newstatus);
InStatusToControls(newstatus);
CloseRegisterTransaction(_T("OnEopIn"));
}
/****************************************************************************
* CSimulatorDlg::OnErrIn
* Result: void
*
* Effect:
* Simulates an ERR status
* Clears EOP
* Sets DONE
* If IE is set, sets INT and generates an interrupt
****************************************************************************/
void CSimulatorDlg::OnErrIn()
{
ASSERT(manual);
OpenRegisterTransaction(_T("OnErrIn"));
BYTE status = registers.get(REGISTER_IN_STATUS);
BYTE command = registers.get(REGISTER_IN_COMMAND);
BYTE newstatus;
if(c_ErrIn.GetCheck() == BST_UNCHECKED)
{ /* off */
newstatus &= ~(REGISTER_IN_STATUS_ERR | REGISTER_IN_STATUS_OVR);
} /* off */
else
{ /* on */
newstatus = status | REGISTER_IN_STATUS_ERR | REGISTER_IN_STATUS_DONE;
newstatus &= ~ REGISTER_IN_STATUS_EOP;
if(c_OvrIn.GetCheck() == BST_CHECKED)
newstatus |= REGISTER_IN_STATUS_OVR;
else
newstatus &= ~REGISTER_IN_STATUS_OVR;
if(command & REGISTER_IN_COMMAND_IE)
newstatus |= REGISTER_IN_STATUS_INT;
} /* on */
logStatusChangeIn(status, newstatus);
registers.set(REGISTER_IN_STATUS, newstatus);
InStatusToControls(newstatus);
if((newstatus & REGISTER_IN_STATUS_ERR) &&
(command & REGISTER_IN_COMMAND_IE))
generateAndLogInterrupt(_T("by manual ERR"));
CloseRegisterTransaction(_T("OnErrIn"));
}
/****************************************************************************
* CSimulatorDlg::OnErrOut
* Result: void
*
* Effect:
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -