📄 register.cpp
字号:
/*****************************************************************************
* Change Log
* Date | Change
*-----------+-----------------------------------------------------------------
* 15-Mar-98 | Created change log
*****************************************************************************/
#include "stdafx.h"
#include <winioctl.h>
#include "register.h"
#include "Simulator.h"
#include "format.h"
/****************************************************************************
* IORegisters::get
* Inputs:
* UINT registerID: register ID
* Result: BYTE
* The 8-bit register value
* Effect:
* Queries the simulator for the local copy of the register
****************************************************************************/
BYTE IORegisters::get(UINT registerID)
{
ASSERT(valid);
return SimulatedRegisters.registers[registerID];
}
/****************************************************************************
* IORegisters::set
* Inputs:
* UINT registerID: register ID
* BYTE value: value to set
* Result: void
*
* Effect:
* Sets the register in the local copy. Marks the register as "dirty"
* in the writeBitmap
****************************************************************************/
void IORegisters::set(UINT registerID, BYTE value)
{
ASSERT(valid);
SimulatedRegisters.registers[registerID] = value;
SimulatedRegisters.writeBitmap |= WRITE_BITMAP(registerID); // mark
}
/****************************************************************************
* IORegisters::generateInterrupt
* Result: void
*
* Effect:
* Enqueues a request an interrupt on the simulated device. This will
* be taken when the registers are written back.
****************************************************************************/
void IORegisters::generateInterrupt()
{
ASSERT(valid);
wantInterrupt = TRUE;
}
/****************************************************************************
* IORegisters::read
* Result: void
*
* Effect:
* Reads the register set from the device
* Notes:
* A "Register transaction" begins with a "read" operation and ends with
* a "write" operation. Note the ASSERTs that check that local register
* accesses take place between a "read" and a "write". Accesses that
* precede a "read" or follow a "write" are invalid.
****************************************************************************/
void IORegisters::read()
{
ASSERT(!valid);
#ifdef _DEBUG
valid = TRUE;
#endif
if(simulator == NULL)
return;
DWORD BytesRead = 0;
// We are reading the registers. We use a dummy write block that
// contains no flags in the writeBitmap
HDW_SIM_REGS nothing;
nothing.writeBitmap = 0; // nothing to write
BOOL result = DeviceIoControl(simulator, // simulator device
IOCTL_HDW_SIM_REGS,
¬hing, // empty register write set
sizeof(nothing),
&SimulatedRegisters, // place to put result
sizeof(SimulatedRegisters), // size
&BytesRead, // how many read
NULL); // Not overlapped
if(!result || BytesRead != sizeof(SimulatedRegisters))
DeviceIoControlFailure(IDS_DEVICEIO_FAILED_READ, GetLastError(),
&BytesRead, sizeof(SimulatedRegisters));
SimulatedRegisters.writeBitmap = 0; // force all registers to be "clean"
wantInterrupt = FALSE; // note this may be redundant, but let's be sure!
}
/****************************************************************************
* IORegisters::write
* Result: void
*
* Effect:
* Writes the register set back to the device. Only those registers
* modified by the writeBitmap are actually written
* If the wantInterrupt flag is set, generate an interrupt
****************************************************************************/
void IORegisters::write()
{
ASSERT(valid);
#ifdef _DEBUG
valid = FALSE;
#endif
if(simulator == NULL)
{ /* no simulator */
if(wantInterrupt)
MessageBeep(MB_ICONERROR);
wantInterrupt = FALSE;
return;
} /* no simulator */
DWORD RequiredButNotMeaningful; //the name says it all
// Right now we don't worry about race conditions, so when the write
// operation completes, we ignore the data read back ("write" ends a
// transaction)
if(SimulatedRegisters.writeBitmap != 0)
{ /* something to write */
HDW_SIM_REGS nothing;
BOOL result = DeviceIoControl(
simulator, // simulator device
IOCTL_HDW_SIM_REGS,
&SimulatedRegisters, // registers to write
sizeof(SimulatedRegisters), // size
¬hing, // output ignored
sizeof(nothing),
&RequiredButNotMeaningful,
NULL); // Not overlapped
if(!result)
DeviceIoControlFailure(IDS_DEVICEIO_FAILED_WRITE, GetLastError());
} /* something to write */
if(wantInterrupt)
{ /* generate Interrupt */
BOOL result = DeviceIoControl(simulator,
IOCTL_HDW_SIM_GEN_INTR,
NULL,
0,
NULL,
0,
&RequiredButNotMeaningful,
NULL);
} /* generate Interrupt */
// Once we have completed the write transaction, clear the
// wantInterrupt flag
wantInterrupt = FALSE;
}
/****************************************************************************
* IORegisters::Open
* Result: BOOL
* TRUE if handle open successfully
* FALSE if device open failed
* Effect:
* Opens the device simulator
****************************************************************************/
BOOL IORegisters::Open()
{
simulator = CreateFile(_T("\\\\.\\HdwSim"),
GENERIC_READ | GENERIC_WRITE,
0, // no sharing
NULL,
OPEN_EXISTING, // creationdisposition
FILE_ATTRIBUTE_NORMAL,
NULL);
if(simulator == INVALID_HANDLE_VALUE)
{ /* failed */
simulator = NULL;
return FALSE;
} /* failed */
#ifdef _DEBUG
valid = FALSE;
#endif
return TRUE;
}
/****************************************************************************
* IORegisters::Close
* Result: void
*
* Effect:
* Closes the handle if it is open
****************************************************************************/
void IORegisters::Close()
{
if(simulator != NULL)
CloseHandle(simulator);
simulator = NULL;
#ifdef _DEBUG
valid = FALSE;
#endif
}
/****************************************************************************
* IORegisters::setIRQ
* Inputs:
* UINT irqValue: New IRQ number to set
* Result: void
*
* Effect:
* Sets the IRQ number
****************************************************************************/
void IORegisters::setIRQ(UINT irqValue)
{
if(simulator == NULL)
return; // ignore if simulator not running
HDW_SIM_SET_INTR irq;
irq.interrupt_Line = irqValue;
DWORD RequiredButNotMeaningful; // the name says it all
BOOL result = DeviceIoControl(simulator,
IOCTL_HDW_SIM_SET_INTR,
&irq,
sizeof(HDW_SIM_SET_INTR),
NULL,
0,
&RequiredButNotMeaningful,
NULL);
if(!result)
DeviceIoControlFailure(IDS_DEVICEIO_FAILED_SET_INTR, GetLastError());
}
/****************************************************************************
* IORegisters::DeviceIoControlFailure
* Inputs:
* UINT id: IDS_ entry of message
* DWORD err: Error code from GetLastError
* LPDWORD BytesRead: Pointer to number of bytes read, or NULL if not
* meaningful (default NULL)
* DWORD BytesExpected: If BytesRead is non-NULL, this is the number
* of bytes expected; if BytesRead is NULL, this is
* ignored (default 0)
* Result: void
*
* Effect:
* Issues error message
****************************************************************************/
void IORegisters::DeviceIoControlFailure(UINT id, DWORD err, LPDWORD BytesRead, DWORD BytesExpected)
{
CString s;
s.LoadString(IDS_DEVICEIO_FAILED_WRITE);
if(err != 0)
{ /* additional information */
s += _T("\r\n");
s += formatError(err);
} /* additional information */
if(BytesRead != NULL && *BytesRead != BytesExpected)
{ /* wrong length */
CString fmt;
fmt.LoadString(IDS_WRONG_LENGTH_READ);
CString t;
t.Format(fmt, sizeof(SimulatedRegisters), BytesRead);
s += _T("\r\n");
s += t;
} /* wrong length */
AfxMessageBox(s, MB_ICONERROR | MB_OK);
}
/****************************************************************************
* IORegisters::setTrace
* Inputs:
* DWORD trace: Trace flags to set
* Result: void
*
* Effect:
* Sets the trace flags if there is a valid simulator
****************************************************************************/
void IORegisters::setTrace(DWORD trace)
{
if(simulator == NULL)
return;
HDW_SIM_DEBUGMASK mask;
mask.value = trace;
DWORD RequiredButNotMeaningful; // the name says it all
BOOL result = DeviceIoControl(simulator,
IOCTL_HDW_SIM_SET_TRACE,
&mask,
sizeof(HDW_SIM_DEBUGMASK),
NULL,
0,
&RequiredButNotMeaningful,
NULL);
if(!result)
DeviceIoControlFailure(IDS_DEVICEIO_FAILED_SET_TRACE, GetLastError());
}
/****************************************************************************
* IORegisters::getTrace
* Result: DWORD
* Current trace flag, or 0 if simulator not valid
****************************************************************************/
DWORD IORegisters::getTrace()
{
if(simulator == NULL)
return 0;
HDW_SIM_DEBUGMASK mask;
DWORD BytesReturned;
BOOL result = DeviceIoControl(simulator,
IOCTL_HDW_SIM_GET_TRACE,
NULL,
0,
&mask,
sizeof(HDW_SIM_DEBUGMASK),
&BytesReturned,
NULL);
if(!result)
DeviceIoControlFailure(IDS_DEVICEIO_FAILED_GET_TRACE, GetLastError());
return mask.value;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -