#pragma num_alias_table_entries	14
#include 
#define DAC_address 0x21

IO_0 output frequency clock(3) io_sound;
IO_1 output bitshift numbits(8) clockedge(+) io_com_data;
IO_3 output bit en;

IO_4 input infrared ded clock (2) io_ir;
IO_4 input bit io_ir_level;
IO_5 input bit up;
IO_6 input bit down;
IO_7 input bit enter;
IO_8 input bit esc;

network output SNVT_switch nvo_lighting[4];
network output SNVT_count nvo_no_lighting;
network output SNVT_count nvo_no_blind;
network output SNVT_count nvo_no_air_cond;
network output SNVT_count nvo_size;
network output SNVT_count nvo_remote;
network output SNVT_count nvo_remote_dir;
network output SNVT_count nvo_remotes[5];

network input SNVT_switch nvi_lighting[4];
network input SNVT_count nvi_no_lighting;
network input SNVT_count nvi_no_blind;
network input SNVT_count nvi_no_air_cond;
network input SNVT_count nvi_size;

SNVT_switch lighting_level[4];

int item = 1;
int part = 1;
int cur_pos = 1;
int mnu_pos = 1;
char display[20];
unsigned int bits_read;
unsigned int irb[4];

eeprom int no_lighting = 4;
eeprom int no_blind = 2;
eeprom int no_air_cond = 3;
eeprom int size = 20;

void writecmd(int a)
{
	io_out(en, 1);
	io_out(io_com_data, 0b00000000UL);
	io_out(io_com_data, a);
	io_out(en, 0);
	delay(0);
}

void command(int a)
{
	io_out(en, 1);
	io_out(io_com_data, 0b00000000UL);
	switch(a)
	{
		case 0:
			io_out(io_com_data, 0b00000001UL);	//clear
			break;
		case 1:
			io_out(io_com_data, 0b00111000UL);	//datainterface
			break;
		case 20:
			io_out(io_com_data, 0b00001000UL);	//displayoff
			break;
		case 21:
			io_out(io_com_data, 0b00001100UL);	//displayon
			break;
		case 30:
			io_out(io_com_data, 0b00000100UL);	//autoforward off
			break;
		case 31:
			io_out(io_com_data, 0b00000110UL);	//autoforward on
			break;
	}
	io_out(en, 0);
	if(a == 2)
	{
		delay(63);
	}
	else
	{
		delay(0);
	}
}

void chr(char a)
{
	io_out(en, 1);
	io_out(io_com_data, 0b10000000UL);
	io_out(io_com_data, a);
	io_out(en, 0);
	delay(0);
}

void str(char a[20])
{
	int chr_num;
	for(chr_num = 0; a[chr_num] != '~'; chr_num = chr_num + 1)
	{
		chr(a[chr_num]);
	}
}

//void sound(int a)
//{
//	io_out(io_sound, a);
//}

void name(int a)
{
	switch(a)
	{
		case 1:
			strcpy(display, " Lighting~");
			break;
		case 11:
			strcpy(display, " Lamp 1~");
			break;
		case 12:
			strcpy(display, " Lamp 2~");
			break;
		case 13:
			strcpy(display, " Lamp 3~");
			break;
		case 14:
			strcpy(display, " Lamp 4~");
			break;
		case 2:
			strcpy(display, " Blind~");
			break;
		case 21:
			strcpy(display, " Blind 1~");
			break;
		case 22:
			strcpy(display, " Blind 2~");
			break;
		case 23:
			strcpy(display, " Blind 3~");
			break;
		case 24:
			strcpy(display, " Blind 4~");
			break;
		case 3:
			strcpy(display, " Air Condition~");
			break;
		case 31:
			strcpy(display, " Air Cond. 1~");
			break;
		case 32:
			strcpy(display, " Air Cond. 2~");
			break;
		case 33:
			strcpy(display, " Air Cond. 3~");
			break;
		case 34:
			strcpy(display, " Air Cond. 4~");
			break;
		case 4:
			strcpy(display, " Other~");
			break;
		case 41:
			strcpy(display, " Light Sensor~");
			break;
		case 42:
			strcpy(display,	" Door Contact~");
			break;
		case 43:
			strcpy(display, " Person Detector~");
			break;
		case 44:
			strcpy(display,	" Smoke Detector~");
			break;
	}
	str(display);
}

void move(int a, int b)
{
	if(a == 1)
	{
		writecmd(127 + b);
	}
	else if(a == 2)
	{
		writecmd(128 + 63 + b);
	}
	else if(a == 3)
	{
		writecmd(128 + 19 + b);
	}
	else if(a == 4)
	{
		writecmd(128 + 83 + b);
	}
}

void dec_num(unsigned int a)
{
	unsigned int b, c, d;
	b = a / 200;
	if(b == 0)
	{
		c = a / 20;
		d = (a % 20) / 2;
	}
	else
	{
		c = 0;
		d = 0;
	}
	chr(48 + b);
	chr(48 + c);
	chr(48 + d);
	chr('%');
}

void menu(int a)
{
	int b, c;
	b = 4;
	command(0);
	if(a == 1)
	{
		for(b = 1; b <= 4; b = b + 1)
		{
			move(b, 1);
			name(b);
		}
		move(cur_pos, 1);
		chr(126);
	}
	else if(a == 11 || a == 12 || a == 13 || a == 14)
	{
		if(a == 11)
		{
			b = no_lighting;
		}
		else if(a == 12)
		{
			b = no_blind;
		}
		else if(a == 13)
		{
			b = no_air_cond;
		}
        for(c = 1; c <= b; c = c + 1)
		{
			move(c, 1);
			if(a == 11)
			{
				name(10 + c);
				if(lighting_level[c - 1].state == 1)
				{
					move(c, size - 8);
					strcpy(display, " ON~");
					str(display);
					move(c, size - 3);
					dec_num(lighting_level[c - 1].value);
				}
				else if(lighting_level[c - 1].state == 0)
				{
					move(c, size - 8);
					strcpy(display, "OFF~");
					str(display);
					move(c, size - 3);
					strcpy(display, "    ~");
					str(display);
				}
			}
			else if(a == 12)
			{
				name(20 + c);
			}
			else if(a == 13)
			{
				name(30 + c);
			}
			else if(a == 14)
			{
				name(40 + c);
			}
		}
		if(a == 11 || a == 12 || a == 13 )
		{
			move(cur_pos, 1);
			chr(126);
		}
	}
	else if(a == 21 || a == 22 || a == 23)
	{
		if(mnu_pos == 21)
		{
			move(2, 8);
			strcpy(display, "Level~");
			str(display);
			move(3, 9);
			dec_num(lighting_level[item - 1].value);
		}
		else if(mnu_pos == 22)
		{
			move(1, 8);
			strcpy(display, "Motion~");
			str(display);
			move(2, 8);
			strcpy(display, " UP~");
			str(display);
			move(3, 8);
			strcpy(display, " STOP~");
			str(display);
			move(4, 8);
			strcpy(display, " DOWN~");
			str(display);
			move(cur_pos, 8);
			chr(126);
		}
		else if(mnu_pos == 23)
		{
			move(1, 1);
			strcpy(display, " Power~");
			str(display);
			move(2, 1);
			strcpy(display, " Swing~");
			str(display);
			move(3, 1);
			strcpy(display, " Fan Speed~");
			str(display);
			move(4, 1);
			strcpy(display, " Temperture~");
			str(display);
			move(cur_pos, 1);
			chr(126);
		}
	}	
	else if(a == 33)
	{
		if(part == 1 || part == 2)
		{
			move(1, 8);
			if(part == 1)
			{
				strcpy(display, "Power~");
			}
			else if(part == 2)
			{
				strcpy(display, "Swing~");
			}
			str(display);
			move(2, 8);
			strcpy(display, " ON~");
			str(display);
			move(3, 8);
			strcpy(display, " OFF~");
			str(display);
			move(cur_pos, 8);
			chr(126);
		}
		else if(part == 3)
		{
			move(1, 6);
			strcpy(display, "Fan Speed~");
			str(display);
			move(2, 8);
			strcpy(display, " HI~");
			str(display);
			move(3, 8);
			strcpy(display, " MED~");
			str(display);
			move(4, 8);
			strcpy(display, " LO~");
			str(display);
			move(cur_pos, 8);
			chr(126);
		}
	}
}

void roll_cur(int a)
{
	int b;
	if(mnu_pos == 11)
	{
		b = no_lighting;
	}
	else if(mnu_pos == 12)
	{
		b = no_blind;
	}
	else if(mnu_pos == 13)
	{
		b = no_air_cond;
	}
	switch(a)
	{
		case 1:
			if(cur_pos > 1)
			{
				move(cur_pos, 1);
				chr(' ');
				cur_pos = cur_pos - 1;
				move(cur_pos, 1);
				chr(126);
				item = item - 1;
			}
			break;
		case 2:
			if(cur_pos < 4)
			{
				move(cur_pos, 1);
				chr(' ');
				cur_pos = cur_pos + 1;
				move(cur_pos, 1);
				chr(126);
				item = item + 1;
			}
			break;
		case 12:
			if(cur_pos < 4 && cur_pos < b)
			{
				move(cur_pos, 1);
				chr(' ');
				cur_pos = cur_pos + 1;
				move(cur_pos, 1);
				chr(126);
				item = item + 1;
			}
			break;
		case 21:
			if(mnu_pos == 21)
			{
				if(lighting_level[item - 1].value < 200)
				{
					if((lighting_level[item - 1].value % 40) == 0)
					{
						lighting_level[item - 1].value = lighting_level[item - 1].value + 40;
					}
					else
					{
						lighting_level[item - 1].value  = ((lighting_level[item - 1].value / 40) + 1) * 40;
					}
					menu(21);
				}
			}
			else if(mnu_pos == 22)
			{
				if(cur_pos > 2)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos - 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			else if(mnu_pos == 23)
			{
				if(cur_pos > 1)
				{
					move(cur_pos, 1);
					chr(' ');
					cur_pos = cur_pos - 1;
					move(cur_pos, 1);
					chr(126);
					part = cur_pos;
				}
			}
			break;
		case 22:
			if(mnu_pos == 21)
			{
				if(lighting_level[item - 1].value > 0)
				{
					if((lighting_level[item - 1].value % 40) == 0)
					{
						lighting_level[item - 1].value = lighting_level[item - 1].value - 40;
					}
					else
					{
						lighting_level[item - 1].value  = (lighting_level[item - 1].value / 40) * 40;
					}
					menu(21);
				}
			}
			else if(mnu_pos == 22)
			{
				if(cur_pos < 4)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			else if(mnu_pos == 23)
			{
				if(cur_pos < 4)
				{
					move(cur_pos, 1);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 1);
					chr(126);
					part = cur_pos;
				}
			}
			break;
		case 31:
			if(cur_pos > 2)
			{
				move(cur_pos, 8);
				chr(' ');
				cur_pos = cur_pos - 1;
				move(cur_pos, 8);
				chr(126);
			}
			break;
		case 32:
			if(part == 1 || part == 2)
			{
				if(cur_pos < 3)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			else if(part == 3)
			{
				if(cur_pos < 4)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			break;
	}
}

void main_cmd(int a)
{
	switch (a)
	{
		case 1:
			if(mnu_pos == 1 || mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13 )
			{
				roll_cur(1);
			}
			else if(mnu_pos == 21 || mnu_pos == 22 || mnu_pos == 23 )
			{
				roll_cur(21);
			}
			else if(mnu_pos == 33)
			{
				roll_cur(31);
			}
			break;
		case 2:
			if(mnu_pos == 1)
			{
				roll_cur(2);
			}
			else if(mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13)
			{
				roll_cur(12);
			}
			else if(mnu_pos == 21 || mnu_pos == 22 || mnu_pos == 23)
			{
				roll_cur(22);
			}
			else if(mnu_pos == 33)
			{
				roll_cur(32);
			}
			break;
		case 3:
			if(mnu_pos == 1)
			{
				cur_pos = 1;
				mnu_pos = item + 10;
				menu(mnu_pos);
				item = 1;
			}
			else if(mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13)
			{
				if(mnu_pos == 12)
				{
					cur_pos  = 3;
				}
				if(mnu_pos == 13)
				{
					cur_pos = 1;
				}
				mnu_pos = mnu_pos + 10;
				menu(mnu_pos);
			}
			else if(mnu_pos == 21 || mnu_pos == 23)
			{
				if(mnu_pos == 21)
				{
					nvo_lighting[item - 1].value = lighting_level[item - 1].value;
					if(lighting_level[item - 1].value != 0)
					{
						nvo_lighting[item - 1].state = 1;
					}
					else
					{
						nvo_lighting[item - 1].state = 0;
					}
					cur_pos = item;
					mnu_pos = mnu_pos - 10;
					menu(mnu_pos);
				}
				else if(mnu_pos == 23)
				{
					if(part == 1 || part == 2 || part == 3)
					{
						cur_pos = 2;
					}
					mnu_pos = mnu_pos + 10;
					menu(mnu_pos);
				}
			}
			break;
		case 4:
			if(mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13 || mnu_pos == 14)
			{
				cur_pos = mnu_pos - 10;
				item = cur_pos;
				mnu_pos = 1;
				menu(1);
			}
			else if(mnu_pos == 21 || mnu_pos == 22 || mnu_pos == 23 || mnu_pos == 24)
			{
				if(mnu_pos == 21)
				{
					lighting_level[item - 1].value = nvi_lighting[item - 1].value;
					lighting_level[item - 1].state = nvi_lighting[item - 1].state;
				
				}
				cur_pos = item;
				mnu_pos = mnu_pos - 10;
				menu(mnu_pos);
			}
			else if(mnu_pos == 33)
			{
				cur_pos = part;
				mnu_pos = mnu_pos - 10;
				menu(mnu_pos);
			}
			break;
	}
}

when(nv_update_occurs(nvi_size))
{
	size = (short) nvi_size;
}

when(nv_update_occurs(nvi_no_lighting))
{
	no_lighting = (short) nvi_no_lighting;
	if(mnu_pos == 11)
	{
		menu(11);
	}
}

when(nv_update_occurs(nvi_no_blind))
{
	no_blind = (short) nvi_no_blind;
	if(mnu_pos == 12)
	{
		menu(12);
	}
}

when(nv_update_occurs(nvi_no_air_cond))
{
	no_air_cond = (short) nvi_no_air_cond;
	if(mnu_pos == 13)
	{
		menu(13);
	}
}

when(nv_update_occurs(nvi_lighting))
{
	int a;
	for(a = 0; a < 4; a = a + 1)
	{
		lighting_level[a].value = nvi_lighting[a].value;
		lighting_level[a].state = nvi_lighting[a].state;
	}
	if(mnu_pos == 11)
	{
		menu(11);
	}
	else if(mnu_pos == 21)
	{
		menu(21);
	}
}

when(reset)
{
	delay(600);
	command(1);
	delay(160);
	command(1);
	delay(2);	
	command(1);
	delay(160);
	command(1);
	command(20);
	command(0);
	command(21);
	menu(1);
	nvo_size = size;
	nvo_no_lighting = no_lighting;
	nvo_no_blind = no_blind;
	nvo_no_air_cond = no_air_cond;
}

when(io_changes(io_ir_level)to 0)
{
	bits_read = io_in(io_ir, irb, 32, 48211UL, 48211UL + 2000UL);
	nvo_remotes[0] = irb[0];
	nvo_remotes[1] = irb[1];
	nvo_remotes[2] = irb[2];
	nvo_remotes[3] = irb[3];
	nvo_remotes[4] = bits_read;
	delay(4000);
//	JVC: 	bits_read = 16, irb[0] = 3
	if(bits_read == 16 && irb[0] == 3 && irb[1] >= 33 && irb[1] <= 42)
	{
		if(irb[1] == 42)
		{
			nvo_remote = 0;
		}
		else
		{
			nvo_remote = irb[1] - 32;
		}
	}
	else if(bits_read == 16 && irb[0] == 3 && irb[1] == 25)
	{
		nvo_remote_dir = 1;
		main_cmd(1);
	}
	else if(bits_read == 16 && irb[0] == 3 && irb[1] == 24)
	{
		nvo_remote_dir = 2;
		main_cmd(2);
	}
	else if(bits_read == 16 && irb[0] == 3 && irb[1] == 30)
	{
		nvo_remote_dir = 3;
		main_cmd(4);
	}
	else if(bits_read == 16 && irb[0] == 3 && irb[1] == 31)
	{
		nvo_remote_dir = 4;
		main_cmd(3);
	}
}

when(io_changes(up)to 0)
{
	main_cmd(1);
}

when(io_changes(down)to 0)
{
	main_cmd(2);
}

when(io_changes(enter)to 0)
{
	main_cmd(3);
}

when(io_changes(esc)to 0)
{
	main_cmd(4);
}

    Source: geocities.com/hk/cloud_fan_school/Program/LCD/20040216

               ( geocities.com/hk/cloud_fan_school/Program/LCD)                   ( geocities.com/hk/cloud_fan_school/Program)                   ( geocities.com/hk/cloud_fan_school)                   ( geocities.com/hk)