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

📄 com.h

📁 c游戏编程从入门到精通_全部源代码和文档
💻 H
字号:
// D E F I N E S  ////////////////////////////////////////////////////////////
#ifdef __cplusplus
    #define __CPPARGS ...
#else
    #define __CPPARGS
#endif
// registers in UART

#define SER_RBF        0    // the read buffer
#define SER_THR        0    // the write buffer
#define SER_IER        1    // the int. enable register
#define SER_IIR        2    // the int. identification register
#define SER_LCR        3    // control data config. and divisor latch
#define SER_MCR        4    // modem control reg.
#define SER_LSR        5    // line status reg.
#define SER_MSR        6    // modem status of cts, ring etc.
#define SER_DLL        0    // the low byte of baud rate divisor
#define SER_DLH        1    // the hi byte of divisor latch

// bit patterns for control registers

#define SER_BAUD_1200  96   // baud rate divisors for 1200 baud - 19200
#define SER_BAUD_2400  48
#define SER_BAUD_9600  12
#define SER_BAUD_19200  6

#define SER_GP02        8     // enable interrupt

#define COM_1           0x3F8 // base port address of port 0
#define COM_2           0x2F8 // base port address of port 1

#define SER_STOP_1      0     // 1 stop bit per character
#define SER_STOP_2      4     // 2 stop bits per character

#define SER_BITS_5      0     // send 5 bit characters
#define SER_BITS_6      1     // send 6 bit characters
#define SER_BITS_7      2     // send 7 bit characters
#define SER_BITS_8      3     // send 8 bit characters

#define SER_PARITY_NONE 0     // no parity
#define SER_PARITY_ODD  8     // odd parity
#define SER_PARITY_EVEN 24    // even parity

#define SER_DIV_LATCH_ON 128  // used to turn reg 0,1 into divisor latch

#define PIC_IMR    0x21   // pic's interrupt mask reg.
#define PIC_ICR    0x20   // pic's interupt control reg.

#define INT_SER_PORT_0    0x0C  // port 0 interrupt com 1 & 3
#define INT_SER_PORT_1    0x0B  // port 0 interrupt com 2 & 4

#define SERIAL_BUFF_SIZE 128    // current size of circulating receive buffer

// G L O B A L S /////////////////////////////////////////////////////////////

void interrupt far (*Old_Isr)(__CPPARGS);  // holds old com port interrupt handler

char ser_buffer[SERIAL_BUFF_SIZE];  // the receive buffer

int ser_end = -1,ser_start=-1;      // indexes into receive buffer
int ser_ch, char_ready=0;           // current character and ready flag
int old_int_mask;                   // the old interrupt mask on the PIC
int open_port;                      // the currently open port
int serial_lock = 0;                // serial ISR semaphore so the buffer
				    // isn't altered will it is being written
                                    // to by the ISR

//////////////////////////////////////////////////////////////////////////////

void interrupt far Serial_Isr(__CPPARGS)
{

// this is the ISR (Interrupt Service Routine) for the com port.  It is very
// simple.  When it gets called, it gets the next character out of the receive
// buffer register 0 and places it into the software buffer. Note: C takes care
// of all the register saving and house work.  Cool huh!

// lock out any other functions so the buffer doesn't get corrupted

serial_lock = 1;

// place character into next position in buffer

ser_ch = inp(open_port + SER_RBF);

// wrap buffer index around

if (++ser_end > SERIAL_BUFF_SIZE-1)
    ser_end = 0;

// move character into buffer

ser_buffer[ser_end] = ser_ch;

++char_ready;

// restore PIC

outp(PIC_ICR,0x20);

// undo lock

serial_lock = 0;

} // end Serial_Isr

//////////////////////////////////////////////////////////////////////////////

int Ready_Serial()
{

// this functions returns true if there are any characters waiting and 0 if
// the buffer is empty

return(char_ready);

} // end Ready_Serial

//////////////////////////////////////////////////////////////////////////////

int Serial_Read()
{

// this function reads a character from the circulating buffer and returns it
// to the caller

int ch;

// wait for isr to end

while(serial_lock){}

// test if there is a character(s) ready in buffer

if (ser_end != ser_start)
   {

   // wrap buffer index if needed

   if (++ser_start > SERIAL_BUFF_SIZE-1)
       ser_start = 0;

   // get the character out of buffer

   ch = ser_buffer[ser_start];

   // one less character in buffer now

   if (char_ready > 0)
       --char_ready;

   // send data back to caller

   return(ch);

   } // end if a character is in buffer
else
   // buffer was empty return a NULL i.e. 0
   return(0);

} // end Serial_read

//////////////////////////////////////////////////////////////////////////////

Serial_Write(char ch)
{

// this function writes a character to the transmit buffer, but first it
// waits for the transmit buffer to be empty.  note: it is not interrupt
// driven and it turns of interrupts while it's working

// wait for transmit buffer to be empty

while(!(inp(open_port + SER_LSR) & 0x20)){}

// turn off interrupts for a bit

asm cli

// send the character

outp(open_port + SER_THR, ch);

// turn interrupts back on

asm sti

} // end Serial_Write

//////////////////////////////////////////////////////////////////////////////

Open_Serial(int port_base, int baud, int configuration)
{

// this function will open up the serial port, set it's configuration, turn
// on all the little flags and bits to make interrupts happen and load the
// ISR

// save the port for other functions

open_port = port_base;

// first set the baud rate

// turn on divisor latch registers

outp(port_base + SER_LCR, SER_DIV_LATCH_ON);

// send low and high bytes to divsor latches

outp(port_base + SER_DLL, baud);
outp(port_base + SER_DLH, 0);

// set the configuration for the port

outp(port_base + SER_LCR, configuration);

// enable the interrupts

outp(port_base + SER_MCR, SER_GP02);

outp(port_base + SER_IER, 1);

// hold off on enabling PIC until we have the ISR installed

if (port_base == COM_1)
   {
   Old_Isr = _dos_getvect(INT_SER_PORT_0);
   _dos_setvect(INT_SER_PORT_0, Serial_Isr);
   printf("\nOpening Communications Channel Com Port #1...\n");

   }
else
   {
   Old_Isr = _dos_getvect(INT_SER_PORT_1);
   _dos_setvect(INT_SER_PORT_1, Serial_Isr);
   printf("\nOpening Communications Channel Com Port #2...\n");
   }

// enable interrupt on PIC

old_int_mask = inp(PIC_IMR);

outp(PIC_IMR, (port_base==COM_1) ? (old_int_mask & 0xEF) : (old_int_mask & 0xF7 ));

} // Open_Serial

//////////////////////////////////////////////////////////////////////////////

Close_Serial(int port_base)
{

// this function closes the port which entails turning off interrupts and
// restoring the old interrupt vector

// disable the interrupts

outp(port_base + SER_MCR, 0);

outp(port_base + SER_IER, 0);

outp(PIC_IMR, old_int_mask );

// reset old isr handler

if (port_base == COM_1)
   {
   _dos_setvect(INT_SER_PORT_0, Old_Isr);
   printf("\nClosing Communications Channel Com Port #1.\n");
   }
else
   {
   _dos_setvect(INT_SER_PORT_1, Old_Isr);
   printf("\nClosing Communications Channel Com Port #2.\n");
   }

} // end Close_Serial

//////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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