?? digi.cpp
字號:
// the appropriate bit from the MSR and return a boolean value
// to the calling program.
int DigiBoard::Cd( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
return ( r.h.al & MSR_CD ) != 0;
}
int DigiBoard::Ri( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
return ( r.h.al & MSR_RI ) != 0;
}
int DigiBoard::Cts( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
return ( r.h.al & MSR_CTS ) != 0;
}
int DigiBoard::Dsr( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
return ( r.h.al & MSR_DSR ) != 0;
}
// Like the modem status functions, the four line status functions
// use BIOS function 3 to read the LSR from the UART, then mask
// off the appropriate bits and return a logical true or false to
// the calling program.
int DigiBoard::ParityError( int reset )
{
union REGS r;
int status;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
status = ( line_status & LSR_PARITY_ERROR ) != 0;
if ( reset != UNCHANGED && reset != 0 )
line_status &= ~LSR_PARITY_ERROR;
return status;
}
int DigiBoard::BreakDetect( int reset )
{
union REGS r;
int status;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
status = ( line_status & LSR_BREAK_DETECT ) != 0;
if ( reset != UNCHANGED && reset != 0 )
line_status &= ~LSR_BREAK_DETECT;
return status;
}
int DigiBoard::FramingError( int reset )
{
union REGS r;
int status;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
status = ( line_status & LSR_FRAMING_ERROR ) != 0;
if ( reset != UNCHANGED && reset != 0 )
line_status &= ~LSR_FRAMING_ERROR;
return status;
}
int DigiBoard::HardwareOverrunError( int reset )
{
union REGS r;
int status;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 3;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
status = ( line_status & LSR_OVERRUN_ERROR ) != 0;
if ( reset != UNCHANGED && reset != 0 )
line_status &= ~LSR_OVERRUN_ERROR;
return status;
}
// The five handshaking and modem control functions are all
// basically lazy. They modify a the appropriate value in
// the settings member, then call write_settings() to do the
// real work.
int DigiBoard::XonXoffHandshaking( int setting )
{
if ( setting != UNCHANGED ) {
settings.XonXoff = ( setting != 0 );
write_settings();
}
return settings.XonXoff;
}
int DigiBoard::RtsCtsHandshaking( int setting )
{
if ( setting != UNCHANGED ) {
settings.RtsCts = ( setting != 0 );
write_settings();
}
return settings.RtsCts;
}
int DigiBoard::DtrDsrHandshaking( int setting )
{
if ( setting != UNCHANGED ) {
settings.DtrDsr = ( setting != 0 );
write_settings();
}
return settings.DtrDsr;
}
int DigiBoard::Dtr( int setting )
{
if ( setting != UNCHANGED ) {
settings.Dtr = ( setting != 0 );
write_settings();
}
return ( settings.Dtr != 0 );
}
int DigiBoard::Rts( int setting )
{
if ( setting != UNCHANGED ) {
settings.Rts = ( setting != 0 );
write_settings();
}
return ( settings.Rts != 0 );
}
// DigiBoard only lets us peek ahead by one byte into the
// input buffer. If there is a character there, this function
// reads it in and stores it in the appropriate place.
int DigiBoard::PeekBuffer( void *buffer, unsigned int count )
{
union REGS r;
if ( count ) {
r.h.ah = 3;
r.x.dx = port_name;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
if ( r.h.ah & 0x80 )
return RS232_ERROR;
if ( r.h.ah & 1 ) {
r.h.ah = 0x14;
r.x.dx = port_name;
int86( 0x14, &r, &r );
line_status |= r.h.ah;
*( (char *) buffer ) = r.h.al;
ByteCount = 1;
} else
ByteCount = 0;
}
return RS232_SUCCESS;
}
// These functions all use private digiboard INT 14 calls to
// return buffer counts. The only complication is that there
// is no direct way to determine the RX space free. It has to
// be calculated indirectly as the RX buffer size - the buffer
// space used.
int DigiBoard::TXSpaceUsed( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 0xfd;
r.h.al = 1;
int86( 0x14, &r, &r );
return( r.x.cx );
}
int DigiBoard::TXSpaceFree( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 0x12;
int86( 0x14, &r, &r );
return r.x.ax;
}
int DigiBoard::RXSpaceUsed( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 0x0a;
int86( 0x14, &r, &r );
return r.x.ax;
}
int DigiBoard::RXSpaceFree( void )
{
union REGS r;
int buffer_size;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 0x1b;
r.h.al = 1;
int86( 0x14, &r, &r );
buffer_size = r.x.bx;
r.h.ah = 10;
r.x.dx = port_name;
int86( 0x14, &r, &r );
return( buffer_size - r.x.ax );
}
// DigiBoard provides two private INT 14 calls to handle flushing
// the TX and RX buffers.
int DigiBoard::FlushRXBuffer( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 0x10;
int86( 0x14, &r, &r );
return RS232_SUCCESS;
}
int DigiBoard::FlushTXBuffer( void )
{
union REGS r;
if ( error_status < RS232_SUCCESS )
return error_status;
r.x.dx = port_name;
r.h.ah = 0x11;
int86( 0x14, &r, &r );
return RS232_SUCCESS;
}
int DigiBoard::FormatDebugOutput( char *buffer, int line_number )
{
union REGS r;
if ( buffer == 0 )
return( first_debug_output_line + 4 );
if ( line_number < first_debug_output_line )
return RS232::FormatDebugOutput( buffer, line_number );
switch( line_number - first_debug_output_line ) {
case 0 :
r.x.dx = port_name;
r.h.ah = 6;
r.h.al = 1;
int86( 0x14, &r, &r );
sprintf( buffer,
"Derived class: DigiBoard Boards/Channels: %2d/%2d "
"Ver: %2x.%02x 1st Port: COM%-2d",
r.x.cx,
r.x.ax,
r.h.bh, r.h.bl,
r.x.dx + 1 );
break;
case 1 :
ParityError( UNCHANGED );
sprintf( buffer,
"Parity Err: %d "
"Break Det: %d "
"Overrun Err: %d "
"Framing Err: %d ",
( line_status & LSR_PARITY_ERROR ) ? 1 : 0,
( line_status & LSR_BREAK_DETECT ) ? 1 : 0,
( line_status & LSR_OVERRUN_ERROR ) ? 1 : 0,
( line_status & LSR_FRAMING_ERROR ) ? 1 : 0 );
break;
case 2 :
sprintf( buffer,
"Buffer Counts: RX Used/Free: %5u/%5u "
"TX Used/Free: %5u/%5u",
RXSpaceUsed(),
RXSpaceFree(),
TXSpaceUsed(),
TXSpaceFree() );
break;
case 3 :
sprintf( buffer,
"RI: %2d CD: %2d CTS: %2d DSR: %2d",
Ri(), Cd(), Cts(), Dsr() );
break;
default :
return RS232_ILLEGAL_LINE_NUMBER;
}
return RS232_SUCCESS;
}
char * DigiBoard::ErrorName( int error )
{
if ( error < RS232_NEXT_FREE_ERROR && error >= RS232_ERROR )
return RS232::ErrorName( error );
if ( error < RS232_NEXT_FREE_WARNING && error >= RS232_WARNING )
return RS232::ErrorName( error );
if ( error >= RS232_SUCCESS )
return RS232::ErrorName( error );
switch ( error ) {
case DIGIBOARD_DRIVER_NOT_FOUND : return( "Driver not found" );
default : return( "Undefined error" );
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -