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

📄 parallelport.cpp

📁 并口操作的封装类
💻 CPP
📖 第 1 页 / 共 3 页
字号:
          settings.m_Type = CParallelPortSettings::ParallelTypeSPP;

        settings.m_nBaseAddress = nBaseAddress;
        settings.m_ECPMode = CParallelPortSettings::ECPModeUndefined;
        bSuccess = TRUE;
      }
    }
  }

  if (!bSuccess)
  {
    settings.m_nBaseAddress = 0;
    settings.m_Type = CParallelPortSettings::ParallelTypeUndefined;
    settings.m_ECPMode = CParallelPortSettings::ECPModeUndefined;
  }  

  return bSuccess;
}

BOOL CParallelPort::GetECPPort(unsigned short nBaseAddress)
{
  //If the ECP is idle and the FIFO empty,
  //in the ECP's Ecp (at base address+402h),
  //bit 1 (Fifo full)=0, and bit 0 (Fifo empty)=1.
  //The first test is to see if these bits differ from the
  //corresponding bits in the control port (at base address+2).
  //If so a further test is to write 34h to the Ecr, 
  //then read it back. Bit 1 is read/write and bit 0 is read-only.
  //If the value read is 35h, the port is an ECP.
  BOOL bSuccess = FALSE;
 
  unsigned short nEcrAddress = (unsigned short)(nBaseAddress+0x402);
  int nEcrData = _inp(nEcrAddress);
  
  //Read bits 0 and 1 and control port bit 1
  int nEcrBit0 = nEcrData & 0x1;
  int nEcrBit1 = (nEcrData & 0x2) >> 1;
  int nControlBit1 = (ReadControl(nBaseAddress) & 0x2) >> 1;

  if (nEcrBit0 == 1 && nEcrBit1 == 0)
  {
    //Compare control bit 1 to ECR bit 1
    //Toggle the control bit if necessary
    //to be sure the two registers are different.
    if (nControlBit1 == 0)
    {
      WriteControl(nBaseAddress, 0xF);
      nControlBit1 = (ReadControl(nBaseAddress) & 0x2) >> 1;
    }

    if (nEcrBit1 != nControlBit1)
    {
      int nOriginalEcrData = nEcrData;
      _outp(nEcrAddress, 0x34);
      if (_inp(nEcrAddress) == 0x35)
        bSuccess = TRUE;

      //Restore the ECR to its original value
      _outp(nEcrAddress, nOriginalEcrData);
    }
  }

  return bSuccess;
}

BOOL CParallelPort::GetEPPPort(unsigned short nBaseAddress)
{
  //Write to an EPP register, then read it back.
  //If the read matches the write, it's probably an EPP
  BOOL bSuccess = FALSE;

  //Use nEppAddressPort for testing, SPP's, ECP's and PS/2 ports
  //do not have this register
  unsigned short nEppAddressPort = (unsigned short) (nBaseAddress+3);
  _outp(nEppAddressPort, 0x55);

  //Clear the timeout bit after each EPP operation
  int nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
  int nRead = _inp(nEppAddressPort);
  nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
  if (nRead == 0x55)
  {
    _outp(nEppAddressPort, 0xAA);
    nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
    nRead = _inp(nEppAddressPort);
    nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
    if (nRead == 0xAA)
      bSuccess = TRUE;
  }  

  return bSuccess;
}

int CParallelPort::GetEPPTimeoutBit(unsigned short nBaseAddress)
{
  //Reads and clears the EPP timeout bit (Statis port bit 0)
  //Should be done after each EPP operation.
  //The method for clearing the bit varies, so try 3 ways
  //1. Write 1 to status port bit 0
  //2. Write 0 to status port bit 1
  //3. Read the status port again
  int nReturn = (ReadStatus(nBaseAddress) & 0x1);
  unsigned short nStatusPortAddress = (unsigned short)(nBaseAddress+1);
  _outp(nStatusPortAddress, 1);
  _outp(nStatusPortAddress, 0);
  nReturn = (ReadStatus(nBaseAddress) & 0x1);
  return nReturn;
}

BOOL CParallelPort::GetPS2Port(unsigned short nBaseAddress)
{
  //First try to tristate (disable) the data outputs by
  //setting bit 5 of the control port. Then write 2 values
  //to the data port and read each one back. If the values
  //match, the data outputs are not disabled and the port
  //is not bidirectional. If the values don't match, the data 
  //outputs are disabled and the port is didirectional
  BOOL bSuccess = FALSE;

  //Set control port bit 5
  WriteControl(nBaseAddress, 0x2F);

  //Write the first byte and read it back
  WriteData(nBaseAddress, 0x55);

  //If it doesn't match, the port is bidirectional
  if (ReadData(nBaseAddress) == 0x55)
  {      \
    WriteData(nBaseAddress, 0xAA);

    //If it doesn't match, the port is bidirectional
    if (ReadData(nBaseAddress) != 0xAA)
      bSuccess = TRUE;
  }
  else
    bSuccess = TRUE;

  //Reset control port bit 5
  WriteControl(nBaseAddress, 0xF);

  return bSuccess;
}

BOOL CParallelPort::GetSPPPort(unsigned short nBaseAddress)
{
  //Write two bytes and read them back. If the
  //reads matches the writes, the port exists
  BOOL bSuccess = FALSE;
  
  //Be sure that control port bit 5 = 0 (Data outputs enabled)
  WriteControl(nBaseAddress, 0xF);

  //Perform the first write  
  WriteData(nBaseAddress, 0x55);
  if (ReadData(nBaseAddress) == 0x55)
  {
    WriteData(nBaseAddress, 0xAA);
    bSuccess = (ReadData(nBaseAddress) == 0xAA);
  }

  return bSuccess;
}

void CParallelPort::WriteControl(unsigned short nBaseAddress, int nData)
{
  //The control port is at offset nBaseAddress + 2.
  //Bits 0, 1 & 3 need to be inverted  
  _outp((unsigned short)(nBaseAddress+2), nData ^ 0xB);
}

int CParallelPort::ReadControl(unsigned short nBaseAddress)
{
  //The control port is at offset nBaseAddress + 2.
  //Bits 0, 1 & 3 need to be inverted  
  return (_inp((unsigned short)(nBaseAddress+2)) ^ 0xB);
}

void CParallelPort::WriteData(unsigned short nBaseAddress, int nData)
{
  //The data port is at offset nBaseAddress.
  _outp(nBaseAddress, nData);
}

int CParallelPort::ReadData(unsigned short nBaseAddress)
{
  //The data port is at offset nBaseAddress.
  return _inp(nBaseAddress);
}

int CParallelPort::ReadStatus(unsigned short nBaseAddress)
{
  //The status port is at offset nBaseAddress + 1.
  //Bit 7 need to be inverted  
  return (_inp((unsigned short)(nBaseAddress+1)) ^ 0x80);
}

void CParallelPort::WriteControl(int nData)
{
  ASSERT(IsOpen()); //Port must be open
  WriteControl(m_nBaseAddress, nData);  
}

int CParallelPort::ReadControl()
{
  ASSERT(IsOpen()); //Port must be open
  return ReadControl(m_nBaseAddress);  
}

void CParallelPort::WriteData(int nData)
{
  ASSERT(IsOpen()); //Port must be open
  WriteData(m_nBaseAddress, nData);  
}

int CParallelPort::ReadData()
{
  ASSERT(IsOpen()); //Port must be open
  return ReadData(m_nBaseAddress);  
}

int CParallelPort::ReadStatus()
{
  ASSERT(IsOpen()); //Port must be open
  return ReadStatus(m_nBaseAddress);  
}

