#include
#include
#include
#include
#define COM1 0x03f8 /* COM1 port address */
#define COM2 0x02f8 /* COM2 port address */
/* offset the COM addr. */
#define THR 0x0000 /* LCR bit 7=0 */
#define RDR 0x0000 /* LCR bit 7=0 */
#define BRDL 0x0000 /* LCR bit 7=1 */
#define IER 0x0001 /* LCR bit 7=0 */
#define BRDH 0x0001 /* LCR bit 7=1 */
#define IIR 0x0002 /* offset the COM port */
#define LCR 0x0003 /* offset the COM port */
#define MCR 0x0004 /* offset the COM port */
#define LSR 0x0005 /* offset the COM port */
#define MSR 0x0006 /* offset the COM port */
#define pic8259Mask 0x21 /* interrupt mask register */
#define pic8259EOI 0x20 /* interrupt end of register */
#define queSize 100 /* the Queue size */
#define TRUE 1
#define FALSE 0
#define OK 0
#define ERROR 1
#define B2400 0x30
#define B4800 0x18
#define B9600 0x0c
#define B19200 0x06
#define B38400 0x03
#define B57600 0x02
char *inQueSpace, *outQueSpace, *str1;
int inQuePushPt, inQuePopPt, outQuePushPt, outQuePopPt,
queHead=0, queTail=queSize;
unsigned char intVectCom=0x0c; /* COM1=0CH, COM2=0BH */
char FOR[11] = { 'C','\\03','\\01','0','0','X','1','0','6','0','0' };
char REV[11] = { 'C','\\03','\\01','0','0','X','3','0','6','0','0' };
char STOP[11] = { 'C','\\03','\\01','0','0','X','2','0','6','0','0' };
void interrupt newComISR();
void setProtocol(unsigned char numBaud, int comPort, unsigned char charFrame)
{
unsigned char regLCR;
regLCR=inportb(COM1+LCR);
regLCR=regLCR | 0x80; /* set LCR bit 7=1, the addr is for BRDL & BRDH */
outportb(COM1+LCR,regLCR);
outportb(COM1+BRDL,numBaud);
outportb(COM1+BRDH,0x00);
regLCR=regLCR & 0x7f; /* recover LCR bit 7 = 0 */
outportb(COM1+LCR,regLCR);
outportb(COM1+LCR,charFrame);
}
void SendOut( char *CmdData, unsigned char lenStr)
{
unsigned char i, waitCount;
unsigned char regLSR;
for (i=0;i<lenStr;i++)
{
waitCount = 10;
while ( waitCount != 0 )
{
regLSR=inportb(COM1+LSR);
delay(1);
if ( (regLSR & 0x20 ) !=0 )
{
waitCount=0;
putchar(*(CmdData+i));
outportb(COM1+THR,*(CmdData+i));
delay(1);
}
else
{
waitCount--;
/* if ( waitCount == 0 ) printf("\\nError-can not transimit.\\n"); */
}
}
}
}
main()
{
char inChar;
unsigned char waitCount;
int irqMask;
unsigned char regIIR, regIER, regMCR, regLCR, regLSR;
void interrupt (*oldComISR)();
inQueSpace=(char *)malloc(sizeof(char)*queSize);
outQueSpace=(char *)malloc(sizeof(char)*queSize);
printf("\\nVFD-A COMMUNICATION CONTROL PROGRAM");
printf("\\nBaud rate : 4800, 8, 1, Odd, COM1");
printf("\\nOperating Choices : [F] FORWARD RUNNING !");
printf("\\n : [R] REVERSE RUNNING !");
printf("\\n : [S] STOP RUNNING !");
printf("\\n : [Q] QUIT");
printf("\\nCHOICE ? ");
/* save/install interrupt */
oldComISR=getvect(intVectCom);
setvect(intVectCom,newComISR);
/* set protocol */
setProtocol(B4800,COM1,0x0b);
/* communications line on */
disable(); /* interrupts off */
inQuePushPt=0; /* Reset InQue pointers to start of Queue */
inQuePopPt=0;
/* Initial modem control register for data terminal ready
(bit 0), request to send (bit 1) and OUTPUT 2 (bit 3). */
outportb(COM1+MCR,0x0b); /* Bits 0, 1 and 3 set */
/* Set bit 7 of the line control register to access
the interrupt enable register */
regLCR=inportb(COM1+LCR);
delay(1); /* I/O delay */
regLCR=regLCR & 0x7F; /* Reset bit 7 of LCR */
outportb(COM1+LCR,regLCR);
delay(1); /* I/O delay */
/* Enable interrupts for Received data available only */
outportb(COM1+IER,0x01);
delay(1); /* I/O delay */
/* Enable communications interrupts by resetting the bits
corresponding to the IRQ1 and IRQ3 lines on the interrupt mask
register (pic8259Mask) */
irqMask=inportb(pic8259Mask);
delay(1); /* I/O delay */
irqMask=irqMask & 0xf7; /* Reset bit 3 */
outportb(pic8259Mask,irqMask);
delay(1); /* I/O delay */
enable(); /* Reenable interrupt */
/* Flush keyboard buffer of old characters */
while ( bioskey(1) ) bioskey(0);
do
{
if ( bioskey(1) )
{
inChar=bioskey(0);
switch ( inChar & 0xdf )
{
case 'F' : /* FORWARD RUNNING */
putchar('\\n');
cprintf("PC -> VFD-A: ");
SendOut(FOR,11);
break;
case 'R' : /* REVERSE RUNNING */
putchar('\\n');
cprintf("PC -> VFD-A: ");
SendOut(REV,11);
break;
case 'S' : /* STOP RUNNING */
putchar('\\n');
cprintf("PC -> VFD-A: ");
SendOut(STOP,11);
break;
}
}
}
while ( (inChar & 0xdf) != 'Q');
/* communications line off */
/* Disable communications interrupts by settings bit for IRQ3
line on the interrupt mask register */
irqMask=inportb(pic8259Mask);
irqMask=irqMask | 0x08; /* Set bit 3 */
delay(1); /* I/O delay */
}
void interrupt newComISR() /* ISR */
{
unsigned char regIIR, regLSR, regRDR;
unsigned char DATA_CHECK;
disable();
DATA_CHECK=FALSE;
/* Check line status register for reception error and data ready */
do
{
regLSR=inportb(COM1+LSR);
delay(1); /* I/O delay */
if ( (regLSR & 0x01) != 0 )
{
DATA_CHECK=FALSE;
regRDR=inportb(COM1+RDR);
delay(1);
regRDR=regRDR & 0x7F;
}
else
{
if ( (regLSR & 0x1E) == 0 ) DATA_CHECK=TRUE;
else regRDR='?';
}
}
while ( DATA_CHECK );
*(inQueSpace+inQuePushPt)=regRDR;
inQuePushPt++;
if (inQuePushPt == 20) inQuePushPt=0;
/* Signal end-of-interrupt to the interrupt command register */
outportb(pic8259EOI,0x20);
delay(1); /* I/O delay */
enable();
}