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

📄 serdos.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#ifndef ZDP
   #define ZDP
#endif

#include <dos.h>
#include <conio.h>
#include <stddef.h>
#include "trpimp.h"
#include "trperr.h"
#include "dosequip.h"
#include "serial.h"
#include "tinyio.h"

#define I8259  0x20 /* 8259 control register address */
#define I8259M  0x21 /* 8259 mask register */
#define EOI  0x20 /* 8259 end of interrupt command */
#define EOI_COM  (0x60+IntVector) /* specific level EOI */

#define IER  (IOBase+1) /* interrupt enable register address */
#define IIR  (IOBase+2) /* interrupt identification register address */
#define LCR  (IOBase+3) /* line control register address */
#define MCR  (IOBase+4) /* modem control register address */
#define LSR  (IOBase+5) /* line status register address */
#define MSR  (IOBase+6) /* modem status register address */

#define LCR_SETUP   0x03 /* set 8 bits, no parity, 1 stop */
#define LCR_DLAB    0x80 /* divisor latch access bit */
#define MCR_DTR     0x01 /* Data Terminal Ready control */
#define MCR_RTS     0x02 /* Request To Send control */
#define MCR_OUT2    0x08 /* out2 control bit */
#define MCR_SETUP   ( MCR_OUT2 | MCR_RTS | MCR_DTR )

#define LSR_DRDY  0x01 /* data ready */
#define LSR_ORUN  0x02 /* overrun error */
#define LSR_PRTY  0x04 /* parity error */
#define LSR_FRM   0x08 /* framing error */
#define LSR_BRK   0x10 /* break interrupt */
#define LSR_THRE  0x20 /* transmit holding register empty */
#define LSR_TSRE  0x40 /* transmit shift register empty */
#define LSR_ERR   (LSR_FRM+LSR_PRTY+LSR_ORUN) /* error conditions */

#define MSR_CTS         0x10 /* Clear To Send */
#define MSR_DSR         0x20 /* Data Set Ready */

#define BREAK_TIME      4

int IOBase; /* base com port address */
int IntVector; /* com interrupt vector to use */
int ErrorFlag;
int BreakFlag;

static int I8259mBit;
static int CurrentBaud;
static char Modem;
unsigned Ticks;

extern void ClearBuffer( void );
extern int GetBufferByte( void );
extern void Wait( int );
extern void InitInts( void );
extern void FiniInts( void );


void ZeroWaitCount( void )
{
    Ticks = 0;
}


unsigned WaitCount( void )
{
    return( Ticks );
}


char *InitSys( void )
{
    int i8259_val;                  /* storing I8259 value */
    int i8259m_val;                 /* storing I8259 mask register value */

    inp( IOBase );                 /* base com port: clear any characters */
    outp( IER, 0 );                /* ier <= 0 : no ints for now */
    inp( MSR );                    /* MSR : reset MSR now */

    InitInts();

    outp( LCR, LCR_SETUP );                /* set com line characteristics */
    outp( MCR, MCR_SETUP );                /* set MCR value */
    outp( IER, 0x05 );                     /* set ier, allow lsr & rx ints */

    _disable();
    i8259m_val = inp( I8259M );            /* set 8259 mask register    */
    I8259mBit = i8259m_val & ( 1 << IntVector );
    i8259m_val &= ~( 1 << IntVector );    /*    to allow com interrupts */
    outp( I8259M, i8259m_val );
    _enable();
    i8259_val = IntVector;                 /* set 8259 priority */
    --i8259_val;
    i8259_val |= 0xc0;
    outp( I8259, i8259_val );
    CurrentBaud = -1;
    Modem = 0;
    return( NULL );
}


void ResetSys( void )
{
    int i8259m_val;         /* storing I8259 mask register value */

    outp( I8259, 0xc7 );              /* reset normal 8259 priority */

    i8259m_val = inp( I8259M );               /* set 8259 mask register  */
    i8259m_val |= I8259mBit;                  /*  to previous status for */
    outp( I8259M, i8259m_val );               /*  com:-level interrupts  */

    outp( IER, 0 );                   /* ier <= 0 : all ints off */
    outp( MCR, 0 );                   /* MCR : set OUT2 & DTR off */

    FiniInts();
}


void SendByte( int value )
{
    do {
        ;
    } while( (inp( LSR ) & LSR_THRE) == 0 );
    if( Modem ) {
        /* talking over a modem - check the data set ready line */
        do {
            ;
        } while( (inp( MSR ) & MSR_CTS) == 0 );
    }
    outp( IOBase, value );
}

void StartBlockTrans( void )
{
}

void StopBlockTrans( void )
{
    if( Modem ) {
        /* talking over a modem - check the data set ready line */
        do {
            ;
        } while( (inp( MSR ) & MSR_CTS) == 0 );
    }
}

int GetByte( void )
{
    return( GetBufferByte() );
}


void ClearCom( void )
{
    ClearBuffer();
}


void SendABreak( void )
{
    int lcr_value;             /* storing line control register value */

    lcr_value = inp( LCR );                /* LCR contents */
    outp( LCR, lcr_value | 0x40 );         /* set break bit on */
    SendByte( 0 );                         /* interrupt other side */
    Wait( BREAK_TIME );                    /* hold it there */
    lcr_value &= (~0x40);                  /* assure break bit is off */
    outp( LCR, lcr_value );                /* restore lcr content */
}

bool TestForBreak( void )
{
    _disable();
    if( BreakFlag || ( inp(LSR) & LSR_BRK ) ) {
        BreakFlag = 0;
        _enable();
        return( TRUE );
    }
    _enable();
    return( FALSE );
}


int Divisor[] = { 1, 2, 3, 6, 12, 24, 48, 96, 0 };

bool Baud( int index )
{
    int lcr_value;

    ErrorFlag = 0;
    BreakFlag = 0;
    if( index == MIN_BAUD ) {
        Modem = 1;
        return( TRUE );
    }
    Modem = 0;
    if( index == CurrentBaud ) return( TRUE );

    /* don't change baud rate while a character is still being sent */
    do {} while( (inp( LSR ) & LSR_TSRE) == 0 );
    lcr_value = inp( LCR );              /* get LCR value */
    _disable();                          /* disable interrupt */
    outp( LCR, lcr_value | LCR_DLAB );   /* set Divisor Latch Access Bit(DLAB)*/
                                         /*  to enable setting of baud rate */
    outp( IOBase, Divisor[index] );      /* LSB portion of new divisor */
    outp( IOBase+1, 0 );                 /* MSB portion of new divisor */
    lcr_value = inp( LCR );
    outp( LCR, lcr_value & ~LCR_DLAB );  /* set off DLAB bit of LCR */
    _enable();                           /* re-enable interrupts */
    CurrentBaud = index;
    return( TRUE );
}

char *ParsePortSpec( char * *spec )
{
    char    *parm;
    int     port;

    parm = (spec == NULL) ? "" : *spec;

    switch( *parm ) {
    case '1':
        ++parm;
        /* fall through */
    case '.':
    case '\0':
        port = 0;
        IntVector = 4;
        IOBase = 0x3f8;
        break;
    case '2':
        ++parm;
        port = 1;
        IntVector = 3;
        IOBase = 0x2f8;
        break;
    default:
        return( TRP_ERR_invalid_serial_port_number );
    }
    if( *parm != '\0' && *parm != '.' ) return( TRP_ERR_invalid_serial_port_number );
    if( port >= Equipment().num_rs232s ) return( TRP_ERR_serial_port_does_not_exist );
    if( spec != NULL ) *spec = parm;
    return( NULL );
}


void DonePort( void )
{
}


bool CheckPendingError( void )
{
    int old_error;

    _disable();
    old_error = ErrorFlag;
    ErrorFlag = 0;
    _enable();
    return( old_error != 0 );
}


void ClearLastChar( void )
{
    /* wait for last character to be sent */
    do {
        ;
    } while( (inp( LSR ) & LSR_TSRE) == 0 );
}

⌨️ 快捷键说明

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