BOOL CParallelPort::ReadByteUsingNibbleMode(BYTE& byData)
{
  ASSERT(IsOpen()); //Port must be open

  //Read a byte of data at the status port, in 2 nibbles

  //When S6 = 0, set D3 to 0
  int S6;
  DWORD dwStartTicks = GetTickCount();
  do
  {
    S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 1);
  WriteData(m_nBaseAddress, 0);

  //When the peripheral responds by setting S6=1, Set D3=1
  //nLowNibble then holds 4 bits of data
  int nLowNibble;
  do
  {
    nLowNibble = ReadStatus(m_nBaseAddress);
    S6 = (nLowNibble & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 0);
  WriteData(m_nBaseAddress, 8);

  //When S6 = 0, set D3 to 0
  do
  {
    S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 1);
  WriteData(m_nBaseAddress, 0);

  //When the peripheral responds by setting S6=1, Set D3=1
  //nHighNibble then holds 4 bits of data
  int nHighNibble;
  do
  {
    nHighNibble = ReadStatus(m_nBaseAddress);
    S6 = (nHighNibble & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 0);
  WriteData(m_nBaseAddress, 8);

  //Recombine the two nibbles back into the byte
  byData = (BYTE) (((nLowNibble & 0x8) >> 3) +
                   ((nLowNibble & 0x10) >> 3) +
                   ((nLowNibble & 0x20) >> 3) +
                   ((nLowNibble & 0x80) >> 4) +
                   ((nHighNibble & 0x8) << 1) +
                   ((nHighNibble & 0x10) << 1) +
                   ((nHighNibble & 0x20) << 1) +
                   ((nHighNibble & 0x80))); 

  return TRUE;
}

BOOL CParallelPort::WriteByteUsingNibbleMode(BYTE byData)
{
  ASSERT(IsOpen()); //Port must be open

  //Write a byte to the data port, in 2 nibbles.
  //The remote system reads the data at its status port.
  //The data bits are D0, D1, D2 and D4.
  //D3 is the strobe
  int nLowNibble = byData & 0x07;
  nLowNibble |= (byData & 0x08) << 1;
  int nHighNibble = (byData & 0x70) >> 4;
  nHighNibble |= (byData & 0x80) >> 3;

  //When S6=1 (not busy), write the low nibble and set D3=0.
  int S6;
  DWORD dwStartTicks = GetTickCount();  
  do
  {
    S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 0);
  WriteData(m_nBaseAddress, nLowNibble);

  //When the peripheral responds by setting S6=0, Set D3=1.
  do
  {
    S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 1);
  WriteData(m_nBaseAddress, nLowNibble | 0x8);

  //When S6=1, write the high nibble and set D3=0
  do
  {
    S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 0);
  WriteData(m_nBaseAddress, nHighNibble);

  //When the peripheral responds by setting S6=0, Set D3=1.
  do
  {
    S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;

    //Check the timeout has not elapsed
    if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
      return FALSE;
  }
  while (S6 == 1);
  WriteData(m_nBaseAddress, nHighNibble | 0x8);

  return TRUE;
}

BOOL CParallelPort::ReadUsingNibbleMode(void* lpBuf, DWORD dwBytes)
{
  //Validate the parameters
  ASSERT(lpBuf);

  //Read each byte into lpBuf  
  BYTE* lpByteBuf = (BYTE*) lpBuf;
  for (DWORD i=0; i<dwBytes; i++)
  {
    if (!ReadByteUsingNibbleMode(lpByteBuf[i]))
      return FALSE;
  }
  return TRUE;
}

BOOL CParallelPort::WriteUsingNibbleMode(const void* lpBuf, DWORD dwBytes)
{
  //Validate the parameters
  ASSERT(lpBuf);

  //Write each byte from lpBuf  
  const BYTE* lpByteBuf = (const BYTE*) lpBuf;
  for (DWORD i=0; i<dwBytes; i++)
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -