// // send byte // VOID CpPutByte(__in PCPPORT Port,__in UCHAR Byte) { // // if modem control, make sure DSR, CTS and CD are all set before sending any data. // UCHAR msr; while((Port->Flags & PORT_MODEMCONTROL) && (msr = READ_UCHAR(Port->Address + COM_MSR) & MS_DSRCTSCD) != MS_DSRCTSCD) { // // if no CD, and there's a charactor ready, eat it // if((msr & MS_CD) == 0 && (CpReadLsr(Port,0) & COM_DATRDY) == COM_DATRDY) READ_UCHAR(Port->Address + COM_DAT); } // // wait for port to not be busy // while(!(CpReadLsr(Port, COM_OUTRDY) & COM_OUTRDY)); // // send the byte // WRITE_UCHAR(Port->Address + COM_DAT, Byte); }
// // fetch a byte // ULONG CpGetByte(__in PCPPORT Port,__out PUCHAR Byte,__in BOOLEAN WaitForByte,__in BOOLEAN CheckOnly) { // // check to make sure the CPPORT we were passed has been initialized. // if(!Port->Address) return CP_GET_NODATA; ULONG LimitCount = WaitForByte ? 204800 : 1; while(LimitCount) { LimitCount -= 1; // // check data ready // UCHAR lsr = CpReadLsr(Port,COM_DATRDY); if((lsr & COM_DATRDY) == COM_DATRDY) { // // check for errors // if(lsr & (COM_FE | COM_PE | COM_OE)) { *Byte = 0; return CP_GET_ERROR; } // // check data ready only // if(CheckOnly) return CP_GET_SUCCESS; // // fetch the byte // UCHAR value = READ_PORT_UCHAR(Port->Address + COM_DAT); if(Port->Flags & PORT_MODEMCONTROL) { // // using modem control. if no CD, then skip this byte. // if((READ_UCHAR(Port->Address + COM_MSR) & MS_CD) == 0) continue; } *Byte = value & 0xff; return CP_GET_SUCCESS; } } CpReadLsr(Port,0); return CP_GET_NODATA; }
USHORT NTAPI CpGetByte(IN PCPPORT Port, IN PUCHAR Byte, IN BOOLEAN Wait, IN BOOLEAN Poll) { UCHAR Lsr; ULONG i; /* Handle early read-before-init */ if (!Port->Address) return CP_GET_NODATA; /* If "wait" mode enabled, spin many times, otherwise attempt just once */ i = Wait ? 204800 : 1; while (i--) { /* Read LSR for data ready */ Lsr = CpReadLsr(Port, SERIAL_LSR_DR); if ((Lsr & SERIAL_LSR_DR) == SERIAL_LSR_DR) { /* If an error happened, clear the byte and fail */ if (Lsr & (SERIAL_LSR_FE | SERIAL_LSR_PE)) { *Byte = 0; return CP_GET_ERROR; } /* If only polling was requested by caller, return now */ if (Poll) return CP_GET_SUCCESS; /* Otherwise read the byte and return it */ *Byte = READ_PORT_UCHAR(Port->Address + RECEIVE_BUFFER_REGISTER); /* Handle CD if port is in modem control mode */ if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) { /* Not implemented yet */ DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n"); } /* Byte was read */ return CP_GET_SUCCESS; } } /* Reset LSR, no data was found */ CpReadLsr(Port, 0); return CP_GET_NODATA; }
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte) { /* Check if port is in modem control to handle CD */ while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) { /* Not implemented yet */ DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n"); } /* Wait for LSR to say we can go ahead */ while (!(CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE)); /* Send the byte */ WRITE_PORT_UCHAR(Port->Address + RECEIVE_BUFFER_REGISTER, Byte); }
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte) { /* Check if port is in modem control to handle CD */ // while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // Commented for the moment. if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // To be removed when this becomes implemented. { /* Not implemented yet */ // DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n"); } /* Wait for LSR to say we can go ahead */ while ((CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE) == 0x00); /* Send the byte */ WRITE_PORT_UCHAR(Port->Address + TRANSMIT_HOLDING_REGISTER, Byte); }