⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 register.cpp

📁 通过VC源代码
💻 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,
     				   &nothing,     // 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
				&nothing, 	       	// 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 + -