/* ----------------------------------------------------------- */

/* demo 6 : test RS-232 port (single VXC-112A + PC-COM1)       */

/* step 1 : RS-232 port of vxc112A connect to COM1 of PC       */

/* step 2 : run DEMO6.EXE		                   		       */

/* NOTE   : PC_COM1:send=polling, receive=polling	           */

/*	        Vxc112A:send=polling, receive=interrupt	           */

/* ----------------------------------------------------------- */



#include "..\PIO.H"

#include "..\VxCard.h"



#define COM1	  0x3f8

#define COM2	  0x2f8

#define COM3	  0x3e8

#define COM4	  0x2e8



#define A1_8259   0x20

#define A2_8259   0xA0

#define EOI	      0x20



WORD init_low();

WORD restore_int();

void interrupt (*oldfunc) ();

static void interrupt irq_service();

int  rs232_val, rs232_statusA, irqmask;



#define MAX_NUM  5



WORD wBase, wIrq, wA1;

WORD wT=32000;

/* -------------------------------------------------------------- */

void interrupt irq_service()

{

	rs232_statusA=1;

	rs232_val=inportb(wA1);

	if (wIrq>=8) outportb(A2_8259,0x20);

	outportb(A1_8259,0x20);

}





int main()

{

	int   t,tt,i,j,ii,jj,k;

	int   iRet;

	WORD  wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;

	WORD  wBoards,wRetVal, t1, t0,tt0,tt1;



	clrscr();



	/* step 1: find address-mapping of PIO/PISO cards		  */

	wRetVal=PIO_DriverInit(&wBoards,0x1D61,0x00,0x00);  /* for VXC-112A */

	printf("\nThrer are %d VXC-112A Cards in this PC; Ret=%d",wBoards, wRetVal);

	if (wBoards==0) return 1;



	printf("\n--------------- The Configuration Space ---------------");

	for(i=0; i<wBoards; i++)

	{

		PIO_GetConfigAddressSpace(i,&wBase,&wIrq,&wSubVendor,&wSubDevice,

					&wSubAux,&wSlotBus,&wSlotDevice);

		printf("\nCard_%d: wBase=%x,wIrq=%x,subID=[%x,%x],SlotID=[%x,%x]",

					i,wBase,wIrq,wSubVendor,wSubDevice,wSlotBus,wSlotDevice);

		printf(" --> ");

		ShowPioPiso(wSubVendor,wSubDevice,wSubAux);

	}



	PIO_GetConfigAddressSpace(0,&wBase,&wIrq,&wSubVendor,&wSubDevice,

					&wSubAux,&wSlotBus,&wSlotDevice);



	/* step 2: enable all D/I/O port */

	outportb(wBase,1);				            /* enable D/I/O  */

	Vxc_SetConfig(wBase, VXC_112A_CONFIG);      /* for VXC-112A  */

	Vxc_SetLed(   wBase, VXC_112A_LED_ON); 	    /* led on	     */



	Vxc_SetSpeedMode(wBase, 0, VXC_LOW_SPEED);

	Vxc_SetSpeedMode(wBase, 1, VXC_LOW_SPEED);  /* low speed	 */

	init_low();

	printf("\ninit 1");

	//printf("\ninit 2\n");



	/* step 3: select port  */

	printf("\nPlease select 1:Port1, or other keys:Port2\n");

	wA1 = wBase + ( '1' == getch()? VXC_PORT1 : VXC_PORT2 );

	printf("wBase=0x%x, wPort=0x%x\n", wBase, wA1);



	iRet=Vxc_OpenCom(wA1,115200L, "8N1");      /* RS-232 of VXC-112A=115200	   */

	if (iRet==0) printf("\n\n(1) Open card_0 OK");

	else         printf("\niRET=%d",iRet);



	iRet= Vxc_OpenCom(COM1, 115200L, "8N1");   /* RS_232 of PC-COM1=115200	   */

	if (iRet==0) printf("\n\n(2) Open PC COM OK");

	else         printf("\niRET=%d",iRet);



	outportb(wA1+VXC_IER, 1);   // Enable UART Interrupt



	i=0x55; j=0xaa; rs232_statusA=0;

	for (;;)

	{

		t0=0; t1=0; tt0=0; tt1=0;

		for (;;)

		{

			if (t0<MAX_NUM)

			{

				if ( 0 == Vxc_SendChar(COM1, i, 2) )  /* pc-send=polling */

				{

					t0++;

					//printf("PC Sending i=0x%x\n", i);

				}

			}



			if (t1<MAX_NUM)

			{

				if ( 0 == Vxc_SendChar(wA1, j, 2) ) /* Vxc-112A-send=polling */

				{

					t1++;

					//printf("Card Sending j=0x%x", j);

				}

			}



			for (k=0; k<10000; k++) ;



			if ( 0 == Vxc_ReceiveChar(COM1, &k, 2) ) /* pc-receive=polling */

			{

				if (k!=j) {

					printf("[Err0,%2x,%2x]",k,j);

					return 1;

				}

				tt0++;

				//printf(", PC Receiving k=0x%x\n", k);

			}



			if (rs232_statusA==1)		// vxc-112A-receive=interrupt

			{

				k=rs232_val;

				rs232_statusA=0;

				if (k!=i) {

					printf("[Err1,%2x,%2x]",k,i);

					return 1;

				}

				tt1++;

				//printf(", Card Receiving k=0x%d\n", k);

			}



			if ((tt0>=MAX_NUM) && (tt1>=MAX_NUM))

				break;

			if ( kbhit() ) {

				printf("\n\nUser Cancel\n");

				restore_int();

				PIO_DriverClose();

				getch();

				return 2;

			}

		}

		i++; i=i&0xff;

		j++; j=j&0xff;

		if (kbhit()!=0) {getch(); break;}

		printf("\n[%2x, %2x]",i,j);

	}



	restore_int();



	PIO_DriverClose();

	return 0;

}



/* -------------------------------------------------------------- */

WORD init_low()

{

	DWORD dwVal;



	disable();

	outportb(wBase+5,0);			 // disable all interrupt



	if (wIrq<8)

	{

		oldfunc=getvect(wIrq+8);

		irqmask=inportb(A1_8259+1);

		outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq)));

		setvect(wIrq+8, irq_service);

	}

	else

	{

		oldfunc=getvect(wIrq-8+0x70);

		irqmask=inportb(A1_8259+1);

		outportb(A1_8259+1,irqmask & 0xfb);			  // IRQ2

		irqmask=inportb(A2_8259+1);

		outportb(A2_8259+1,irqmask & (0xff ^ (1 << (wIrq-8))));

		setvect(wIrq-8+0x70, irq_service);

	}



	outportb(wBase+0x2a, 12); 	       // non-invert COM1

	outportb(wBase+5, 12);		       // enable DI1 interrupt

	enable();

	return 0;

}



/* -------------------------------------------------------------- */



WORD restore_int()

{

	disable();



	outportb(wBase+5,0);			 /* disable all interrupt */

	if (wIrq<8)

	{

		setvect(wIrq+8,oldfunc);

	} else {

		setvect(wIrq-8+0x70,oldfunc);

	}



	return 0;

}



