/***************************************************************************\
	Modbus RTU/ASCII Master Test Program
		Copyright (c) 2000 Z-World, Inc.
		Copyright (c) 1999, CFControls, Inc.
\***************************************************************************/

#use	"MMZ.LIB"
#use	"VDRIVER.LIB"

#define NUM_SLAVE_COILS 64		// slave coil count may be either 32 or 64

/***************************************************************************\
	Test Program
\***************************************************************************/

/*=========================================================================*\
	Test
		[0x03] Read Holding Registers (pxRead = mmRead)
		[0x04] Read Input Registers (pxRead = mmInput)
		[0x06] Preset Single Register (pxWrite = mmPresetReg)
		[0x10] Preset Multiple Registers (pxWrite = mmPresetRegs)
		[0x17] Read/Write Registers (pxWrite/pxRead = mmRegRdWr)
\*=========================================================================*/
nodebug
void test34x(unsigned wAddr, int (*pxWrite)(), int (*pxRead)())
{
	static unsigned wCnt, wReg, awOut[4], awIn[4];

	for(;;)
	{
		costate
		{
			memset(awOut, 0x00, sizeof(awOut));
			memset(awIn, 0xFF, sizeof(awIn));
			for(wCnt = 0; ; ++wCnt)
			{
				awOut[wReg = wCnt & 3] = wCnt;
				lprintf("\x80%04x %04x %04x %04x", awOut[3], awOut[2], awOut[1],
				 awOut[0]);
				if(pxWrite == mmRegRdWr)
				{
					waitfor(mmRegRdWr(wAddr, 0x0000, 0x0004, awIn, 0x0000, 0x0004,
					 awOut));
				}
				else if(pxWrite == mmPresetReg)
				{
					waitfor(mmPresetReg(wAddr, wReg, awOut[wReg]));
				}
				else if(pxWrite == mmPresetRegs)
				{
					waitfor(mmPresetRegs(wAddr, 0x0000, 0x0004, awOut));
				}
				if(!wAddr)
				{
					waitfor(DelayMs(20));
				}
				waitfor(pxRead(0x01, 0x0000, 0x0004, awIn));
				lprintf("\xC0%04x %04x %04x %04x", awIn[3], awIn[2], awIn[1],
				 awIn[0]);
			}
		}
	}
}

/*=========================================================================*\
	Test
		[0x01] Read Output Coil Status (pxRead = mmOutRd)
		[0x02] Read Input Coils (pxRead = mmIn)
		[0x05] Force Single Coil (pxWrite = mmForceCoil)
		[0x0F] Force Multiple Coils (pxWrite = mmForceCoils)
		[0x16] Mask Write Register
\*=========================================================================*/
nodebug
void test01x(unsigned wAddr, int (*pxWrite)(), int (*pxRead)())
{
	static unsigned wCnt, wReg, awOut[4], awIn[4];
	static unsigned wCoil, wMask;
	static int bState;

	for(;;)
	{
		costate
		{
			memset(awOut, 0x00, sizeof(awOut));
			memset(awIn, 0xFF, sizeof(awIn));
			for(wCnt = 0; ; ++wCnt)
			{
				wCoil = wCnt & 63;
				wReg = wCoil >> 4;
				wMask = 1 << (wCoil & 15);
				if(wCnt & 64)
				{
					awOut[wReg] &= ~wMask;
					bState = 0;
				}
				else
				{
					awOut[wReg] |= wMask;
					bState = 1;
				}
				lprintf("\x80%04x %04x %04x %04x", awOut[3], awOut[2], awOut[1],
				 awOut[0]);
				if(pxWrite == mmRegMask)
				{
					waitfor(mmRegMask(wAddr, wReg, bState ? 0xFFFF : ~wMask,
					 bState ? wMask : 0x0000));
				}
				else if(pxWrite == mmForceCoil)
				{
					waitfor(mmForceCoil(wAddr, wCoil, bState));
				}
				else if(pxWrite == mmForceCoils)
				{
					waitfor(mmForceCoils(wAddr, 0x0000, NUM_SLAVE_COILS, awOut));
				}
				if(!wAddr)
				{
					waitfor(DelayMs(20));
				}
				waitfor(pxRead(0x01, 0x0000, NUM_SLAVE_COILS, awIn));
				lprintf("\xC0%04x %04x %04x %04x", awIn[3], awIn[2], awIn[1],
				 awIn[0]);
			}
		}
	}
}


/*=========================================================================*\
	Main Program
\*=========================================================================*/
//nodebug
main()
{
	VdInit();										// init timer1, call _GLOBAL_INIT()
	lcd_init(0x18);
	lprintf("\xF2");
		
//	mmaZ0(9600, 0);
	mmaZ1(9600, 0);
//	mmrZ0(9600, 0);
//	mmrZ1(9600, 0);

	test01x(0x01, mmForceCoil, mmOutRd);	// Test Output Coil Read/Write

//	test01x(0x00, mmForceCoil, mmOutRd);	// Test Broadcast Coil Write
//	test01x(0x01, mmForceCoil, mmIn);		// Test Input Coil Read
//	test01x(0x01, mmForceCoils, mmOutRd);	// Test Output Coils Write
//	test01x(0x01, mmRegMask, mmOutRd);		// Test Output Coil Mask Write
		
//	test34x(0x01, mmPresetReg, mmRead);		// Test 4x Reg Read/Write
//	test34x(0x00, mmPresetReg, mmRead);		// Test Broadcast 4x Reg Write
//	test34x(0x01, mmPresetReg, mmInput);	// Test Input Reg Read
//	test34x(0x01, mmPresetRegs, mmRead);	// Test 4x Reg Writes
//	test34x(0x01, mmRegRdWr, mmRegRdWr);	// Test 4x Reg Read/Write
}
