📄 stdcom.cpp
字号:
#include <dos.h>
#include <string.h>
#include <stdio.h>
#include <alloc.h>
#include "StdCom.h"
#define __CPPARGS ...
BYTE COM2 = 0x0b; // Interrupt vector
WORD PORT2 = 0x2f8 ; // Port address
struct TranslateStruct Com2Send ;
struct TranslateStruct Com2Receive ;
// Save COM interrupt address
void interrupt (* OldCOM2Handler) (__CPPARGS) ;
// New COM interrupt address
void interrupt COM2Handler (__CPPARGS) ;
void Com2InterruptReceive (void) ;
void Com2InterruptSend (void) ;
void interrupt COM2Handler (__CPPARGS)
{
asm cli
int intstatus ;
intstatus = inportb (PORT2 + 2) ;
while (! (intstatus & 0x1))
{
if (intstatus == 4)
Com2InterruptReceive ( ) ;
if (intstatus == 2)
Com2InterruptSend ( ) ;
intstatus = inportb(PORT2 + 2);
}
asm mov al, 20h
asm out 20h, al
asm sti
}
void Com2InterruptReceive (void)
{
// Read receive data into receive buffer
Com2Receive.Buffer [Com2Receive.Counter] = inportb (PORT2) ;
Com2Receive.Counter ++ ; // Adjust Receive counter
if(Com2Receive.Counter >= MaxLength)
Com2Receive.Counter = 0 ;
}
void Com2InterruptSend (void)
{
// Send data interrupt process
outportb (PORT2, Com2Send.Buffer [Com2Send.Counter]) ;
Com2Send.Counter ++ ;
if(Com2Send.Counter >= Com2Send.Length)
{
outportb (PORT2 + 1,0x01);
Com2Send.Length = 0;
Com2Send.Counter = 0 ;
}
}
CStdCOM :: CStdCOM (int comId=1, long baud=9600, BYTE mode=0x03)
{
ComId = comId ;
Baud = baud ;
Mode = mode;
//------------add by cfy 98.8.28
if (ComId == 1)
{
}
else
{
OldCOM2Handler = getvect(COM2); // save the old interrupt vector
setvect(COM2, COM2Handler); // install the new interrupt handler
Old8250IntMask = inportb (0x21) ;
}
//------------------------add end------------------------
}
CStdCOM :: ~CStdCOM ( )
{
CloseComm ( );
}
CStdCOM :: CloseComm ( )
{
if (ComId == 1)
{
}
else
{
// reset the old interrupt handler
setvect(COM2, OldCOM2Handler);
outportb (0x21, Old8250IntMask) ;
}
return 0 ;
}
/*
Function : Initinate COM1 or COM2 port : 8 data bits, 1 stop bit ,
no check bit . Baud is enable to choose .
Working with interrupts mode, there is two kind of interrupt
mode : receive and send .
Enter parameters :
Port : COM start port : 0x2F8 or 0x3F8 */
//void CStdCOM :: InitComm (void) change by cfy 98.8.28
void CStdCOM :: InitComm (WORD combaud)
{
Baud=combaud;
int Port ;
if (ComId == 1)
{
}
else
{
memset (&Com2Receive, 0, sizeof (struct TranslateStruct));
memset (&Com2Send, 0, sizeof (struct TranslateStruct));
Port = PORT2 ;
}
inportb (Port);
disable ( );
BYTE highbyte,lowbyte;
WORD baud;
if (Baud != 0) baud=(WORD)((long)(300L*0x180L)/Baud);
highbyte = baud >> 8;
lowbyte = baud & 0xff;
disable();
outportb (Port + 3, Mode) ;
outportb (0x21, 0x0ff) ;
Com2Send.Length = 0 ;
Com2Send.Counter = 0 ;
Com2Receive.Length = 0 ;
Com2Receive.Counter = 0 ;
Com2Receive.FetchCounter = 0 ;
outportb (Port + 1, 0x01) ;
// Set interrupt enable register Addres : COM1 : 3F9 COM2 : 2F9
outportb (Port + 4, 0x0b) ;
// Set MODEM control register enable Address : COM1 : 3FC COM2 : 2FC
outportb (Port + 3, 0x80) ;
// Set DLAB = 1
// Set translation control register Addres : COM1 : 3FB COM2 : 2FB
outportb (Port + 1, highbyte) ;
// Set Baud register high byte Addres : COM1 : 3F9 COM2 : 2F9
outportb (Port, lowbyte) ;
// Set Baud register low byte Addres : COM1 : 3F8 COM2 : 2F8
outportb (Port + 3, Mode) ;
// outportb (Port + 3, 0x07) ;
// Set data format : 1 stop bit 8 data bits
// Addres : COM1 : 3FB COM2 : 2FB
// DataBITS: Bit1 Bit0 = 00 5Bits; = 10 6Bits; = 01 7Bits; = 11 8Bits.
// StopBITS: Bit2 = 0 1Bits; = 1 2Bits.
// Check: Bit5 Bit4 Bit4 = 000 NONE; = 100 ODD ; = 110 EVEN;
// = 101 MARK; = 111 SPACE.
outportb (0x21, 0x0) ;
inportb(Port);
inportb(Port);
enable ( ) ;
}
int CStdCOM:: StdComSendData (BYTE * buf, int length)
{
if(ComId == 1)
{
}
else
{
if (Com2Send.Counter < Com2Send.Length)
return 1 ; // All Data is not sent yet
if (length >= MaxLength || length <= 0)
return 2 ; // Data is too long or < 0
for(int i = 0; i < length; i ++) // Store data into send buffer
Com2Send.Buffer[i] = buf [i] ;
Com2Send.Length = length ; // Set Send length
Com2Send.Counter = 0 ; // Clear Send counter
outportb (PORT2 + 1, 0x03) ; // Open Send enable register
}
return 0 ; // Send sucessfully
}
int CStdCOM :: ReadData (BYTE * buf)
{
struct TranslateStruct * pRecv;
if (ComId == 2)
pRecv = & Com2Receive ;
int i=0;
asm cli
while(pRecv->FetchCounter != pRecv->Counter)
{
buf [i] = pRecv->Buffer [pRecv->FetchCounter] ;
i ++ ;
pRecv->FetchCounter ++ ;
if (pRecv->FetchCounter >= MaxLength)
pRecv->FetchCounter = 0 ;
}
asm sti
return i ;
}
void CStdCOM :: ClearBuffer (int flag)
{
asm cli
if (ComId == 1)
{
}
else
{
if(flag==0)
{
Com2Receive.Length = 0 ;
Com2Receive.Counter = 0 ;
Com2Receive.FetchCounter = 0 ;
outportb (PORT2 + 1, 0x01) ;
}
else if(flag==1)
{
Com2Send.Length = 0 ;
Com2Send.Counter = 0 ;
outportb (PORT2 + 1, 0x01) ;
}
else if(flag==2)
{
Com2Receive.Length = 0 ;
Com2Receive.Counter = 0 ;
Com2Receive.FetchCounter = 0 ;
Com2Send.Length = 0 ;
Com2Send.Counter = 0 ;
outportb (PORT2 + 1, 0x01) ;
inportb(PORT2);
}
}
asm sti
}
int CStdCOM :: ReceiveChar (BYTE * cBuf)
{
struct TranslateStruct * pRecv;
if (ComId == 2)
pRecv = &Com2Receive ;
if (pRecv->FetchCounter == pRecv->Counter)
return 0 ;
asm cli
*cBuf = pRecv->Buffer [pRecv->FetchCounter] ;
pRecv->FetchCounter ++ ;
if (pRecv->FetchCounter >= MaxLength)
pRecv->FetchCounter = 0 ;
asm sti
return 1 ;
}
int CStdCOM :: SendBlock (BYTE * buf, int length)
{
while (1)
{
if (StdComSendData (buf, length) == 0)
return length;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -